diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 553bb61ed04..64edeb35dd2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3563,17 +3563,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )]); } ObligationCauseCode::OpaqueReturnType(expr_info) => { - if let Some((expr_ty, hir_id)) = expr_info { - let expr_ty = self.tcx.short_ty_string(expr_ty, long_ty_file); - let expr = self.infcx.tcx.hir().expect_expr(hir_id); - err.span_label( - expr.span, - with_forced_trimmed_paths!(format!( - "return type was inferred to be `{expr_ty}` here", - )), - ); - suggest_remove_deref(err, &expr); - } + let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info { + let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file); + let expr = tcx.hir().expect_expr(hir_id); + (expr_ty, expr) + } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id() + && let body = tcx.hir().body(body_id) + && let hir::ExprKind::Block(block, _) = body.value.kind + && let Some(expr) = block.expr + && let Some(expr_ty) = self + .typeck_results + .as_ref() + .and_then(|typeck| typeck.node_type_opt(expr.hir_id)) + && let Some(pred) = predicate.as_clause() + && let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder() + && self.can_eq(param_env, pred.self_ty(), expr_ty) + { + let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file); + (expr_ty, expr) + } else { + return; + }; + err.span_label( + expr.span, + with_forced_trimmed_paths!(format!( + "return type was inferred to be `{expr_ty}` here", + )), + ); + suggest_remove_deref(err, &expr); } } } diff --git a/tests/ui/async-await/async-error-span.stderr b/tests/ui/async-await/async-error-span.stderr index 44f1583f4cc..37b5c329a7d 100644 --- a/tests/ui/async-await/async-error-span.stderr +++ b/tests/ui/async-await/async-error-span.stderr @@ -3,6 +3,9 @@ error[E0277]: `()` is not a future | LL | fn get_future() -> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future +LL | +LL | panic!() + | -------- return type was inferred to be `_` here | = help: the trait `Future` is not implemented for `()` diff --git a/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr index c7d6507fd79..839299f1c94 100644 --- a/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr +++ b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr @@ -5,7 +5,10 @@ LL | fn foo() -> impl Coroutine { | ^^^^^^^^^^^^^^^^^^ expected due to this ... LL | |_: ()| {} - | ------- found signature defined here + | ---------- + | | + | found signature defined here + | return type was inferred to be `{coroutine@$DIR/arg-count-mismatch-on-unit-input.rs:8:5: 8:12}` here | = note: expected coroutine signature `fn(u8) -> _` found coroutine signature `fn(()) -> _` diff --git a/tests/ui/coroutine/gen_block_is_coro.stderr b/tests/ui/coroutine/gen_block_is_coro.stderr index afcdce1d58d..083e738f3ec 100644 --- a/tests/ui/coroutine/gen_block_is_coro.stderr +++ b/tests/ui/coroutine/gen_block_is_coro.stderr @@ -3,18 +3,24 @@ error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}: C | LL | fn foo() -> impl Coroutine { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}: Coroutine` is not satisfied --> $DIR/gen_block_is_coro.rs:10:13 | LL | fn bar() -> impl Coroutine { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}` +LL | gen { yield 42 } + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}` here error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}: Coroutine` is not satisfied --> $DIR/gen_block_is_coro.rs:14:13 | LL | fn baz() -> impl Coroutine { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}` +LL | gen { yield 42 } + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}` here error: aborting due to 3 previous errors diff --git a/tests/ui/coroutine/gen_block_is_no_future.stderr b/tests/ui/coroutine/gen_block_is_no_future.stderr index bf0985a76a2..43e18dbc2a9 100644 --- a/tests/ui/coroutine/gen_block_is_no_future.stderr +++ b/tests/ui/coroutine/gen_block_is_no_future.stderr @@ -3,6 +3,8 @@ error[E0277]: `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a fut | LL | fn foo() -> impl std::future::Future { | ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a future +LL | gen { yield 42 } + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` here | = help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` diff --git a/tests/ui/coroutine/issue-88653.rs b/tests/ui/coroutine/issue-88653.rs index 3afd12a2093..b5936c7960d 100644 --- a/tests/ui/coroutine/issue-88653.rs +++ b/tests/ui/coroutine/issue-88653.rs @@ -14,6 +14,7 @@ fn foo(bar: bool) -> impl Coroutine<(bool,)> { #[coroutine] |bar| { //~^ NOTE: found signature defined here + //~| NOTE: return type was inferred to be if bar { yield bar; } diff --git a/tests/ui/coroutine/issue-88653.stderr b/tests/ui/coroutine/issue-88653.stderr index 8a23ad17b8b..ef0cc11dde8 100644 --- a/tests/ui/coroutine/issue-88653.stderr +++ b/tests/ui/coroutine/issue-88653.stderr @@ -1,11 +1,21 @@ error[E0631]: type mismatch in coroutine arguments --> $DIR/issue-88653.rs:8:22 | -LL | fn foo(bar: bool) -> impl Coroutine<(bool,)> { - | ^^^^^^^^^^^^^^^^^^^^^^^ expected due to this +LL | fn foo(bar: bool) -> impl Coroutine<(bool,)> { + | ^^^^^^^^^^^^^^^^^^^^^^^ expected due to this ... -LL | |bar| { - | ----- found signature defined here +LL | |bar| { + | ----- + | | + | _____found signature defined here + | | +LL | | +LL | | +LL | | if bar { +LL | | yield bar; +LL | | } +LL | | } + | |_____- return type was inferred to be `{coroutine@$DIR/issue-88653.rs:15:5: 15:10}` here | = note: expected coroutine signature `fn((bool,)) -> _` found coroutine signature `fn(bool) -> _` diff --git a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg index 277fd1536bc..1a79a9d7efa 100644 --- a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg +++ b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg @@ -1,4 +1,4 @@ - + ` is implemented for `T` = note: required for `impl Into` to implement `Into` @@ -55,7 +57,9 @@ error[E0277]: the trait bound `impl Debug: From>` is not satisfie --> $DIR/nested_impl_trait.rs:19:34 | LL | fn bad(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Debug` + | ^^^^^^^^^^^^^^^^^^^^^ - return type was inferred to be `impl Into` here + | | + | the trait `From>` is not implemented for `impl Debug` | = help: the trait `Into` is implemented for `T` = note: required for `impl Into` to implement `Into` diff --git a/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr index 5ade6a69d4b..6866f3f5350 100644 --- a/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr +++ b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr @@ -3,6 +3,9 @@ error[E0283]: type annotations needed | LL | fn run() -> Foo> { | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type +LL | +LL | loop {} + | ------- return type was inferred to be `!` here | = note: cannot satisfy `_: Future` diff --git a/tests/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr b/tests/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr index fa71adc6380..96e18f1f1cb 100644 --- a/tests/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr +++ b/tests/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr @@ -3,6 +3,9 @@ error[E0271]: type mismatch resolving `<() as Super>::Assoc == ()` | LL | fn test() -> impl Test { | ^^^^^^^^^ type mismatch resolving `<() as Super>::Assoc == ()` +LL | +LL | () + | -- return type was inferred to be `()` here | note: expected this to be `()` --> $DIR/projection-mismatch-in-impl-where-clause.rs:6:18 diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr index 1664466df3c..f26d6b8d0be 100644 --- a/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied | LL | fn foo() -> impl Future> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>` +LL | +LL | Ok(()) + | ------ return type was inferred to be `Result<(), _>` here | help: this trait has no implementations, consider adding one --> $DIR/lifetime-elision-return-type-trait.rs:1:1 diff --git a/tests/ui/lint/issue-106991.stderr b/tests/ui/lint/issue-106991.stderr index 9b4fab68102..0441a6377d0 100644 --- a/tests/ui/lint/issue-106991.stderr +++ b/tests/ui/lint/issue-106991.stderr @@ -3,6 +3,9 @@ error[E0271]: expected `foo` to be a fn item that returns `i32`, but it returns | LL | fn bar() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `()` +... +LL | x.iter_mut().map(foo) + | --------------------- return type was inferred to be `Map>, for<'a> fn(&'a mut Vec) {foo}>` here | = note: required for `Map>, for<'a> fn(&'a mut Vec) {foo}>` to implement `Iterator` diff --git a/tests/ui/never_type/impl_trait_fallback2.stderr b/tests/ui/never_type/impl_trait_fallback2.stderr index 78cc83bdbfa..4c32dce465b 100644 --- a/tests/ui/never_type/impl_trait_fallback2.stderr +++ b/tests/ui/never_type/impl_trait_fallback2.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn should_ret_unit() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` +LL | +LL | panic!() + | -------- return type was inferred to be `_` here | = help: the trait `T` is implemented for `i32` @@ -11,6 +14,9 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn a() -> Foo { | ^^^ the trait `T` is not implemented for `()` +LL | +LL | panic!() + | -------- return type was inferred to be `_` here | = help: the trait `T` is implemented for `i32` diff --git a/tests/ui/never_type/impl_trait_fallback3.stderr b/tests/ui/never_type/impl_trait_fallback3.stderr index e2246eea17c..fde8d0896dd 100644 --- a/tests/ui/never_type/impl_trait_fallback3.stderr +++ b/tests/ui/never_type/impl_trait_fallback3.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn a() -> Foo { | ^^^ the trait `T` is not implemented for `()` +... +LL | panic!() + | -------- return type was inferred to be `_` here | help: this trait has no implementations, consider adding one --> $DIR/impl_trait_fallback3.rs:5:1 diff --git a/tests/ui/never_type/impl_trait_fallback4.stderr b/tests/ui/never_type/impl_trait_fallback4.stderr index 8f6b5cfea68..c4fc949373a 100644 --- a/tests/ui/never_type/impl_trait_fallback4.stderr +++ b/tests/ui/never_type/impl_trait_fallback4.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn foo() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` +LL | +LL | panic!() + | -------- return type was inferred to be `_` here | help: this trait has no implementations, consider adding one --> $DIR/impl_trait_fallback4.rs:3:1 diff --git a/tests/ui/type-alias-impl-trait/fallback.stderr b/tests/ui/type-alias-impl-trait/fallback.stderr index 5250252a0da..c909ab66f0e 100644 --- a/tests/ui/type-alias-impl-trait/fallback.stderr +++ b/tests/ui/type-alias-impl-trait/fallback.stderr @@ -4,7 +4,10 @@ error[E0283]: type annotations needed LL | fn unconstrained_foo() -> Wrapper { | ------------ type must be known at this point LL | Wrapper::Second - | ^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the enum `Wrapper` + | ^^^^^^^^^^^^^^^ + | | + | cannot infer type of the type parameter `T` declared on the enum `Wrapper` + | return type was inferred to be `Wrapper<_>` here | = note: cannot satisfy `_: Copy` help: consider specifying the generic argument diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr index fa3306ff11f..6e5bd34ce38 100644 --- a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr +++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr @@ -17,6 +17,9 @@ error[E0277]: the trait bound `{integer}: Trait<()>` is not satisfied | LL | fn produce() -> impl for Trait<(), Assoc = impl Trait> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<()>` is not implemented for `{integer}` +... +LL | 16 + | -- return type was inferred to be `{integer}` here | help: this trait has no implementations, consider adding one --> $DIR/non-lifetime-binder-in-constraint.rs:4:1