aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-12-05 22:02:31 +0000
committerFlorian Diebold <[email protected]>2019-12-06 14:15:26 +0000
commitf86fe3d891ab295e9e394a1338da86524a6205d3 (patch)
tree891cf4be4893c79598800928e7c0b669d9d2a9c2 /crates/ra_hir_ty/src/infer
parentd2b210a02e3e8ee1cf38909411fa8945aec99f4e (diff)
Don't unify within a reference
If we are expecting a `&Foo` and get a `&something`, when checking the `something`, we are *expecting* a `Foo`, but we shouldn't try to unify whatever we get with that expectation, because it could actually be a `&Foo`, and `&&Foo` coerces to `&Foo`. So this fixes quite a few false type mismatches.
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs21
1 files changed, 10 insertions, 11 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 1e78f6efd..b8df27706 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -201,7 +201,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
201 } 201 }
202 Expr::Return { expr } => { 202 Expr::Return { expr } => {
203 if let Some(expr) = expr { 203 if let Some(expr) = expr {
204 self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone())); 204 self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone()));
205 } 205 }
206 Ty::simple(TypeCtor::Never) 206 Ty::simple(TypeCtor::Never)
207 } 207 }
@@ -245,7 +245,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
245 ty 245 ty
246 } 246 }
247 Expr::Field { expr, name } => { 247 Expr::Field { expr, name } => {
248 let receiver_ty = self.infer_expr(*expr, &Expectation::none()); 248 let receiver_ty = self.infer_expr_inner(*expr, &Expectation::none());
249 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); 249 let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty);
250 let ty = autoderef::autoderef( 250 let ty = autoderef::autoderef(
251 self.db, 251 self.db,
@@ -280,7 +280,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
280 self.normalize_associated_types_in(ty) 280 self.normalize_associated_types_in(ty)
281 } 281 }
282 Expr::Await { expr } => { 282 Expr::Await { expr } => {
283 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 283 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
284 let ty = match self.resolve_future_future_output() { 284 let ty = match self.resolve_future_future_output() {
285 Some(future_future_output_alias) => { 285 Some(future_future_output_alias) => {
286 let ty = self.table.new_type_var(); 286 let ty = self.table.new_type_var();
@@ -299,7 +299,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
299 ty 299 ty
300 } 300 }
301 Expr::Try { expr } => { 301 Expr::Try { expr } => {
302 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 302 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
303 let ty = match self.resolve_ops_try_ok() { 303 let ty = match self.resolve_ops_try_ok() {
304 Some(ops_try_ok_alias) => { 304 Some(ops_try_ok_alias) => {
305 let ty = self.table.new_type_var(); 305 let ty = self.table.new_type_var();
@@ -318,7 +318,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
318 ty 318 ty
319 } 319 }
320 Expr::Cast { expr, type_ref } => { 320 Expr::Cast { expr, type_ref } => {
321 let _inner_ty = self.infer_expr(*expr, &Expectation::none()); 321 let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
322 let cast_ty = self.make_ty(type_ref); 322 let cast_ty = self.make_ty(type_ref);
323 // FIXME check the cast... 323 // FIXME check the cast...
324 cast_ty 324 cast_ty
@@ -334,12 +334,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
334 } else { 334 } else {
335 Expectation::none() 335 Expectation::none()
336 }; 336 };
337 // FIXME reference coercions etc. 337 let inner_ty = self.infer_expr_inner(*expr, &expectation);
338 let inner_ty = self.infer_expr(*expr, &expectation);
339 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) 338 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty)
340 } 339 }
341 Expr::Box { expr } => { 340 Expr::Box { expr } => {
342 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 341 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
343 if let Some(box_) = self.resolve_boxed_box() { 342 if let Some(box_) = self.resolve_boxed_box() {
344 Ty::apply_one(TypeCtor::Adt(box_), inner_ty) 343 Ty::apply_one(TypeCtor::Adt(box_), inner_ty)
345 } else { 344 } else {
@@ -347,7 +346,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
347 } 346 }
348 } 347 }
349 Expr::UnaryOp { expr, op } => { 348 Expr::UnaryOp { expr, op } => {
350 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 349 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
351 match op { 350 match op {
352 UnaryOp::Deref => match self.resolver.krate() { 351 UnaryOp::Deref => match self.resolver.krate() {
353 Some(krate) => { 352 Some(krate) => {
@@ -417,7 +416,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
417 _ => Ty::Unknown, 416 _ => Ty::Unknown,
418 }, 417 },
419 Expr::Range { lhs, rhs, range_type } => { 418 Expr::Range { lhs, rhs, range_type } => {
420 let lhs_ty = lhs.map(|e| self.infer_expr(e, &Expectation::none())); 419 let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none()));
421 let rhs_expect = lhs_ty 420 let rhs_expect = lhs_ty
422 .as_ref() 421 .as_ref()
423 .map_or_else(Expectation::none, |ty| Expectation::has_type(ty.clone())); 422 .map_or_else(Expectation::none, |ty| Expectation::has_type(ty.clone()));
@@ -455,7 +454,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
455 } 454 }
456 } 455 }
457 Expr::Index { base, index } => { 456 Expr::Index { base, index } => {
458 let _base_ty = self.infer_expr(*base, &Expectation::none()); 457 let _base_ty = self.infer_expr_inner(*base, &Expectation::none());
459 let _index_ty = self.infer_expr(*index, &Expectation::none()); 458 let _index_ty = self.infer_expr(*index, &Expectation::none());
460 // FIXME: use `std::ops::Index::Output` to figure out the real return type 459 // FIXME: use `std::ops::Index::Output` to figure out the real return type
461 Ty::Unknown 460 Ty::Unknown