Skip to content

Commit 092ecca

Browse files
committed
Point at tail expression on rpit E0277
``` error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}: Coroutine` is not satisfied --> $DIR/gen_block_is_coro.rs:6:13 | LL | fn foo() -> impl Coroutine<Yield = u32, Return = ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` LL | gen { yield 42 } | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` here ``` The secondary span label is new.
1 parent 86b5965 commit 092ecca

20 files changed

+121
-32
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -3563,17 +3563,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
35633563
)]);
35643564
}
35653565
ObligationCauseCode::OpaqueReturnType(expr_info) => {
3566-
if let Some((expr_ty, hir_id)) = expr_info {
3567-
let expr_ty = self.tcx.short_ty_string(expr_ty, long_ty_file);
3568-
let expr = self.infcx.tcx.hir().expect_expr(hir_id);
3569-
err.span_label(
3570-
expr.span,
3571-
with_forced_trimmed_paths!(format!(
3572-
"return type was inferred to be `{expr_ty}` here",
3573-
)),
3574-
);
3575-
suggest_remove_deref(err, &expr);
3576-
}
3566+
let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info {
3567+
let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file);
3568+
let expr = tcx.hir().expect_expr(hir_id);
3569+
(expr_ty, expr)
3570+
} else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id()
3571+
&& let body = tcx.hir().body(body_id)
3572+
&& let hir::ExprKind::Block(block, _) = body.value.kind
3573+
&& let Some(expr) = block.expr
3574+
&& let Some(expr_ty) = self
3575+
.typeck_results
3576+
.as_ref()
3577+
.and_then(|typeck| typeck.node_type_opt(expr.hir_id))
3578+
&& let Some(pred) = predicate.as_clause()
3579+
&& let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
3580+
&& self.can_eq(param_env, pred.self_ty(), expr_ty)
3581+
{
3582+
let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file);
3583+
(expr_ty, expr)
3584+
} else {
3585+
return;
3586+
};
3587+
err.span_label(
3588+
expr.span,
3589+
with_forced_trimmed_paths!(format!(
3590+
"return type was inferred to be `{expr_ty}` here",
3591+
)),
3592+
);
3593+
suggest_remove_deref(err, &expr);
35773594
}
35783595
}
35793596
}

tests/ui/async-await/async-error-span.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0277]: `()` is not a future
33
|
44
LL | fn get_future() -> impl Future<Output = ()> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future
6+
LL |
7+
LL | panic!()
8+
| -------- return type was inferred to be `_` here
69
|
710
= help: the trait `Future` is not implemented for `()`
811

tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ LL | fn foo() -> impl Coroutine<u8> {
55
| ^^^^^^^^^^^^^^^^^^ expected due to this
66
...
77
LL | |_: ()| {}
8-
| ------- found signature defined here
8+
| ----------
9+
| |
10+
| found signature defined here
11+
| return type was inferred to be `{coroutine@$DIR/arg-count-mismatch-on-unit-input.rs:8:5: 8:12}` here
912
|
1013
= note: expected coroutine signature `fn(u8) -> _`
1114
found coroutine signature `fn(()) -> _`

tests/ui/coroutine/gen_block_is_coro.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,24 @@ error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}: C
33
|
44
LL | fn foo() -> impl Coroutine<Yield = u32, Return = ()> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}`
6+
LL | gen { yield 42 }
7+
| ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` here
68

79
error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}: Coroutine` is not satisfied
810
--> $DIR/gen_block_is_coro.rs:10:13
911
|
1012
LL | fn bar() -> impl Coroutine<Yield = i64, Return = ()> {
1113
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}`
14+
LL | gen { yield 42 }
15+
| ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}` here
1216

1317
error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}: Coroutine` is not satisfied
1418
--> $DIR/gen_block_is_coro.rs:14:13
1519
|
1620
LL | fn baz() -> impl Coroutine<Yield = i32, Return = ()> {
1721
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}`
22+
LL | gen { yield 42 }
23+
| ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}` here
1824

1925
error: aborting due to 3 previous errors
2026

tests/ui/coroutine/gen_block_is_no_future.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ error[E0277]: `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a fut
33
|
44
LL | fn foo() -> impl std::future::Future {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a future
6+
LL | gen { yield 42 }
7+
| ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` here
68
|
79
= help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}`
810

tests/ui/coroutine/issue-88653.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fn foo(bar: bool) -> impl Coroutine<(bool,)> {
1414
#[coroutine]
1515
|bar| {
1616
//~^ NOTE: found signature defined here
17+
//~| NOTE: return type was inferred to be
1718
if bar {
1819
yield bar;
1920
}

tests/ui/coroutine/issue-88653.stderr

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
error[E0631]: type mismatch in coroutine arguments
22
--> $DIR/issue-88653.rs:8:22
33
|
4-
LL | fn foo(bar: bool) -> impl Coroutine<(bool,)> {
5-
| ^^^^^^^^^^^^^^^^^^^^^^^ expected due to this
4+
LL | fn foo(bar: bool) -> impl Coroutine<(bool,)> {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ expected due to this
66
...
7-
LL | |bar| {
8-
| ----- found signature defined here
7+
LL | |bar| {
8+
| -----
9+
| |
10+
| _____found signature defined here
11+
| |
12+
LL | |
13+
LL | |
14+
LL | | if bar {
15+
LL | | yield bar;
16+
LL | | }
17+
LL | | }
18+
| |_____- return type was inferred to be `{coroutine@$DIR/issue-88653.rs:15:5: 15:10}` here
919
|
1020
= note: expected coroutine signature `fn((bool,)) -> _`
1121
found coroutine signature `fn(bool) -> _`

tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg

+17-13
Loading

tests/ui/impl-trait/issue-55872-1.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ error[E0277]: the trait bound `S: Copy` is not satisfied in `(S, T)`
1212
|
1313
LL | fn foo<T: Default>() -> Self::E {
1414
| ^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `S`
15+
...
16+
LL | (S::default(), T::default())
17+
| ---------------------------- return type was inferred to be `(S, T)` here
1518
|
1619
= note: required because it appears within the type `(S, T)`
1720
help: consider further restricting this bound
@@ -24,6 +27,9 @@ error[E0277]: the trait bound `T: Copy` is not satisfied in `(S, T)`
2427
|
2528
LL | fn foo<T: Default>() -> Self::E {
2629
| ^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `T`
30+
...
31+
LL | (S::default(), T::default())
32+
| ---------------------------- return type was inferred to be `(S, T)` here
2733
|
2834
= note: required because it appears within the type `(S, T)`
2935
help: consider further restricting this bound

tests/ui/impl-trait/issue-55872-3.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}:
33
|
44
LL | fn foo<T>() -> Self::E {
55
| ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}`
6+
LL |
7+
LL | async {}
8+
| -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}` here
69

710
error: aborting due to 1 previous error
811

tests/ui/impl-trait/nested_impl_trait.stderr

+6-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfie
4646
--> $DIR/nested_impl_trait.rs:6:46
4747
|
4848
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
49-
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
49+
| ^^^^^^^^^^^^^^^^^^^^^ - return type was inferred to be `impl Into<u32>` here
50+
| |
51+
| the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
5052
|
5153
= help: the trait `Into<U>` is implemented for `T`
5254
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
@@ -55,7 +57,9 @@ error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfie
5557
--> $DIR/nested_impl_trait.rs:19:34
5658
|
5759
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
58-
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
60+
| ^^^^^^^^^^^^^^^^^^^^^ - return type was inferred to be `impl Into<u32>` here
61+
| |
62+
| the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
5963
|
6064
= help: the trait `Into<U>` is implemented for `T`
6165
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`

tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0283]: type annotations needed
33
|
44
LL | fn run() -> Foo<impl Future<Output = ()>> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
6+
LL |
7+
LL | loop {}
8+
| ------- return type was inferred to be `!` here
69
|
710
= note: cannot satisfy `_: Future`
811

tests/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0271]: type mismatch resolving `<() as Super>::Assoc == ()`
33
|
44
LL | fn test() -> impl Test {
55
| ^^^^^^^^^ type mismatch resolving `<() as Super>::Assoc == ()`
6+
LL |
7+
LL | ()
8+
| -- return type was inferred to be `()` here
69
|
710
note: expected this to be `()`
811
--> $DIR/projection-mismatch-in-impl-where-clause.rs:6:18

tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied
33
|
44
LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>`
6+
LL |
7+
LL | Ok(())
8+
| ------ return type was inferred to be `Result<(), _>` here
69
|
710
help: this trait has no implementations, consider adding one
811
--> $DIR/lifetime-elision-return-type-trait.rs:1:1

tests/ui/lint/issue-106991.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0271]: expected `foo` to be a fn item that returns `i32`, but it returns
33
|
44
LL | fn bar() -> impl Iterator<Item = i32> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `()`
6+
...
7+
LL | x.iter_mut().map(foo)
8+
| --------------------- return type was inferred to be `Map<std::slice::IterMut<'_, Vec<u8>>, for<'a> fn(&'a mut Vec<u8>) {foo}>` here
69
|
710
= note: required for `Map<std::slice::IterMut<'_, Vec<u8>>, for<'a> fn(&'a mut Vec<u8>) {foo}>` to implement `Iterator`
811

tests/ui/never_type/impl_trait_fallback2.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): T` is not satisfied
33
|
44
LL | fn should_ret_unit() -> impl T {
55
| ^^^^^^ the trait `T` is not implemented for `()`
6+
LL |
7+
LL | panic!()
8+
| -------- return type was inferred to be `_` here
69
|
710
= help: the trait `T` is implemented for `i32`
811

@@ -11,6 +14,9 @@ error[E0277]: the trait bound `(): T` is not satisfied
1114
|
1215
LL | fn a() -> Foo {
1316
| ^^^ the trait `T` is not implemented for `()`
17+
LL |
18+
LL | panic!()
19+
| -------- return type was inferred to be `_` here
1420
|
1521
= help: the trait `T` is implemented for `i32`
1622

tests/ui/never_type/impl_trait_fallback3.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): T` is not satisfied
33
|
44
LL | fn a() -> Foo {
55
| ^^^ the trait `T` is not implemented for `()`
6+
...
7+
LL | panic!()
8+
| -------- return type was inferred to be `_` here
69
|
710
help: this trait has no implementations, consider adding one
811
--> $DIR/impl_trait_fallback3.rs:5:1

tests/ui/never_type/impl_trait_fallback4.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): T` is not satisfied
33
|
44
LL | fn foo() -> impl T {
55
| ^^^^^^ the trait `T` is not implemented for `()`
6+
LL |
7+
LL | panic!()
8+
| -------- return type was inferred to be `_` here
69
|
710
help: this trait has no implementations, consider adding one
811
--> $DIR/impl_trait_fallback4.rs:3:1

tests/ui/type-alias-impl-trait/fallback.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error[E0283]: type annotations needed
44
LL | fn unconstrained_foo() -> Wrapper<Foo> {
55
| ------------ type must be known at this point
66
LL | Wrapper::Second
7-
| ^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the enum `Wrapper`
7+
| ^^^^^^^^^^^^^^^
8+
| |
9+
| cannot infer type of the type parameter `T` declared on the enum `Wrapper`
10+
| return type was inferred to be `Wrapper<_>` here
811
|
912
= note: cannot satisfy `_: Copy`
1013
help: consider specifying the generic argument

tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ error[E0277]: the trait bound `{integer}: Trait<()>` is not satisfied
1717
|
1818
LL | fn produce() -> impl for<T> Trait<(), Assoc = impl Trait<T>> {
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<()>` is not implemented for `{integer}`
20+
...
21+
LL | 16
22+
| -- return type was inferred to be `{integer}` here
2023
|
2124
help: this trait has no implementations, consider adding one
2225
--> $DIR/non-lifetime-binder-in-constraint.rs:4:1

0 commit comments

Comments
 (0)