diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2021-07-01 11:15:42 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-01 11:15:42 +0200 |
| commit | 7e27209ff83ffd6b94b6d9833b28644587ec3207 (patch) | |
| tree | 62043387a2676b77099a9e65f2fd1ea020688af0 | |
| parent | dfd30d7b705f858603ef6d21bdb893297aea37ba (diff) | |
| parent | 61554bc9d72472332aac8cad341d77aa40cfb733 (diff) | |
| download | rust-7e27209ff83ffd6b94b6d9833b28644587ec3207.tar.gz rust-7e27209ff83ffd6b94b6d9833b28644587ec3207.zip | |
Rollup merge of #86666 - ptrojahn:compare_kinds, r=petrochenkov
Fix misleading "impl Trait" error The kinds can't be compared directly, as types with references are treated as different because the lifetimes aren't bound in ty, but are in expected. Closes #84160
| -rw-r--r-- | compiler/rustc_typeck/src/check/coercion.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs | 16 | ||||
| -rw-r--r-- | src/test/ui/extern/extern-types-distinct-types.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/retslot-cast.stderr | 3 | ||||
| -rw-r--r-- | src/test/ui/typeck/issue-84160.rs | 9 | ||||
| -rw-r--r-- | src/test/ui/typeck/issue-84160.stderr | 15 |
6 files changed, 43 insertions, 3 deletions
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 236fec94bdb..afa4d0f1c4d 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -1481,6 +1481,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { expected, found, can_suggest, + fcx.tcx.hir().get_parent_item(id), ); } if !pointing_at_return_type { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index d6b1e56316b..54aab271fdb 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -52,9 +52,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut pointing_at_return_type = false; if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) { - pointing_at_return_type = - self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest); let fn_id = self.tcx.hir().get_return_block(blk_id).unwrap(); + pointing_at_return_type = self.suggest_missing_return_type( + err, + &fn_decl, + expected, + found, + can_suggest, + fn_id, + ); self.suggest_missing_break_or_return_expr( err, expr, &fn_decl, expected, found, blk_id, fn_id, ); @@ -433,6 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, can_suggest: bool, + fn_id: hir::HirId, ) -> bool { // Only suggest changing the return type for methods that // haven't set a return type at all (and aren't `fn main()` or an impl). @@ -465,7 +472,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty); debug!("suggest_missing_return_type: return type {:?}", ty); debug!("suggest_missing_return_type: expected type {:?}", ty); - if ty.kind() == expected.kind() { + let bound_vars = self.tcx.late_bound_vars(fn_id); + let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars)); + let ty = self.normalize_associated_types_in(sp, ty); + if self.can_coerce(expected, ty) { err.span_label(sp, format!("expected `{}` because of return type", expected)); return true; } diff --git a/src/test/ui/extern/extern-types-distinct-types.stderr b/src/test/ui/extern/extern-types-distinct-types.stderr index 32b45ee10ad..f69629232ae 100644 --- a/src/test/ui/extern/extern-types-distinct-types.stderr +++ b/src/test/ui/extern/extern-types-distinct-types.stderr @@ -6,6 +6,8 @@ LL | type A; LL | type B; | ------- the expected foreign type ... +LL | fn foo(r: &A) -> &B { + | -- expected `&B` because of return type LL | r | ^ expected extern type `B`, found extern type `A` | diff --git a/src/test/ui/retslot-cast.stderr b/src/test/ui/retslot-cast.stderr index 9b5f11ce667..798ce1199a9 100644 --- a/src/test/ui/retslot-cast.stderr +++ b/src/test/ui/retslot-cast.stderr @@ -1,6 +1,9 @@ error[E0308]: mismatched types --> $DIR/retslot-cast.rs:13:5 | +LL | -> Option<&Iterator<Item=()>> { + | -------------------------- expected `Option<&dyn Iterator<Item = ()>>` because of return type +... LL | inner(x) | ^^^^^^^^ expected trait `Iterator<Item = ()>`, found trait `Iterator<Item = ()> + Send` | diff --git a/src/test/ui/typeck/issue-84160.rs b/src/test/ui/typeck/issue-84160.rs new file mode 100644 index 00000000000..7b444df8528 --- /dev/null +++ b/src/test/ui/typeck/issue-84160.rs @@ -0,0 +1,9 @@ +fn mismatched_types_with_reference(x: &u32) -> &u32 { + if false { + return x; + } + return "test"; + //~^ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/typeck/issue-84160.stderr b/src/test/ui/typeck/issue-84160.stderr new file mode 100644 index 00000000000..24c188b3fcb --- /dev/null +++ b/src/test/ui/typeck/issue-84160.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/issue-84160.rs:5:12 + | +LL | fn mismatched_types_with_reference(x: &u32) -> &u32 { + | ---- expected `&u32` because of return type +... +LL | return "test"; + | ^^^^^^ expected `u32`, found `str` + | + = note: expected reference `&u32` + found reference `&'static str` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. |
