Fix misleading "impl Trait" error

Closes #84160
This commit is contained in:
Paul Trojahn 2021-06-25 18:22:32 +02:00
parent 117799b73c
commit 61554bc9d7
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`.