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
This commit is contained in:
commit
7e27209ff8
6 changed files with 43 additions and 3 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
||||
|
|
|
|||
9
src/test/ui/typeck/issue-84160.rs
Normal file
9
src/test/ui/typeck/issue-84160.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
fn mismatched_types_with_reference(x: &u32) -> &u32 {
|
||||
if false {
|
||||
return x;
|
||||
}
|
||||
return "test";
|
||||
//~^ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
15
src/test/ui/typeck/issue-84160.stderr
Normal file
15
src/test/ui/typeck/issue-84160.stderr
Normal file
|
|
@ -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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue