From 5fe220b9873d587188adae63fa205481a9aae9ce Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 29 Feb 2020 15:31:07 +0100 Subject: 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. --- crates/ra_hir_ty/src/infer/expr.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_ty/src/infer/expr.rs') 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> { /// Return the type after possible coercion. pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { let ty = self.infer_expr_inner(expr, &expected); - let ty = if !self.coerce(&ty, &expected.ty) { + let ty = if !self.coerce(&ty, &expected.coercion_target()) { self.result .type_mismatches .insert(expr, TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }); // Return actual type when type mismatch. // This is needed for diagnostic when return type mismatch. ty - } else if expected.ty == Ty::Unknown { + } else if expected.coercion_target() == &Ty::Unknown { ty } else { expected.ty.clone() @@ -297,7 +297,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { // FIXME: throw type error - expected mut reference but found shared ref, // which cannot be coerced } - Expectation::has_type(Ty::clone(exp_inner)) + Expectation::rvalue_hint(Ty::clone(exp_inner)) } else { Expectation::none() }; @@ -542,7 +542,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let ty = if let Some(expr) = tail { self.infer_expr_coerce(expr, expected) } else { - self.coerce(&Ty::unit(), &expected.ty); + self.coerce(&Ty::unit(), expected.coercion_target()); Ty::unit() }; if diverges { -- cgit v1.2.3