aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-02-29 14:31:07 +0000
committerFlorian Diebold <[email protected]>2020-02-29 14:31:07 +0000
commit5fe220b9873d587188adae63fa205481a9aae9ce (patch)
tree51599b3664e16cd5f0ef288dac924330c5cd0af0 /crates/ra_hir_ty/src/infer
parent0ec7f760fcd8bb9c2273e004468faa2a8cbeb29d (diff)
Fix a common false-positive type mismatch
E.g. for `&{ some_string() }` in a context where a `&str` is expected, we reported a mismatch inside the block. The problem is that we're passing an expectation of `str` down, but the expectation is more of a hint in this case. There's a long comment in rustc about this, which I just copied. Also, fix reported location for type mismatches in macros.
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs8
1 files changed, 4 insertions, 4 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 9d5f75625..3db5b2b51 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -42,14 +42,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
42 /// Return the type after possible coercion. 42 /// Return the type after possible coercion.
43 pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { 43 pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty {
44 let ty = self.infer_expr_inner(expr, &expected); 44 let ty = self.infer_expr_inner(expr, &expected);
45 let ty = if !self.coerce(&ty, &expected.ty) { 45 let ty = if !self.coerce(&ty, &expected.coercion_target()) {
46 self.result 46 self.result
47 .type_mismatches 47 .type_mismatches
48 .insert(expr, TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }); 48 .insert(expr, TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() });
49 // Return actual type when type mismatch. 49 // Return actual type when type mismatch.
50 // This is needed for diagnostic when return type mismatch. 50 // This is needed for diagnostic when return type mismatch.
51 ty 51 ty
52 } else if expected.ty == Ty::Unknown { 52 } else if expected.coercion_target() == &Ty::Unknown {
53 ty 53 ty
54 } else { 54 } else {
55 expected.ty.clone() 55 expected.ty.clone()
@@ -297,7 +297,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
297 // FIXME: throw type error - expected mut reference but found shared ref, 297 // FIXME: throw type error - expected mut reference but found shared ref,
298 // which cannot be coerced 298 // which cannot be coerced
299 } 299 }
300 Expectation::has_type(Ty::clone(exp_inner)) 300 Expectation::rvalue_hint(Ty::clone(exp_inner))
301 } else { 301 } else {
302 Expectation::none() 302 Expectation::none()
303 }; 303 };
@@ -542,7 +542,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
542 let ty = if let Some(expr) = tail { 542 let ty = if let Some(expr) = tail {
543 self.infer_expr_coerce(expr, expected) 543 self.infer_expr_coerce(expr, expected)
544 } else { 544 } else {
545 self.coerce(&Ty::unit(), &expected.ty); 545 self.coerce(&Ty::unit(), expected.coercion_target());
546 Ty::unit() 546 Ty::unit()
547 }; 547 };
548 if diverges { 548 if diverges {