diff options
author | Florian Diebold <[email protected]> | 2020-02-29 14:31:07 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-02-29 14:31:07 +0000 |
commit | 5fe220b9873d587188adae63fa205481a9aae9ce (patch) | |
tree | 51599b3664e16cd5f0ef288dac924330c5cd0af0 /crates/ra_hir_ty/src/infer/expr.rs | |
parent | 0ec7f760fcd8bb9c2273e004468faa2a8cbeb29d (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/expr.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 8 |
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 { |