Skip to content

Commit 61554bc

Browse files
committed
Fix misleading "impl Trait" error
Closes #84160
1 parent 117799b commit 61554bc

File tree

6 files changed

+43
-3
lines changed

6 files changed

+43
-3
lines changed

compiler/rustc_typeck/src/check/coercion.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
14811481
expected,
14821482
found,
14831483
can_suggest,
1484+
fcx.tcx.hir().get_parent_item(id),
14841485
);
14851486
}
14861487
if !pointing_at_return_type {

compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5252
}
5353
let mut pointing_at_return_type = false;
5454
if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
55-
pointing_at_return_type =
56-
self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
5755
let fn_id = self.tcx.hir().get_return_block(blk_id).unwrap();
56+
pointing_at_return_type = self.suggest_missing_return_type(
57+
err,
58+
&fn_decl,
59+
expected,
60+
found,
61+
can_suggest,
62+
fn_id,
63+
);
5864
self.suggest_missing_break_or_return_expr(
5965
err, expr, &fn_decl, expected, found, blk_id, fn_id,
6066
);
@@ -433,6 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
433439
expected: Ty<'tcx>,
434440
found: Ty<'tcx>,
435441
can_suggest: bool,
442+
fn_id: hir::HirId,
436443
) -> bool {
437444
// Only suggest changing the return type for methods that
438445
// 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> {
465472
let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty);
466473
debug!("suggest_missing_return_type: return type {:?}", ty);
467474
debug!("suggest_missing_return_type: expected type {:?}", ty);
468-
if ty.kind() == expected.kind() {
475+
let bound_vars = self.tcx.late_bound_vars(fn_id);
476+
let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
477+
let ty = self.normalize_associated_types_in(sp, ty);
478+
if self.can_coerce(expected, ty) {
469479
err.span_label(sp, format!("expected `{}` because of return type", expected));
470480
return true;
471481
}

src/test/ui/extern/extern-types-distinct-types.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ LL | type A;
66
LL | type B;
77
| ------- the expected foreign type
88
...
9+
LL | fn foo(r: &A) -> &B {
10+
| -- expected `&B` because of return type
911
LL | r
1012
| ^ expected extern type `B`, found extern type `A`
1113
|

src/test/ui/retslot-cast.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0308]: mismatched types
22
--> $DIR/retslot-cast.rs:13:5
33
|
4+
LL | -> Option<&Iterator<Item=()>> {
5+
| -------------------------- expected `Option<&dyn Iterator<Item = ()>>` because of return type
6+
...
47
LL | inner(x)
58
| ^^^^^^^^ expected trait `Iterator<Item = ()>`, found trait `Iterator<Item = ()> + Send`
69
|

src/test/ui/typeck/issue-84160.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn mismatched_types_with_reference(x: &u32) -> &u32 {
2+
if false {
3+
return x;
4+
}
5+
return "test";
6+
//~^ERROR mismatched types
7+
}
8+
9+
fn main() {}

src/test/ui/typeck/issue-84160.stderr

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-84160.rs:5:12
3+
|
4+
LL | fn mismatched_types_with_reference(x: &u32) -> &u32 {
5+
| ---- expected `&u32` because of return type
6+
...
7+
LL | return "test";
8+
| ^^^^^^ expected `u32`, found `str`
9+
|
10+
= note: expected reference `&u32`
11+
found reference `&'static str`
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)