Skip to content

Commit e33f7f7

Browse files
committed
Explain type mismatch cause pointing to return type when it is impl Trait
1 parent e730697 commit e33f7f7

File tree

3 files changed

+39
-9
lines changed

3 files changed

+39
-9
lines changed

src/librustc_typeck/check/coercion.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,6 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
11991199
(self.final_ty.unwrap_or(self.expected_ty), expression_ty)
12001200
};
12011201

1202-
let reason_label = "expected because of this statement";
12031202
let mut db;
12041203
match cause.code {
12051204
ObligationCauseCode::ReturnNoExpression => {
@@ -1244,26 +1243,46 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
12441243
// as prior return coercions would not be relevant (#57664).
12451244
let parent_id = fcx.tcx.hir().get_parent_node(blk_id);
12461245
let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id));
1247-
if fcx.get_node_fn_decl(parent).is_some() && !pointing_at_return_type {
1246+
if let (Some((fn_decl, _, _)), false) = (
1247+
fcx.get_node_fn_decl(parent),
1248+
pointing_at_return_type,
1249+
) {
12481250
if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
1249-
db.span_label(*sp, reason_label);
1251+
db.span_label(
1252+
fn_decl.output.span(),
1253+
"expected because this return type...",
1254+
);
1255+
db.span_label(*sp, format!(
1256+
"...is found to be `{}` here",
1257+
fcx.resolve_type_vars_with_obligations(expected),
1258+
));
12501259
}
12511260
}
12521261
}
12531262
ObligationCauseCode::ReturnType(_id) => {
12541263
db = fcx.report_mismatched_types(cause, expected, found, err);
12551264
let _id = fcx.tcx.hir().get_parent_node(_id);
12561265
let mut pointing_at_return_type = false;
1266+
let mut return_sp = None;
12571267
if let Some((fn_decl, can_suggest)) = fcx.get_fn_decl(_id) {
12581268
pointing_at_return_type = fcx.suggest_missing_return_type(
12591269
&mut db, &fn_decl, expected, found, can_suggest);
1270+
if !pointing_at_return_type {
1271+
return_sp = Some(fn_decl.output.span()); // `impl Trait` return type
1272+
}
12601273
}
12611274
if let (Some(sp), false) = (
12621275
fcx.ret_coercion_span.borrow().as_ref(),
12631276
pointing_at_return_type,
12641277
) {
1265-
if !sp.overlaps(cause.span) {
1266-
db.span_label(*sp, reason_label);
1278+
if let Some(return_sp) = return_sp {
1279+
db.span_label(return_sp, "expected because this return type...");
1280+
db.span_label( *sp, format!(
1281+
"...is found to be `{}` here",
1282+
fcx.resolve_type_vars_with_obligations(expected),
1283+
));
1284+
} else if !sp.overlaps(cause.span) {
1285+
db.span_label(*sp, "expected because of this statement");
12671286
}
12681287
}
12691288
}

src/test/ui/impl-trait/equality.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
error[E0308]: mismatched types
22
--> $DIR/equality.rs:15:5
33
|
4+
LL | fn two(x: bool) -> impl Foo {
5+
| -------- expected because this return type...
6+
LL | if x {
47
LL | return 1_i32;
5-
| ----- expected because of this statement
8+
| ----- ...is found to be `i32` here
69
LL | }
710
LL | 0_u32
811
| ^^^^^ expected i32, found u32

src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
error[E0308]: mismatched types
22
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5
33
|
4+
LL | fn foo() -> impl std::fmt::Display {
5+
| ---------------------- expected because this return type...
6+
LL | if false {
47
LL | return 0i32;
5-
| ---- expected because of this statement
8+
| ---- ...is found to be `i32` here
69
LL | }
710
LL | 1u32
811
| ^^^^ expected i32, found u32
@@ -13,8 +16,11 @@ LL | 1u32
1316
error[E0308]: mismatched types
1417
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16
1518
|
19+
LL | fn bar() -> impl std::fmt::Display {
20+
| ---------------------- expected because this return type...
21+
LL | if false {
1622
LL | return 0i32;
17-
| ---- expected because of this statement
23+
| ---- ...is found to be `i32` here
1824
LL | } else {
1925
LL | return 1u32;
2026
| ^^^^ expected i32, found u32
@@ -25,10 +31,12 @@ LL | return 1u32;
2531
error[E0308]: mismatched types
2632
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:19:5
2733
|
34+
LL | fn baz() -> impl std::fmt::Display {
35+
| ---------------------- expected because this return type...
2836
LL | / if false {
2937
LL | | //~^ ERROR mismatched types
3038
LL | | return 0i32;
31-
| | ---- expected because of this statement
39+
| | ---- ...is found to be `i32` here
3240
LL | | } else {
3341
LL | | 1u32
3442
LL | | }

0 commit comments

Comments
 (0)