mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 22:54:58 +00:00
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.
This commit is contained in:
parent
0ec7f760fc
commit
5fe220b987
4 changed files with 86 additions and 18 deletions
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue