aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs37
-rw-r--r--crates/ra_hir_ty/src/lib.rs18
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs17
-rw-r--r--crates/ra_hir_ty/src/tests/simple.rs20
4 files changed, 70 insertions, 22 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index b28724f0e..54bab3476 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -17,8 +17,8 @@ use crate::{
17 autoderef, method_resolution, op, 17 autoderef, method_resolution, op,
18 traits::InEnvironment, 18 traits::InEnvironment,
19 utils::{generics, variant_data, Generics}, 19 utils::{generics, variant_data, Generics},
20 ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, 20 ApplicationTy, Binders, CallableDef, InferTy, IntTy, Mutability, Obligation, Rawness, Substs,
21 Ty, TypeCtor, Uncertain, 21 TraitRef, Ty, TypeCtor, Uncertain,
22}; 22};
23 23
24use super::{ 24use super::{
@@ -350,19 +350,28 @@ impl<'a> InferenceContext<'a> {
350 // FIXME check the cast... 350 // FIXME check the cast...
351 cast_ty 351 cast_ty
352 } 352 }
353 Expr::Ref { expr, mutability } => { 353 Expr::Ref { expr, rawness, mutability } => {
354 let expectation = 354 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) =
355 if let Some((exp_inner, exp_mutability)) = &expected.ty.as_reference() { 355 &expected.ty.as_reference_or_ptr()
356 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { 356 {
357 // FIXME: throw type error - expected mut reference but found shared ref, 357 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared {
358 // which cannot be coerced 358 // FIXME: throw type error - expected mut reference but found shared ref,
359 } 359 // which cannot be coerced
360 Expectation::rvalue_hint(Ty::clone(exp_inner)) 360 }
361 } else { 361 if *exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr {
362 Expectation::none() 362 // FIXME: throw type error - expected reference but found ptr,
363 }; 363 // which cannot be coerced
364 }
365 Expectation::rvalue_hint(Ty::clone(exp_inner))
366 } else {
367 Expectation::none()
368 };
364 let inner_ty = self.infer_expr_inner(*expr, &expectation); 369 let inner_ty = self.infer_expr_inner(*expr, &expectation);
365 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) 370 let ty = match rawness {
371 Rawness::RawPtr => TypeCtor::RawPtr(*mutability),
372 Rawness::Ref => TypeCtor::Ref(*mutability),
373 };
374 Ty::apply_one(ty, inner_ty)
366 } 375 }
367 Expr::Box { expr } => { 376 Expr::Box { expr } => {
368 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 377 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 93cb45a64..9fa8d3bdc 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -49,8 +49,10 @@ use std::sync::Arc;
49use std::{iter, mem}; 49use std::{iter, mem};
50 50
51use hir_def::{ 51use hir_def::{
52 expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, 52 expr::ExprId,
53 HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, 53 type_ref::{Mutability, Rawness},
54 AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
55 TypeParamId,
54}; 56};
55use ra_db::{impl_intern_key, salsa, CrateId}; 57use ra_db::{impl_intern_key, salsa, CrateId};
56 58
@@ -709,6 +711,18 @@ impl Ty {
709 } 711 }
710 } 712 }
711 713
714 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
715 match self {
716 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => {
717 Some((parameters.as_single(), Rawness::Ref, *mutability))
718 }
719 Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => {
720 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
721 }
722 _ => None,
723 }
724 }
725
712 pub fn strip_references(&self) -> &Ty { 726 pub fn strip_references(&self) -> &Ty {
713 let mut t: &Ty = self; 727 let mut t: &Ty = self;
714 728
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs
index 2cc4f4bf9..6f777ed8c 100644
--- a/crates/ra_hir_ty/src/tests/coercion.rs
+++ b/crates/ra_hir_ty/src/tests/coercion.rs
@@ -116,15 +116,20 @@ fn infer_let_stmt_coerce() {
116 assert_snapshot!( 116 assert_snapshot!(
117 infer(r#" 117 infer(r#"
118fn test() { 118fn test() {
119 let x: &[i32] = &[1]; 119 let x: &[isize] = &[1];
120 let x: *const [isize] = &[1];
120} 121}
121"#), 122"#),
122 @r###" 123 @r###"
123 11..40 '{ ...[1]; }': () 124 11..76 '{ ...[1]; }': ()
124 21..22 'x': &[i32] 125 21..22 'x': &[isize]
125 33..37 '&[1]': &[i32; _] 126 35..39 '&[1]': &[isize; _]
126 34..37 '[1]': [i32; _] 127 36..39 '[1]': [isize; _]
127 35..36 '1': i32 128 37..38 '1': isize
129 49..50 'x': *const [isize]
130 69..73 '&[1]': &[isize; _]
131 70..73 '[1]': [isize; _]
132 71..72 '1': isize
128 "###); 133 "###);
129} 134}
130 135
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index fd2208af2..f1db34160 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -385,6 +385,26 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
385} 385}
386 386
387#[test] 387#[test]
388fn infer_raw_ref() {
389 assert_snapshot!(
390 infer(r#"
391fn test(a: i32) {
392 &raw mut a;
393 &raw const a;
394}
395"#),
396 @r###"
397 9..10 'a': i32
398 17..54 '{ ...t a; }': ()
399 23..33 '&raw mut a': *mut i32
400 32..33 'a': i32
401 39..51 '&raw const a': *const i32
402 50..51 'a': i32
403 "###
404 );
405}
406
407#[test]
388fn infer_literals() { 408fn infer_literals() {
389 assert_snapshot!( 409 assert_snapshot!(
390 infer(r##" 410 infer(r##"