Skip to content

Commit 7e27209

Browse files
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
2 parents dfd30d7 + 61554bc commit 7e27209

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)