Skip to content

Commit 36a5244

Browse files
committed
Explain where the closure return type was inferred
Fixes #78193
1 parent 1eaadeb commit 36a5244

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

Diff for: compiler/rustc_typeck/src/check/coercion.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,28 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
14751475
if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.borrow().as_ref(), fn_output) {
14761476
self.add_impl_trait_explanation(&mut err, cause, fcx, expected, *sp, fn_output);
14771477
}
1478+
1479+
if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
1480+
// If the closure has an explicit return type annotation,
1481+
// then a type error may occur at the first return expression we
1482+
// see in the closure (if it conflicts with the declared
1483+
// return type). Skip adding a note in this case, since it
1484+
// would be incorrect.
1485+
if !err.span.primary_spans().iter().any(|span| span == sp) {
1486+
let hir = fcx.tcx.hir();
1487+
let body_owner = hir.body_owned_by(hir.enclosing_body_owner(fcx.body_id));
1488+
if fcx.tcx.is_closure(hir.body_owner_def_id(body_owner).to_def_id()) {
1489+
err.span_note(
1490+
*sp,
1491+
&format!(
1492+
"return type inferred to be `{}` here",
1493+
fcx.resolve_vars_if_possible(&expected)
1494+
),
1495+
);
1496+
}
1497+
}
1498+
}
1499+
14781500
err
14791501
}
14801502

Diff for: src/test/ui/closures/closure-return-type-mismatch.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
fn main() {
2+
|| {
3+
if false {
4+
return "test";
5+
}
6+
let a = true;
7+
a //~ ERROR mismatched types
8+
};
9+
10+
|| -> bool {
11+
if false {
12+
return "hello" //~ ERROR mismatched types
13+
};
14+
let b = true;
15+
b
16+
};
17+
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/closure-return-type-mismatch.rs:7:9
3+
|
4+
LL | a
5+
| ^ expected `&str`, found `bool`
6+
|
7+
note: return type inferred to be `&str` here
8+
--> $DIR/closure-return-type-mismatch.rs:4:20
9+
|
10+
LL | return "test";
11+
| ^^^^^^
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/closure-return-type-mismatch.rs:12:20
15+
|
16+
LL | return "hello"
17+
| ^^^^^^^ expected `bool`, found `&str`
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0308`.

Diff for: src/test/ui/generator/type-mismatch-signature-deduction.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ LL | 5
66
|
77
= note: expected type `std::result::Result<{integer}, _>`
88
found type `{integer}`
9+
note: return type inferred to be `std::result::Result<{integer}, _>` here
10+
--> $DIR/type-mismatch-signature-deduction.rs:8:20
11+
|
12+
LL | return Ok(6);
13+
| ^^^^^
914

1015
error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:6:5: 14:6] as Generator>::Return == i32`
1116
--> $DIR/type-mismatch-signature-deduction.rs:5:13

0 commit comments

Comments
 (0)