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:
Guillaume Gomez 2021-07-01 11:15:42 +02:00 committed by GitHub
commit 7e27209ff8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 3 deletions

View file

@ -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 {

View file

@ -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;
}

View file

@ -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`
|

View file

@ -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`
|

View file

@ -0,0 +1,9 @@
fn mismatched_types_with_reference(x: &u32) -> &u32 {
if false {
return x;
}
return "test";
//~^ERROR mismatched types
}
fn main() {}

View 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`.