From e4a18a665b4b8d9384bb332eb97af23221b4ff39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Jul 2026 20:26:57 +0000 Subject: [PATCH 1/8] Provide more context when an expected type was a type parameter This becomes particularly confusing when a type parameter has a default. ``` --> $DIR/default-type-parameter.rs:8:17 | LL | fn foo() -> u32 { 0 } | ^^^ expected `()`, found `u32` | note: type in trait --> $DIR/default-type-parameter.rs:2:17 | LL | fn foo() -> T; | ^ = note: expected signature `fn() -> ()` found signature `fn() -> u32` note: expected to match this type parameter --> $DIR/default-type-parameter.rs:1:13 | LL | trait Trait { | ^^^^^^ help: change the output type to match the trait | LL - fn foo() -> u32 { 0 } LL + fn foo() -> () { 0 } ``` --- .../src/check/compare_impl_item.rs | 13 +++++ tests/ui/compare-method/bad-self-type.stderr | 5 ++ .../compare-method/default-type-parameter.rs | 14 +++++ .../default-type-parameter.stderr | 51 +++++++++++++++++++ tests/ui/compare-method/issue-90444.stderr | 2 + .../reordered-type-param.stderr | 5 ++ .../fn-impl-mismatched-param-type.stderr | 6 +++ .../traits/wrong-mul-method-signature.stderr | 4 ++ 8 files changed, 100 insertions(+) create mode 100644 tests/ui/compare-method/default-type-parameter.rs create mode 100644 tests/ui/compare-method/default-type-parameter.stderr diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 8a7ad70f8ebb1..6f8baee71e176 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1092,6 +1092,19 @@ fn report_trait_method_mismatch<'tcx>( None, ); + if let TypeError::ArgumentSorts(_, i) = &terr + && let Some(ty) = + tcx.fn_sig(trait_m.def_id).skip_binder().inputs_and_output().skip_binder().get(*i) + && let ty::Param(param) = ty.kind() + { + // The expected type corresponds to a type parameter, which migh thave a default type or + // have been explicitly set in the `impl` with a different type. + let generics = tcx.generics_of(trait_m.def_id); + let param = generics.type_param(*param, tcx); + let span = tcx.def_span(param.def_id); + diag.span_note(span, format!("expected to match this type parameter")); + } + diag.emit_err() } diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr index bc1587883a352..ea5a45214702f 100644 --- a/tests/ui/compare-method/bad-self-type.stderr +++ b/tests/ui/compare-method/bad-self-type.stderr @@ -24,6 +24,11 @@ LL | fn foo(self); | ^^^^ = note: expected signature `fn(MyFuture)` found signature `fn(Box)` +note: expected to match this type parameter + --> $DIR/bad-self-type.rs:16:1 + | +LL | trait T { + | ^^^^^^^ help: change the self-receiver type to match the trait | LL - fn foo(self: Box) {} diff --git a/tests/ui/compare-method/default-type-parameter.rs b/tests/ui/compare-method/default-type-parameter.rs new file mode 100644 index 0000000000000..92746fb4ebcad --- /dev/null +++ b/tests/ui/compare-method/default-type-parameter.rs @@ -0,0 +1,14 @@ +trait Trait { + fn foo() -> T; +} + +struct S; + +impl Trait for S { + fn foo() -> u32 { 0 } //~ ERROR +} +impl Trait for () { + fn foo() -> u32 { 0 } //~ ERROR +} + +fn main() {} diff --git a/tests/ui/compare-method/default-type-parameter.stderr b/tests/ui/compare-method/default-type-parameter.stderr new file mode 100644 index 0000000000000..a97e772dc238d --- /dev/null +++ b/tests/ui/compare-method/default-type-parameter.stderr @@ -0,0 +1,51 @@ +error[E0053]: method `foo` has an incompatible type for trait + --> $DIR/default-type-parameter.rs:8:17 + | +LL | fn foo() -> u32 { 0 } + | ^^^ expected `()`, found `u32` + | +note: type in trait + --> $DIR/default-type-parameter.rs:2:17 + | +LL | fn foo() -> T; + | ^ + = note: expected signature `fn() -> ()` + found signature `fn() -> u32` +note: expected to match this type parameter + --> $DIR/default-type-parameter.rs:1:13 + | +LL | trait Trait { + | ^^^^^^ +help: change the output type to match the trait + | +LL - fn foo() -> u32 { 0 } +LL + fn foo() -> () { 0 } + | + +error[E0053]: method `foo` has an incompatible type for trait + --> $DIR/default-type-parameter.rs:11:17 + | +LL | fn foo() -> u32 { 0 } + | ^^^ expected `i32`, found `u32` + | +note: type in trait + --> $DIR/default-type-parameter.rs:2:17 + | +LL | fn foo() -> T; + | ^ + = note: expected signature `fn() -> i32` + found signature `fn() -> u32` +note: expected to match this type parameter + --> $DIR/default-type-parameter.rs:1:13 + | +LL | trait Trait { + | ^^^^^^ +help: change the output type to match the trait + | +LL - fn foo() -> u32 { 0 } +LL + fn foo() -> i32 { 0 } + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/compare-method/issue-90444.stderr b/tests/ui/compare-method/issue-90444.stderr index c69d63b3e30bc..8071dbc4442d5 100644 --- a/tests/ui/compare-method/issue-90444.stderr +++ b/tests/ui/compare-method/issue-90444.stderr @@ -20,6 +20,8 @@ LL | fn from(_: fn((), (), u64)) -> Self { | = note: expected signature `fn(fn((), (), u32)) -> B` found signature `fn(fn((), (), u64)) -> B` +note: expected to match this type parameter + --> $SRC_DIR/core/src/convert/mod.rs:LL:COL help: change the parameter type to match the trait | LL - fn from(_: fn((), (), u64)) -> Self { diff --git a/tests/ui/compare-method/reordered-type-param.stderr b/tests/ui/compare-method/reordered-type-param.stderr index 536364871a368..8bb88cb185999 100644 --- a/tests/ui/compare-method/reordered-type-param.stderr +++ b/tests/ui/compare-method/reordered-type-param.stderr @@ -16,6 +16,11 @@ LL | fn b(&self, x: C) -> C; found signature `fn(&E, G) -> G` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters +note: expected to match this type parameter + --> $DIR/reordered-type-param.rs:7:8 + | +LL | fn b(&self, x: C) -> C; + | ^ help: change the parameter type to match the trait | LL - fn b(&self, _x: G) -> G { panic!() } diff --git a/tests/ui/fn_traits/fn-impl-mismatched-param-type.stderr b/tests/ui/fn_traits/fn-impl-mismatched-param-type.stderr index b7aa3d29f0d7d..1e2819d48fb6e 100644 --- a/tests/ui/fn_traits/fn-impl-mismatched-param-type.stderr +++ b/tests/ui/fn_traits/fn-impl-mismatched-param-type.stderr @@ -8,6 +8,8 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {} | = note: expected signature `extern "rust-call" fn(&Foo, (&'a _,))` found signature `extern "rust-call" fn(&Foo, (_,))` +note: expected to match this type parameter + --> $SRC_DIR/core/src/ops/function.rs:LL:COL help: change the parameter type to match the trait | LL | extern "rust-call" fn call(&self, (_,): (&'a T,)) {} @@ -23,6 +25,8 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} | = note: expected signature `extern "rust-call" fn(&mut Foo, (&'a _,))` found signature `extern "rust-call" fn(&mut Foo, (_,))` +note: expected to match this type parameter + --> $SRC_DIR/core/src/ops/function.rs:LL:COL help: change the parameter type to match the trait | LL | extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {} @@ -39,6 +43,8 @@ LL | extern "rust-call" fn call_once(self, (_,): (T,)) {} | = note: expected signature `extern "rust-call" fn(Foo, (&'a _,))` found signature `extern "rust-call" fn(Foo, (_,))` +note: expected to match this type parameter + --> $SRC_DIR/core/src/ops/function.rs:LL:COL help: change the parameter type to match the trait | LL | extern "rust-call" fn call_once(self, (_,): (&'a T,)) {} diff --git a/tests/ui/traits/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr index bdfc4320631b0..8cef50ef1d6f7 100644 --- a/tests/ui/traits/wrong-mul-method-signature.stderr +++ b/tests/ui/traits/wrong-mul-method-signature.stderr @@ -6,6 +6,8 @@ LL | fn mul(self, s: &f64) -> Vec1 { | = note: expected signature `fn(Vec1, _) -> Vec1` found signature `fn(Vec1, &_) -> Vec1` +note: expected to match this type parameter + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the parameter type to match the trait | LL - fn mul(self, s: &f64) -> Vec1 { @@ -20,6 +22,8 @@ LL | fn mul(self, s: f64) -> Vec2 { | = note: expected signature `fn(Vec2, Vec2) -> f64` found signature `fn(Vec2, f64) -> Vec2` +note: expected to match this type parameter + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the parameter type to match the trait | LL - fn mul(self, s: f64) -> Vec2 { From b1476a0e58fb3fdbe6218f3a29853d48a1c5c5e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 5 Oct 2026 20:00:33 +0000 Subject: [PATCH 2/8] Only point at param with default type --- .../rustc_hir_analysis/src/check/compare_impl_item.rs | 10 ++++++---- tests/ui/compare-method/bad-self-type.stderr | 5 ----- tests/ui/compare-method/issue-90444.stderr | 2 -- tests/ui/compare-method/reordered-type-param.stderr | 5 ----- .../ui/fn_traits/fn-impl-mismatched-param-type.stderr | 6 ------ 5 files changed, 6 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 6f8baee71e176..51431672b736b 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1096,12 +1096,14 @@ fn report_trait_method_mismatch<'tcx>( && let Some(ty) = tcx.fn_sig(trait_m.def_id).skip_binder().inputs_and_output().skip_binder().get(*i) && let ty::Param(param) = ty.kind() - { // The expected type corresponds to a type parameter, which migh thave a default type or // have been explicitly set in the `impl` with a different type. - let generics = tcx.generics_of(trait_m.def_id); - let param = generics.type_param(*param, tcx); - let span = tcx.def_span(param.def_id); + && let generics = tcx.generics_of(trait_m.def_id) + && let param = generics.type_param(*param, tcx) + && let GenericParamDefKind::Type { has_default: true, .. } = param.kind + { + let mut span: MultiSpan = tcx.def_span(param.def_id).into(); + span.push_span_context(tcx.def_span(trait_m.container_id(tcx)).shrink_to_lo()); diag.span_note(span, format!("expected to match this type parameter")); } diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr index ea5a45214702f..bc1587883a352 100644 --- a/tests/ui/compare-method/bad-self-type.stderr +++ b/tests/ui/compare-method/bad-self-type.stderr @@ -24,11 +24,6 @@ LL | fn foo(self); | ^^^^ = note: expected signature `fn(MyFuture)` found signature `fn(Box)` -note: expected to match this type parameter - --> $DIR/bad-self-type.rs:16:1 - | -LL | trait T { - | ^^^^^^^ help: change the self-receiver type to match the trait | LL - fn foo(self: Box) {} diff --git a/tests/ui/compare-method/issue-90444.stderr b/tests/ui/compare-method/issue-90444.stderr index 8071dbc4442d5..c69d63b3e30bc 100644 --- a/tests/ui/compare-method/issue-90444.stderr +++ b/tests/ui/compare-method/issue-90444.stderr @@ -20,8 +20,6 @@ LL | fn from(_: fn((), (), u64)) -> Self { | = note: expected signature `fn(fn((), (), u32)) -> B` found signature `fn(fn((), (), u64)) -> B` -note: expected to match this type parameter - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL help: change the parameter type to match the trait | LL - fn from(_: fn((), (), u64)) -> Self { diff --git a/tests/ui/compare-method/reordered-type-param.stderr b/tests/ui/compare-method/reordered-type-param.stderr index 8bb88cb185999..536364871a368 100644 --- a/tests/ui/compare-method/reordered-type-param.stderr +++ b/tests/ui/compare-method/reordered-type-param.stderr @@ -16,11 +16,6 @@ LL | fn b(&self, x: C) -> C; found signature `fn(&E, G) -> G` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -note: expected to match this type parameter - --> $DIR/reordered-type-param.rs:7:8 - | -LL | fn b(&self, x: C) -> C; - | ^ help: change the parameter type to match the trait | LL - fn b(&self, _x: G) -> G { panic!() } diff --git a/tests/ui/fn_traits/fn-impl-mismatched-param-type.stderr b/tests/ui/fn_traits/fn-impl-mismatched-param-type.stderr index 1e2819d48fb6e..b7aa3d29f0d7d 100644 --- a/tests/ui/fn_traits/fn-impl-mismatched-param-type.stderr +++ b/tests/ui/fn_traits/fn-impl-mismatched-param-type.stderr @@ -8,8 +8,6 @@ LL | extern "rust-call" fn call(&self, (_,): (T,)) {} | = note: expected signature `extern "rust-call" fn(&Foo, (&'a _,))` found signature `extern "rust-call" fn(&Foo, (_,))` -note: expected to match this type parameter - --> $SRC_DIR/core/src/ops/function.rs:LL:COL help: change the parameter type to match the trait | LL | extern "rust-call" fn call(&self, (_,): (&'a T,)) {} @@ -25,8 +23,6 @@ LL | extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {} | = note: expected signature `extern "rust-call" fn(&mut Foo, (&'a _,))` found signature `extern "rust-call" fn(&mut Foo, (_,))` -note: expected to match this type parameter - --> $SRC_DIR/core/src/ops/function.rs:LL:COL help: change the parameter type to match the trait | LL | extern "rust-call" fn call_mut(&mut self, (_,): (&'a T,)) {} @@ -43,8 +39,6 @@ LL | extern "rust-call" fn call_once(self, (_,): (T,)) {} | = note: expected signature `extern "rust-call" fn(Foo, (&'a _,))` found signature `extern "rust-call" fn(Foo, (_,))` -note: expected to match this type parameter - --> $SRC_DIR/core/src/ops/function.rs:LL:COL help: change the parameter type to match the trait | LL | extern "rust-call" fn call_once(self, (_,): (&'a T,)) {} From b1cf8bd33fc05c05941d01010e67c345a462d2b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 5 Oct 2026 20:58:36 +0000 Subject: [PATCH 3/8] Tweak message --- .../src/check/compare_impl_item.rs | 19 +++++++++++++++++-- .../default-type-parameter.stderr | 4 ++-- .../traits/wrong-mul-method-signature.stderr | 4 ++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 51431672b736b..47a623bee8659 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::{ TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, Upcast, }; -use rustc_span::{BytePos, DUMMY_SP, Span, bug, span_bug}; +use rustc_span::{BytePos, DUMMY_SP, Span, bug, kw, span_bug}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::regions::InferCtxtRegionExt; @@ -1104,7 +1104,22 @@ fn report_trait_method_mismatch<'tcx>( { let mut span: MultiSpan = tcx.def_span(param.def_id).into(); span.push_span_context(tcx.def_span(trait_m.container_id(tcx)).shrink_to_lo()); - diag.span_note(span, format!("expected to match this type parameter")); + + let param_name = param.name; + let msg = if let Some(ty) = trait_sig.inputs_and_output.get(*i) + && infcx.can_eq(param_env, *ty, tcx.type_of(param.def_id).skip_binder()) + { + format!("expected to match the default of type parameter `{param_name}`") + } else if let Some(ty) = trait_sig.inputs_and_output.get(*i) + && let ty::Param(p) = tcx.type_of(param.def_id).skip_binder().kind() + && p.name == kw::SelfUpper + && infcx.can_eq(param_env, *ty, impl_trait_ref.self_ty()) + { + format!("expected to match the `Self` default of type parameter `{param_name}`") + } else { + format!("expected to match type parameter `{param_name}`") + }; + diag.span_note(span, msg); } diag.emit_err() diff --git a/tests/ui/compare-method/default-type-parameter.stderr b/tests/ui/compare-method/default-type-parameter.stderr index a97e772dc238d..71952e9274987 100644 --- a/tests/ui/compare-method/default-type-parameter.stderr +++ b/tests/ui/compare-method/default-type-parameter.stderr @@ -11,7 +11,7 @@ LL | fn foo() -> T; | ^ = note: expected signature `fn() -> ()` found signature `fn() -> u32` -note: expected to match this type parameter +note: expected to match the default of type parameter `T` --> $DIR/default-type-parameter.rs:1:13 | LL | trait Trait { @@ -35,7 +35,7 @@ LL | fn foo() -> T; | ^ = note: expected signature `fn() -> i32` found signature `fn() -> u32` -note: expected to match this type parameter +note: expected to match type parameter `T` --> $DIR/default-type-parameter.rs:1:13 | LL | trait Trait { diff --git a/tests/ui/traits/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr index 8cef50ef1d6f7..d119274352f81 100644 --- a/tests/ui/traits/wrong-mul-method-signature.stderr +++ b/tests/ui/traits/wrong-mul-method-signature.stderr @@ -6,7 +6,7 @@ LL | fn mul(self, s: &f64) -> Vec1 { | = note: expected signature `fn(Vec1, _) -> Vec1` found signature `fn(Vec1, &_) -> Vec1` -note: expected to match this type parameter +note: expected to match type parameter `Rhs` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the parameter type to match the trait | @@ -22,7 +22,7 @@ LL | fn mul(self, s: f64) -> Vec2 { | = note: expected signature `fn(Vec2, Vec2) -> f64` found signature `fn(Vec2, f64) -> Vec2` -note: expected to match this type parameter +note: expected to match the `Self` default of type parameter `Rhs` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the parameter type to match the trait | From bd34b4d0ade6ba8f13ba8762dbf174f1f3b1fb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 5 Oct 2026 21:43:49 +0000 Subject: [PATCH 4/8] Provide trait and impl context when an assoc item doesn't agree with the trait ``` error[E0053]: method `foo` has an incompatible type for trait --> $DIR/async-example-desugared-boxed-in-trait.rs:11:28 | LL | impl MyTrait for i32 { LL | async fn foo(&self) -> i32 { | ^^^ expected `Pin>>`, found future | note: type in trait --> $DIR/async-example-desugared-boxed-in-trait.rs:7:22 | LL | trait MyTrait { LL | fn foo(&self) -> Pin + '_>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn(&_) -> Pin>>` found signature `fn(&_) -> impl Future` ``` --- .../src/check/compare_eii.rs | 2 +- .../src/check/compare_impl_item.rs | 27 +++++++++++++--- .../src/error_reporting/infer/mod.rs | 31 +++++++++++++------ .../traits/fulfillment_errors.rs | 2 +- ...ssociated-const-generic-obligations.stderr | 2 ++ .../associated-const-impl-wrong-type.stderr | 2 ++ .../defaults-specialization.stderr | 5 +++ ...nc-example-desugared-boxed-in-trait.stderr | 2 ++ ...project-to-specializable-projection.stderr | 2 ++ tests/ui/compare-method/bad-self-type.stderr | 8 +++++ .../default-type-parameter.stderr | 4 +++ tests/ui/compare-method/issue-90444.stderr | 2 ++ .../reordered-type-param.stderr | 3 ++ ...e-const-value-type-mismatch.current.stderr | 4 +++ .../issue-70942-trait-vs-impl-mismatch.stderr | 2 ++ ...eful-error-for-mistyped-assoc-const.stderr | 1 + .../target-expr-removal-defs-inside.stderr | 3 ++ .../unused-target-expr-in-glob-or-list.stderr | 6 +++- ...-gate-unboxed-closures-manual-impls.stderr | 4 +++ ...fn-traits-call-once-signature-15094.stderr | 2 ++ .../apit/impl-generic-mismatch-ab.stderr | 2 ++ .../in-assoc-type-unconstrained.stderr | 3 ++ .../ui/impl-trait/in-trait/deep-match.stderr | 12 ++++--- .../method-signature-matches.lt.stderr | 2 ++ .../method-signature-matches.mismatch.stderr | 2 ++ ...od-signature-matches.mismatch_async.stderr | 2 ++ .../in-trait/specialization-broken.stderr | 1 + ...s-impl-trait-declaration-too-subtle.stderr | 3 ++ tests/ui/impl-trait/trait_type.stderr | 1 + tests/ui/impl-trait/where-allowed.stderr | 3 ++ tests/ui/mir/inline-wrong-abi.stderr | 1 + tests/ui/mismatched_types/E0053.stderr | 6 ++++ tests/ui/mismatched_types/issue-112036.stderr | 1 + tests/ui/mismatched_types/issue-13033.stderr | 2 ++ .../trait-impl-fn-incompatibility.stderr | 6 ++++ tests/ui/mut/mismatch-trait-mut.e2015.stderr | 14 +++++++++ tests/ui/mut/mismatch-trait-mut.e2018.stderr | 14 +++++++++ .../pin-ergonomics/pinned-drop-check.stderr | 8 +++++ .../ui/splat/splat-invalid-trait-impl.stderr | 6 ++++ tests/ui/splat/splat-invalid.stderr | 6 ++++ tests/ui/splat/splat-non-tuple.stderr | 2 ++ .../target-feature/invalid-attribute.stderr | 3 ++ .../const-traits/eval-bad-signature.stderr | 2 ++ .../incompatible-method-multiline.stderr | 2 ++ tests/ui/traits/impl-method-mismatch.stderr | 3 ++ tests/ui/traits/issue-35869.stderr | 14 +++++++++ .../traits/wrong-mul-method-signature.stderr | 6 ++++ .../unnameable_type.stderr | 4 ++- .../typeck/mismatched-map-under-self.stderr | 4 +++ tests/ui/ufcs/ufcs-explicit-self-bad.stderr | 4 +++ tests/ui/unsafe/unsafe-trait-impl.stderr | 2 ++ 51 files changed, 232 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_eii.rs b/compiler/rustc_hir_analysis/src/check/compare_eii.rs index 6e22ce3d84b76..78944cfff352e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_eii.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_eii.rs @@ -511,7 +511,7 @@ fn report_eii_mismatch<'tcx>( infcx.err_ctxt().note_type_err( &mut diag, &cause, - trait_err_span.map(|sp| (sp, Cow::from("type in declaration"), false)), + trait_err_span.map(|sp| (sp.into(), Cow::from("type in declaration"), false)), Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound { expected: ty::Binder::dummy(declaration_sig), found: ty::Binder::dummy(external_impl_sig), diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 47a623bee8659..6c371a9cd1788 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -625,12 +625,16 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( "method `{}` has an incompatible return type for trait", trait_m.name() ); + diag.span_context(tcx.def_span(impl_m.container_id(tcx)).shrink_to_lo()); infcx.err_ctxt().note_type_err( &mut diag, &cause, - tcx.hir_get_if_local(impl_m.def_id) - .and_then(|node| node.fn_decl()) - .map(|decl| (decl.output.span(), Cow::from("return type in trait"), false)), + tcx.hir_get_if_local(trait_m.def_id).and_then(|node| node.fn_decl()).map(|decl| { + let mut span: MultiSpan = decl.output.span().into(); + span.push_span_context(tcx.def_span(trait_m.container_id(tcx)).shrink_to_lo()); + span.push_span_context(tcx.def_span(trait_m.def_id).shrink_to_lo()); + (span, Cow::from("return type in trait"), false) + }), Some(param_env.and(infer::ValuePairs::Terms(ExpectedFound { expected: trait_return_ty.into(), found: impl_return_ty.into(), @@ -1014,6 +1018,7 @@ fn report_trait_method_mismatch<'tcx>( "method `{}` has an incompatible type for trait", trait_m.name() ); + diag.span_context(tcx.def_span(impl_m.container_id(tcx)).shrink_to_lo()); match &terr { TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0) if trait_m.is_method() => @@ -1082,7 +1087,12 @@ fn report_trait_method_mismatch<'tcx>( infcx.err_ctxt().note_type_err( &mut diag, &cause, - trait_err_span.map(|sp| (sp, Cow::from("type in trait"), false)), + trait_err_span.map(|sp| { + let mut span: MultiSpan = sp.into(); + span.push_span_context(tcx.def_span(trait_m.container_id(tcx)).shrink_to_lo()); + span.push_span_context(tcx.def_span(trait_m.def_id).shrink_to_lo()); + (span, Cow::from("type in trait"), false) + }), Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound { expected: ty::Binder::dummy(trait_sig), found: ty::Binder::dummy(impl_sig), @@ -2395,6 +2405,8 @@ fn compare_const_clause_entailment<'tcx>( "implemented const `{}` has an incompatible type for trait", trait_ct.name() ); + diag.span_context(tcx.def_span(impl_ct.container_id(tcx)).shrink_to_lo()); + diag.span_context(tcx.def_span(impl_ct.def_id).shrink_to_lo()); let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| { // Add a label to the Span containing just the type of the const @@ -2405,7 +2417,12 @@ fn compare_const_clause_entailment<'tcx>( infcx.err_ctxt().note_type_err( &mut diag, &cause, - trait_c_span.map(|span| (span, Cow::from("type in trait"), false)), + trait_c_span.map(|span| { + let mut span: MultiSpan = span.into(); + span.push_span_context(tcx.def_span(trait_ct.container_id(tcx)).shrink_to_lo()); + span.push_span_context(tcx.def_span(trait_ct.def_id).shrink_to_lo()); + (span, Cow::from("type in trait"), false) + }), Some(param_env.and(infer::ValuePairs::Terms(ExpectedFound { expected: trait_ty.into(), found: impl_ty.into(), diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index eada6d2457e75..c86dcad2b51d4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -54,7 +54,9 @@ use rustc_abi::ExternAbi; use rustc_attr_ir::diagnostic::{CustomDiagnostic, Directive, FormatArgs}; use rustc_attr_ir::find_attr; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_errors::{Applicability, Diag, DiagStyledString, IntoDiagArg, StringPart, pluralize}; +use rustc_errors::{ + Applicability, Diag, DiagStyledString, IntoDiagArg, MultiSpan, StringPart, pluralize, +}; use rustc_hir as hir; use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_hir::intravisit::Visitor; @@ -1462,7 +1464,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { &self, diag: &mut Diag<'_>, cause: &ObligationCause<'tcx>, - secondary_span: Option<(Span, Cow<'static, str>, bool)>, + secondary_span: Option<(MultiSpan, Cow<'static, str>, bool)>, mut values: Option>>, terr: TypeError<'tcx>, prefer_label: bool, @@ -1638,9 +1640,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } }; - let mut label_or_note = |span: Span, msg: Cow<'static, str>| { - if (prefer_label && is_simple_error) || &[span] == diag.span.primary_spans() { - diag.span_label(span, msg); + let mut label_or_note = |span: MultiSpan, msg: Cow<'static, str>| { + if !span.has_span_labels() + && span.span_context().is_empty() + && ((prefer_label && is_simple_error) + || span.primary_spans() == diag.span.primary_spans()) + { + for span in span.primary_spans() { + diag.span_label(*span, msg.clone()); + } } else { diag.span_note(span, msg); } @@ -1656,9 +1664,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { terr.to_string(self.tcx) }; label_or_note(secondary_span, terr); - label_or_note(span, secondary_msg); + label_or_note(span.into(), secondary_msg); } else { - label_or_note(span, terr.to_string(self.tcx)); + label_or_note(span.into(), terr.to_string(self.tcx)); label_or_note(secondary_span, secondary_msg); } } else if let Some(values) = values @@ -1670,12 +1678,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let expected = with_forced_trimmed_paths!(e.sort_string(self.tcx)); let found = with_forced_trimmed_paths!(f.sort_string(self.tcx)); if expected == found { - label_or_note(span, terr.to_string(self.tcx)); + label_or_note(span.into(), terr.to_string(self.tcx)); } else { - label_or_note(span, Cow::from(format!("expected {expected}, found {found}"))); + label_or_note( + span.into(), + Cow::from(format!("expected {expected}, found {found}")), + ); } } else { - label_or_note(span, terr.to_string(self.tcx)); + label_or_note(span.into(), terr.to_string(self.tcx)); } if let Some(param_env) = param_env { diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index ca68ee77d67b3..acf1f4c165822 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1919,7 +1919,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .. }), ) => Some(( - ty.span, + ty.span.into(), with_forced_trimmed_paths!(Cow::from(format!( "type mismatch resolving `{}`", self.tcx.short_string( diff --git a/tests/ui/associated-consts/associated-const-generic-obligations.stderr b/tests/ui/associated-consts/associated-const-generic-obligations.stderr index 5ea85ff3b9899..f7431a1e690d7 100644 --- a/tests/ui/associated-consts/associated-const-generic-obligations.stderr +++ b/tests/ui/associated-consts/associated-const-generic-obligations.stderr @@ -1,12 +1,14 @@ error[E0326]: implemented const `FROM` has an incompatible type for trait --> $DIR/associated-const-generic-obligations.rs:14:17 | +LL | impl Bar for T { LL | const FROM: &'static str = "foo"; | ^^^^^^^^^^^^ expected associated type, found `&'static str` | note: type in trait --> $DIR/associated-const-generic-obligations.rs:10:17 | +LL | trait Bar: Foo { LL | const FROM: Self::Out; | ^^^^^^^^^ = note: expected associated type `::Out` diff --git a/tests/ui/associated-consts/associated-const-impl-wrong-type.stderr b/tests/ui/associated-consts/associated-const-impl-wrong-type.stderr index b91b777d5850f..6b517b4a00528 100644 --- a/tests/ui/associated-consts/associated-const-impl-wrong-type.stderr +++ b/tests/ui/associated-consts/associated-const-impl-wrong-type.stderr @@ -1,12 +1,14 @@ error[E0326]: implemented const `BAR` has an incompatible type for trait --> $DIR/associated-const-impl-wrong-type.rs:8:16 | +LL | impl Foo for SignedBar { LL | const BAR: i32 = -1; | ^^^ expected `u32`, found `i32` | note: type in trait --> $DIR/associated-const-impl-wrong-type.rs:2:16 | +LL | trait Foo { LL | const BAR: u32; | ^^^ diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index a03296af8a37b..ee0e9878e8e6a 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr @@ -1,12 +1,15 @@ error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:18:18 | +LL | default impl Tr for A { LL | fn make() -> u8 { 0 } | ^^ expected associated type, found `u8` | note: type in trait --> $DIR/defaults-specialization.rs:8:18 | +LL | trait Tr { +... LL | fn make() -> Self::Ty { | ^^^^^^^^ = note: expected signature `fn() -> as Tr>::Ty` @@ -30,6 +33,8 @@ LL | fn make() -> bool { true } note: type in trait --> $DIR/defaults-specialization.rs:8:18 | +LL | trait Tr { +... LL | fn make() -> Self::Ty { | ^^^^^^^^ = note: expected signature `fn() -> as Tr>::Ty` diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index c98df134072eb..6fcba3870cb0c 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -1,12 +1,14 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/async-example-desugared-boxed-in-trait.rs:11:28 | +LL | impl MyTrait for i32 { LL | async fn foo(&self) -> i32 { | ^^^ expected `Pin>>`, found future | note: type in trait --> $DIR/async-example-desugared-boxed-in-trait.rs:7:22 | +LL | trait MyTrait { LL | fn foo(&self) -> Pin + '_>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn(&_) -> Pin>>` diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr index d0c11565f4e90..4feaee82fef79 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr @@ -1,12 +1,14 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/dont-project-to-specializable-projection.rs:14:35 | +LL | impl MyTrait for MyStruct { LL | default async fn foo(_: T) -> &'static str { | ^^^^^^^^^^^^ expected associated type, found future | note: type in trait --> $DIR/dont-project-to-specializable-projection.rs:10:27 | +LL | trait MyTrait { LL | async fn foo(_: T) -> &'static str; | ^^^^^^^^^^^^ = note: expected signature `fn(_) -> impl Future` diff --git a/tests/ui/compare-method/bad-self-type.stderr b/tests/ui/compare-method/bad-self-type.stderr index bc1587883a352..fd5e13e5247ce 100644 --- a/tests/ui/compare-method/bad-self-type.stderr +++ b/tests/ui/compare-method/bad-self-type.stderr @@ -1,6 +1,8 @@ error[E0053]: method `poll` has an incompatible type for trait --> $DIR/bad-self-type.rs:10:13 | +LL | impl Future for MyFuture { +LL | type Output = (); LL | fn poll(self, _: &mut Context<'_>) -> Poll<()> { | ^^^^ expected `Pin<&mut MyFuture>`, found `MyFuture` | @@ -14,12 +16,14 @@ LL | fn poll(self: Pin<&mut MyFuture>, _: &mut Context<'_>) -> Poll<()> { error[E0053]: method `foo` has an incompatible type for trait --> $DIR/bad-self-type.rs:22:18 | +LL | impl T for MyFuture { LL | fn foo(self: Box) {} | ^^^^^^^^^ expected `MyFuture`, found `Box` | note: type in trait --> $DIR/bad-self-type.rs:17:12 | +LL | trait T { LL | fn foo(self); | ^^^^ = note: expected signature `fn(MyFuture)` @@ -33,12 +37,16 @@ LL + fn foo(self) {} error[E0053]: method `bar` has an incompatible type for trait --> $DIR/bad-self-type.rs:24:17 | +LL | impl T for MyFuture { +... LL | fn bar(self) {} | ^ expected `Option<()>`, found `()` | note: type in trait --> $DIR/bad-self-type.rs:18:21 | +LL | trait T { +LL | fn foo(self); LL | fn bar(self) -> Option<()>; | ^^^^^^^^^^ = note: expected signature `fn(MyFuture) -> Option<()>` diff --git a/tests/ui/compare-method/default-type-parameter.stderr b/tests/ui/compare-method/default-type-parameter.stderr index 71952e9274987..6b66aaa804ed0 100644 --- a/tests/ui/compare-method/default-type-parameter.stderr +++ b/tests/ui/compare-method/default-type-parameter.stderr @@ -1,12 +1,14 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/default-type-parameter.rs:8:17 | +LL | impl Trait for S { LL | fn foo() -> u32 { 0 } | ^^^ expected `()`, found `u32` | note: type in trait --> $DIR/default-type-parameter.rs:2:17 | +LL | trait Trait { LL | fn foo() -> T; | ^ = note: expected signature `fn() -> ()` @@ -25,12 +27,14 @@ LL + fn foo() -> () { 0 } error[E0053]: method `foo` has an incompatible type for trait --> $DIR/default-type-parameter.rs:11:17 | +LL | impl Trait for () { LL | fn foo() -> u32 { 0 } | ^^^ expected `i32`, found `u32` | note: type in trait --> $DIR/default-type-parameter.rs:2:17 | +LL | trait Trait { LL | fn foo() -> T; | ^ = note: expected signature `fn() -> i32` diff --git a/tests/ui/compare-method/issue-90444.stderr b/tests/ui/compare-method/issue-90444.stderr index c69d63b3e30bc..233def019ea42 100644 --- a/tests/ui/compare-method/issue-90444.stderr +++ b/tests/ui/compare-method/issue-90444.stderr @@ -1,6 +1,7 @@ error[E0053]: method `from` has an incompatible type for trait --> $DIR/issue-90444.rs:3:16 | +LL | impl From for A { LL | fn from(_: fn((), (), &mut ())) -> Self { | ^^^^^^^^^^^^^^^^^^^ types differ in mutability | @@ -15,6 +16,7 @@ LL + fn from(_: for<'a> fn((), (), &'a ())) -> Self { error[E0053]: method `from` has an incompatible type for trait --> $DIR/issue-90444.rs:11:16 | +LL | impl From for B { LL | fn from(_: fn((), (), u64)) -> Self { | ^^^^^^^^^^^^^^^ expected `u32`, found `u64` | diff --git a/tests/ui/compare-method/reordered-type-param.stderr b/tests/ui/compare-method/reordered-type-param.stderr index 536364871a368..bea7b43de48d0 100644 --- a/tests/ui/compare-method/reordered-type-param.stderr +++ b/tests/ui/compare-method/reordered-type-param.stderr @@ -1,6 +1,8 @@ error[E0053]: method `b` has an incompatible type for trait --> $DIR/reordered-type-param.rs:16:30 | +LL | impl A for E { +LL | // n.b. The error message is awful -- see #3404 LL | fn b(&self, _x: G) -> G { panic!() } | - - ^ expected type parameter `F`, found type parameter `G` | | | @@ -10,6 +12,7 @@ LL | fn b(&self, _x: G) -> G { panic!() } note: type in trait --> $DIR/reordered-type-param.rs:7:29 | +LL | trait A { LL | fn b(&self, x: C) -> C; | ^ = note: expected signature `fn(&E, F) -> F` diff --git a/tests/ui/const-generics/mgca/type-const-value-type-mismatch.current.stderr b/tests/ui/const-generics/mgca/type-const-value-type-mismatch.current.stderr index dc7f73f2549e8..5d0c6b06dfc8b 100644 --- a/tests/ui/const-generics/mgca/type-const-value-type-mismatch.current.stderr +++ b/tests/ui/const-generics/mgca/type-const-value-type-mismatch.current.stderr @@ -1,12 +1,16 @@ error[E0053]: method `arr` has an incompatible type for trait --> $DIR/type-const-value-type-mismatch.rs:24:5 | +LL | impl Array for A { +... LL | fn arr() -> [u8; const { Self::LEN }] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an array with a size of 0, found one with a size of const { Self::LEN } | note: type in trait --> $DIR/type-const-value-type-mismatch.rs:17:5 | +LL | pub trait Array { +... LL | fn arr() -> [u8; Self::LEN]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn() -> [u8; 0]` diff --git a/tests/ui/consts/issue-70942-trait-vs-impl-mismatch.stderr b/tests/ui/consts/issue-70942-trait-vs-impl-mismatch.stderr index 0393316f166ba..0e877df4ea553 100644 --- a/tests/ui/consts/issue-70942-trait-vs-impl-mismatch.stderr +++ b/tests/ui/consts/issue-70942-trait-vs-impl-mismatch.stderr @@ -1,12 +1,14 @@ error[E0326]: implemented const `VALUE` has an incompatible type for trait --> $DIR/issue-70942-trait-vs-impl-mismatch.rs:8:18 | +LL | impl Nat for Zero { LL | const VALUE: i32 = 0; | ^^^ expected `usize`, found `i32` | note: type in trait --> $DIR/issue-70942-trait-vs-impl-mismatch.rs:2:18 | +LL | trait Nat { LL | const VALUE: usize; | ^^^^^ diff --git a/tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.stderr b/tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.stderr index 18b06462de7b6..67622e28aca7b 100644 --- a/tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.stderr +++ b/tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.stderr @@ -1,6 +1,7 @@ error[E0326]: implemented const `CONST` has an incompatible type for trait --> $DIR/graceful-error-for-mistyped-assoc-const.rs:10:18 | +LL | impl issue_41549::Trait for S { LL | const CONST: () = (); | ^^ expected `u32`, found `()` diff --git a/tests/ui/delegation/target-expr-removal-defs-inside.stderr b/tests/ui/delegation/target-expr-removal-defs-inside.stderr index 6fde7fb8a7bdb..9f52c8c137d2a 100644 --- a/tests/ui/delegation/target-expr-removal-defs-inside.stderr +++ b/tests/ui/delegation/target-expr-removal-defs-inside.stderr @@ -183,6 +183,7 @@ LL | | } note: type in trait --> $DIR/target-expr-removal-defs-inside.rs:4:25 | +LL | pub trait Trait: Sized { LL | fn static_self() -> F { F } | ^ = note: expected signature `fn() -> F` @@ -257,6 +258,7 @@ LL | | } note: type in trait --> $DIR/target-expr-removal-defs-inside.rs:4:25 | +LL | pub trait Trait: Sized { LL | fn static_self() -> F { F } | ^ = note: expected signature `fn() -> F` @@ -335,6 +337,7 @@ LL | | } note: type in trait --> $DIR/target-expr-removal-defs-inside.rs:4:25 | +LL | pub trait Trait: Sized { LL | fn static_self() -> F { F } | ^ = note: expected signature `fn() -> F` diff --git a/tests/ui/delegation/unused-target-expr-in-glob-or-list.stderr b/tests/ui/delegation/unused-target-expr-in-glob-or-list.stderr index 330e536f81840..81b13c17a543a 100644 --- a/tests/ui/delegation/unused-target-expr-in-glob-or-list.stderr +++ b/tests/ui/delegation/unused-target-expr-in-glob-or-list.stderr @@ -164,7 +164,8 @@ error[E0053]: method `static_self` has an incompatible type for trait --> $DIR/unused-target-expr-in-glob-or-list.rs:107:37 | LL | macro_rules! delegation { -... +LL | () => { +LL | impl Trait for S { LL | reuse ::static_self { self.0 } | ^^^^^^^^^^^ expected `F`, found `()` ... @@ -174,6 +175,7 @@ LL | delegation!(); note: type in trait --> $DIR/unused-target-expr-in-glob-or-list.rs:4:25 | +LL | pub trait Trait: Sized { LL | fn static_self() -> F { F } | ^ = note: expected signature `fn() -> F` @@ -192,12 +194,14 @@ LL | () => { LL | reuse ::static_self { self.0 } | ^^^^^^^^^^^ expected `F`, found `()` ... +LL | impl Trait for S1 { LL | delegation2!(); | -------------- in this macro invocation | note: type in trait --> $DIR/unused-target-expr-in-glob-or-list.rs:4:25 | +LL | pub trait Trait: Sized { LL | fn static_self() -> F { F } | ^ = note: expected signature `fn() -> F` diff --git a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr index f844bdbc2cb21..3a507e5f218b4 100644 --- a/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr +++ b/tests/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr @@ -59,6 +59,8 @@ LL | impl Fn<()> for Foo { error[E0053]: method `call` has an incompatible type for trait --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:13:32 | +LL | impl Fn<()> for Foo { +... LL | extern "rust-call" fn call(self, args: ()) -> () {} | ^^^^ expected `&Foo`, found `Foo` | @@ -151,6 +153,8 @@ LL | impl FnOnce() for Foo1 { error[E0053]: method `call_mut` has an incompatible type for trait --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:36 | +LL | impl FnMut<()> for Bar { +... LL | extern "rust-call" fn call_mut(&self, args: ()) -> () {} | ^^^^^ types differ in mutability | diff --git a/tests/ui/fn/fn-traits-call-once-signature-15094.stderr b/tests/ui/fn/fn-traits-call-once-signature-15094.stderr index bb1d336e84842..1a892168c2c16 100644 --- a/tests/ui/fn/fn-traits-call-once-signature-15094.stderr +++ b/tests/ui/fn/fn-traits-call-once-signature-15094.stderr @@ -1,6 +1,8 @@ error[E0053]: method `call_once` has an incompatible type for trait --> $DIR/fn-traits-call-once-signature-15094.rs:13:5 | +LL | impl ops::FnOnce<(),> for Debuger { +LL | type Output = (); LL | fn call_once(self, _args: ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "rust-call" fn, found "Rust" fn | diff --git a/tests/ui/impl-trait/apit/impl-generic-mismatch-ab.stderr b/tests/ui/impl-trait/apit/impl-generic-mismatch-ab.stderr index 9db996cf9ce65..a7f67f04c4905 100644 --- a/tests/ui/impl-trait/apit/impl-generic-mismatch-ab.stderr +++ b/tests/ui/impl-trait/apit/impl-generic-mismatch-ab.stderr @@ -1,6 +1,7 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/impl-generic-mismatch-ab.rs:8:32 | +LL | impl Foo for () { LL | fn foo(&self, a: &impl Debug, b: &B) { } | - ^^^^^^^^^^^ expected type parameter `B`, found type parameter `impl Debug` | | @@ -9,6 +10,7 @@ LL | fn foo(&self, a: &impl Debug, b: &B) { } note: type in trait --> $DIR/impl-generic-mismatch-ab.rs:4:32 | +LL | trait Foo { LL | fn foo(&self, a: &A, b: &impl Debug); | ^^ = note: expected signature `fn(&(), &B, &impl Debug)` diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr index 39121c99798bf..5522fea6eb5e2 100644 --- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr +++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr @@ -16,6 +16,7 @@ LL | type Ty: IntoIterator; error[E0053]: method `method` has an incompatible type for trait --> $DIR/in-assoc-type-unconstrained.rs:22:24 | +LL | impl Trait for () { LL | type Ty = impl Sized; | ---------- the expected opaque type LL | @@ -25,6 +26,8 @@ LL | fn method() -> () {} note: type in trait --> $DIR/in-assoc-type-unconstrained.rs:17:24 | +LL | trait Trait { +LL | type Ty; LL | fn method() -> Self::Ty; | ^^^^^^^^ = note: expected signature `fn() -> <() as compare_method::Trait>::Ty` diff --git a/tests/ui/impl-trait/in-trait/deep-match.stderr b/tests/ui/impl-trait/in-trait/deep-match.stderr index 8ec30239ea8d7..1433664158b9f 100644 --- a/tests/ui/impl-trait/in-trait/deep-match.stderr +++ b/tests/ui/impl-trait/in-trait/deep-match.stderr @@ -1,12 +1,16 @@ error[E0053]: method `bar` has an incompatible return type for trait --> $DIR/deep-match.rs:8:17 | +LL | impl Foo for () { LL | fn bar() -> i32 { - | ^^^ - | | - | expected `Wrapper<_>`, found `i32` - | return type in trait + | ^^^ expected `Wrapper<_>`, found `i32` | +note: return type in trait + --> $DIR/deep-match.rs:4:17 + | +LL | trait Foo { +LL | fn bar() -> Wrapper; + | ^^^^^^^^^^^^^^^^^^^ = note: expected struct `Wrapper<_>` found type `i32` diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr index 97f5b2af862e0..8c3f4300532fe 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.lt.stderr @@ -1,6 +1,7 @@ error[E0053]: method `early` has an incompatible type for trait --> $DIR/method-signature-matches.rs:55:27 | +LL | impl Lifetimes for () { LL | fn early<'late, T>(_: &'late ()) {} | - ^^^^^^^^^ expected type parameter `T`, found `()` | | @@ -9,6 +10,7 @@ LL | fn early<'late, T>(_: &'late ()) {} note: type in trait --> $DIR/method-signature-matches.rs:50:28 | +LL | trait Lifetimes { LL | fn early<'early, T>(x: &'early T) -> impl Sized; | ^^^^^^^^^ = note: expected signature `fn(&'early T)` diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr index 588b453761003..dd6c906e64255 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch.stderr @@ -1,12 +1,14 @@ error[E0053]: method `owo` has an incompatible type for trait --> $DIR/method-signature-matches.rs:11:15 | +LL | impl Uwu for () { LL | fn owo(_: u8) {} | ^^ expected `()`, found `u8` | note: type in trait --> $DIR/method-signature-matches.rs:6:15 | +LL | trait Uwu { LL | fn owo(x: ()) -> impl Sized; | ^^ = note: expected signature `fn(())` diff --git a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr index b0530045bea9a..6a834ceed727e 100644 --- a/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr +++ b/tests/ui/impl-trait/in-trait/method-signature-matches.mismatch_async.stderr @@ -1,12 +1,14 @@ error[E0053]: method `owo` has an incompatible type for trait --> $DIR/method-signature-matches.rs:22:21 | +LL | impl AsyncUwu for () { LL | async fn owo(_: u8) {} | ^^ expected `()`, found `u8` | note: type in trait --> $DIR/method-signature-matches.rs:17:21 | +LL | trait AsyncUwu { LL | async fn owo(x: ()) {} | ^^ = note: expected signature `fn(()) -> _` diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.stderr index fbbe1ac40b9ef..ab739dae23d7f 100644 --- a/tests/ui/impl-trait/in-trait/specialization-broken.stderr +++ b/tests/ui/impl-trait/in-trait/specialization-broken.stderr @@ -10,6 +10,7 @@ LL | fn bar(&self) -> U { note: type in trait --> $DIR/specialization-broken.rs:8:22 | +LL | trait Foo { LL | fn bar(&self) -> impl Sized; | ^^^^^^^^^^ = note: expected signature `fn(&_) -> impl Sized` diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr index f921e5a452244..2c99ae95da74f 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -4,6 +4,8 @@ error[E0053]: method `eq` has an incompatible type for trait LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the found opaque type ... +LL | impl PartialEq<(Bar, i32)> for Bar { +LL | #[define_opaque(Foo)] LL | fn eq(&self, _other: &(Foo, i32)) -> bool { | ^^^^^^^^^^^ expected `a::Bar`, found opaque type | @@ -21,6 +23,7 @@ error[E0053]: method `eq` has an incompatible type for trait LL | type Foo = impl PartialEq<(Foo, i32)>; | -------------------------- the expected opaque type ... +LL | impl PartialEq<(Foo, i32)> for Bar { LL | fn eq(&self, _other: &(Bar, i32)) -> bool { | ^^^^^^^^^^^ expected opaque type, found `b::Bar` | diff --git a/tests/ui/impl-trait/trait_type.stderr b/tests/ui/impl-trait/trait_type.stderr index 18d914a96a291..ff07297eacff1 100644 --- a/tests/ui/impl-trait/trait_type.stderr +++ b/tests/ui/impl-trait/trait_type.stderr @@ -1,6 +1,7 @@ error[E0053]: method `fmt` has an incompatible type for trait --> $DIR/trait_type.rs:7:21 | +LL | impl std::fmt::Display for MyType { LL | fn fmt(&self, x: &str) -> () { } | ^^^^ types differ in mutability | diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index a0cdc8ee89382..86573088ed971 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -348,6 +348,7 @@ LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; error[E0053]: method `in_trait_impl_return` has an incompatible type for trait --> $DIR/where-allowed.rs:129:34 | +LL | impl DummyTrait for () { LL | type Out = impl Debug; | ---------- the expected opaque type ... @@ -357,6 +358,8 @@ LL | fn in_trait_impl_return() -> impl Debug { () } note: type in trait --> $DIR/where-allowed.rs:119:34 | +LL | trait DummyTrait { +... LL | fn in_trait_impl_return() -> Self::Out; | ^^^^^^^^^ = note: expected signature `fn() -> <() as DummyTrait>::Out` diff --git a/tests/ui/mir/inline-wrong-abi.stderr b/tests/ui/mir/inline-wrong-abi.stderr index e44899eb92a5c..cade8c22165f7 100644 --- a/tests/ui/mir/inline-wrong-abi.stderr +++ b/tests/ui/mir/inline-wrong-abi.stderr @@ -1,6 +1,7 @@ error[E0053]: method `call` has an incompatible type for trait --> $DIR/inline-wrong-abi.rs:7:5 | +LL | impl Fn<()> for Foo { LL | extern "C" fn call(&self, _: ()) -> T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "rust-call" fn, found "C" fn | diff --git a/tests/ui/mismatched_types/E0053.stderr b/tests/ui/mismatched_types/E0053.stderr index 32452af5ceda7..6cc5e0b128ee5 100644 --- a/tests/ui/mismatched_types/E0053.stderr +++ b/tests/ui/mismatched_types/E0053.stderr @@ -1,12 +1,14 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/E0053.rs:9:15 | +LL | impl Foo for Bar { LL | fn foo(x: i16) { } | ^^^ expected `u16`, found `i16` | note: type in trait --> $DIR/E0053.rs:2:15 | +LL | trait Foo { LL | fn foo(x: u16); | ^^^ = note: expected signature `fn(u16)` @@ -20,12 +22,16 @@ LL + fn foo(x: u16) { } error[E0053]: method `bar` has an incompatible type for trait --> $DIR/E0053.rs:11:12 | +LL | impl Foo for Bar { +... LL | fn bar(&mut self) { } | ^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/E0053.rs:3:12 | +LL | trait Foo { +LL | fn foo(x: u16); LL | fn bar(&self); | ^^^^^ = note: expected signature `fn(&Bar)` diff --git a/tests/ui/mismatched_types/issue-112036.stderr b/tests/ui/mismatched_types/issue-112036.stderr index fed6b11a7b292..3a4624d206c48 100644 --- a/tests/ui/mismatched_types/issue-112036.stderr +++ b/tests/ui/mismatched_types/issue-112036.stderr @@ -1,6 +1,7 @@ error[E0053]: method `drop` has an incompatible type for trait --> $DIR/issue-112036.rs:4:13 | +LL | impl Drop for Foo { LL | fn drop(self) {} | ^^^^ expected `&mut Foo`, found `Foo` | diff --git a/tests/ui/mismatched_types/issue-13033.stderr b/tests/ui/mismatched_types/issue-13033.stderr index f21d49eac7284..df83d10e29d9c 100644 --- a/tests/ui/mismatched_types/issue-13033.stderr +++ b/tests/ui/mismatched_types/issue-13033.stderr @@ -1,12 +1,14 @@ error[E0053]: method `bar` has an incompatible type for trait --> $DIR/issue-13033.rs:10:30 | +LL | impl Foo for Baz { LL | fn bar(&mut self, other: &dyn Foo) {} | ^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/issue-13033.rs:4:30 | +LL | trait Foo { LL | fn bar(&mut self, other: &mut dyn Foo); | ^^^^^^^^^^^^ = note: expected signature `fn(&mut Baz, &mut dyn Foo)` diff --git a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr index 4aabf2372e478..02df411583fce 100644 --- a/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr +++ b/tests/ui/mismatched_types/trait-impl-fn-incompatibility.stderr @@ -1,12 +1,14 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/trait-impl-fn-incompatibility.rs:9:15 | +LL | impl Foo for Bar { LL | fn foo(x: i16) { } | ^^^ expected `u16`, found `i16` | note: type in trait --> $DIR/trait-impl-fn-incompatibility.rs:2:15 | +LL | trait Foo { LL | fn foo(x: u16); | ^^^ = note: expected signature `fn(u16)` @@ -20,12 +22,16 @@ LL + fn foo(x: u16) { } error[E0053]: method `bar` has an incompatible type for trait --> $DIR/trait-impl-fn-incompatibility.rs:10:28 | +LL | impl Foo for Bar { +LL | fn foo(x: i16) { } LL | fn bar(&mut self, bar: &Bar) { } | ^^^^ types differ in mutability | note: type in trait --> $DIR/trait-impl-fn-incompatibility.rs:3:28 | +LL | trait Foo { +LL | fn foo(x: u16); LL | fn bar(&mut self, bar: &mut Bar); | ^^^^^^^^ = note: expected signature `fn(&mut Bar, &mut Bar)` diff --git a/tests/ui/mut/mismatch-trait-mut.e2015.stderr b/tests/ui/mut/mismatch-trait-mut.e2015.stderr index bc9d60e66bc33..0130f2d9833eb 100644 --- a/tests/ui/mut/mismatch-trait-mut.e2015.stderr +++ b/tests/ui/mut/mismatch-trait-mut.e2015.stderr @@ -1,12 +1,14 @@ error[E0053]: method `f` has an incompatible type for trait --> $DIR/mismatch-trait-mut.rs:30:18 | +LL | impl crate::A for X { LL | fn f(_x: &crate::bar::X) {} | ^^^^^^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/mismatch-trait-mut.rs:15:14 | +LL | pub trait A { LL | fn f(_x: &mut bar::X) {} | ^^^^^^^^^^^ = note: expected signature `fn(&mut X)` @@ -19,12 +21,16 @@ LL | fn f(_x: &mut crate::bar::X) {} error[E0053]: method `g` has an incompatible type for trait --> $DIR/mismatch-trait-mut.rs:34:22 | +LL | impl crate::A for X { +... LL | fn g<'a>(_x: &'a crate::bar::X) -> &'a () { &() } | ^^^^^^^^^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/mismatch-trait-mut.rs:17:18 | +LL | pub trait A { +... LL | fn g<'a>(_x: &'a mut bar::X) -> &'a () { &() } | ^^^^^^^^^^^^^^ = note: expected signature `fn(&'a mut X) -> &'a ()` @@ -37,12 +43,16 @@ LL | fn g<'a>(_x: &'a mut crate::bar::X) -> &'a () { &() } error[E0053]: method `f2` has an incompatible type for trait --> $DIR/mismatch-trait-mut.rs:38:19 | +LL | impl crate::A for X { +... LL | fn f2(_x: &mut crate::bar::X) {} | ^^^^^^^^^^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/mismatch-trait-mut.rs:19:15 | +LL | pub trait A { +... LL | fn f2(_x: &bar::X) {} | ^^^^^^^ = note: expected signature `fn(&X)` @@ -56,12 +66,16 @@ LL + fn f2(_x: &crate::bar::X) {} error[E0053]: method `g2` has an incompatible type for trait --> $DIR/mismatch-trait-mut.rs:42:23 | +LL | impl crate::A for X { +... LL | fn g2<'a>(_x: &'a mut crate::bar::X) -> &'a () { &() } | ^^^^^^^^^^^^^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/mismatch-trait-mut.rs:21:19 | +LL | pub trait A { +... LL | fn g2<'a>(_x: &'a bar::X) -> &'a () { &() } | ^^^^^^^^^^ = note: expected signature `fn(&'a X) -> &'a ()` diff --git a/tests/ui/mut/mismatch-trait-mut.e2018.stderr b/tests/ui/mut/mismatch-trait-mut.e2018.stderr index bc9d60e66bc33..0130f2d9833eb 100644 --- a/tests/ui/mut/mismatch-trait-mut.e2018.stderr +++ b/tests/ui/mut/mismatch-trait-mut.e2018.stderr @@ -1,12 +1,14 @@ error[E0053]: method `f` has an incompatible type for trait --> $DIR/mismatch-trait-mut.rs:30:18 | +LL | impl crate::A for X { LL | fn f(_x: &crate::bar::X) {} | ^^^^^^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/mismatch-trait-mut.rs:15:14 | +LL | pub trait A { LL | fn f(_x: &mut bar::X) {} | ^^^^^^^^^^^ = note: expected signature `fn(&mut X)` @@ -19,12 +21,16 @@ LL | fn f(_x: &mut crate::bar::X) {} error[E0053]: method `g` has an incompatible type for trait --> $DIR/mismatch-trait-mut.rs:34:22 | +LL | impl crate::A for X { +... LL | fn g<'a>(_x: &'a crate::bar::X) -> &'a () { &() } | ^^^^^^^^^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/mismatch-trait-mut.rs:17:18 | +LL | pub trait A { +... LL | fn g<'a>(_x: &'a mut bar::X) -> &'a () { &() } | ^^^^^^^^^^^^^^ = note: expected signature `fn(&'a mut X) -> &'a ()` @@ -37,12 +43,16 @@ LL | fn g<'a>(_x: &'a mut crate::bar::X) -> &'a () { &() } error[E0053]: method `f2` has an incompatible type for trait --> $DIR/mismatch-trait-mut.rs:38:19 | +LL | impl crate::A for X { +... LL | fn f2(_x: &mut crate::bar::X) {} | ^^^^^^^^^^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/mismatch-trait-mut.rs:19:15 | +LL | pub trait A { +... LL | fn f2(_x: &bar::X) {} | ^^^^^^^ = note: expected signature `fn(&X)` @@ -56,12 +66,16 @@ LL + fn f2(_x: &crate::bar::X) {} error[E0053]: method `g2` has an incompatible type for trait --> $DIR/mismatch-trait-mut.rs:42:23 | +LL | impl crate::A for X { +... LL | fn g2<'a>(_x: &'a mut crate::bar::X) -> &'a () { &() } | ^^^^^^^^^^^^^^^^^^^^^ types differ in mutability | note: type in trait --> $DIR/mismatch-trait-mut.rs:21:19 | +LL | pub trait A { +... LL | fn g2<'a>(_x: &'a bar::X) -> &'a () { &() } | ^^^^^^^^^^ = note: expected signature `fn(&'a X) -> &'a ()` diff --git a/tests/ui/pin-ergonomics/pinned-drop-check.stderr b/tests/ui/pin-ergonomics/pinned-drop-check.stderr index 6087d45dd2900..892413655a229 100644 --- a/tests/ui/pin-ergonomics/pinned-drop-check.stderr +++ b/tests/ui/pin-ergonomics/pinned-drop-check.stderr @@ -113,6 +113,7 @@ LL - #[pin_v2] error[E0053]: method `drop` has an incompatible type for trait --> $DIR/pinned-drop-check.rs:83:17 | +LL | impl Drop for Foo { LL | fn drop(&pin const self) {} | ^^^^^^^^^^^^^^^ expected `&mut drop_pin_const_wrong_type::Foo`, found `Pin<&drop_pin_const_wrong_type::Foo>` | @@ -127,6 +128,7 @@ LL + fn drop(&mut self) {} error[E0053]: method `drop` has an incompatible type for trait --> $DIR/pinned-drop-check.rs:87:17 | +LL | impl Drop for Bar { LL | fn drop(&pin const self) {} | ^^^^^^^^^^^^^^^ expected `&mut drop_pin_const_wrong_type::Bar`, found `Pin<&drop_pin_const_wrong_type::Bar>` | @@ -163,6 +165,7 @@ LL - #[pin_v2] error[E0053]: method `drop` has an incompatible type for trait --> $DIR/pinned-drop-check.rs:99:21 | +LL | impl Drop for Foo { LL | fn drop<'a>(&'a pin mut self) {} | ^^^^^^^^^^^^^^^^ expected `&mut drop_with_lifetime_wrong_type::Foo`, found `Pin<&mut Foo>` | @@ -177,6 +180,7 @@ LL + fn drop<'a>(&mut self) {} error[E0053]: method `drop` has an incompatible type for trait --> $DIR/pinned-drop-check.rs:104:21 | +LL | impl Drop for Bar { LL | fn drop<'a>(&'a pin mut self) {} | ^^^^^^^^^^^^^^^^ expected `&mut drop_with_lifetime_wrong_type::Bar`, found `Pin<&mut Bar>` | @@ -213,6 +217,7 @@ LL - #[pin_v2] error[E0053]: method `drop` has an incompatible type for trait --> $DIR/pinned-drop-check.rs:118:23 | +LL | impl Drop for Foo { LL | fn drop(self: Pin<&mut Self>) {} | ^^^^^^^^^^^^^^ expected `&mut drop_explicit_pin_wrong_type::Foo`, found `Pin<&mut Foo>` | @@ -227,6 +232,7 @@ LL + fn drop(&mut self) {} error[E0053]: method `drop` has an incompatible type for trait --> $DIR/pinned-drop-check.rs:123:23 | +LL | impl Drop for Bar { LL | fn drop(self: Pin<&mut Self>) {} | ^^^^^^^^^^^^^^ expected `&mut drop_explicit_pin_wrong_type::Bar`, found `Pin<&mut Bar>` | @@ -241,6 +247,7 @@ LL + fn drop(&mut self) {} error[E0053]: method `pin_drop` has an incompatible type for trait --> $DIR/pinned-drop-check.rs:135:21 | +LL | impl Drop for Foo { LL | fn pin_drop(&mut self) {} | ^^^^^^^^^ expected `Pin<&mut pin_drop_wrong_type::Foo>`, found `&mut pin_drop_wrong_type::Foo` | @@ -255,6 +262,7 @@ LL + fn pin_drop(self: Pin<&mut pin_drop_wrong_type::Foo>) {} error[E0053]: method `pin_drop` has an incompatible type for trait --> $DIR/pinned-drop-check.rs:139:21 | +LL | impl Drop for Bar { LL | fn pin_drop(&mut self) {} | ^^^^^^^^^ expected `Pin<&mut pin_drop_wrong_type::Bar>`, found `&mut pin_drop_wrong_type::Bar` | diff --git a/tests/ui/splat/splat-invalid-trait-impl.stderr b/tests/ui/splat/splat-invalid-trait-impl.stderr index df414a5e63062..3aafd5e0d5575 100644 --- a/tests/ui/splat/splat-invalid-trait-impl.stderr +++ b/tests/ui/splat/splat-invalid-trait-impl.stderr @@ -1,12 +1,14 @@ error[E0053]: method `method` has an incompatible type for trait --> $DIR/splat-invalid-trait-impl.rs:14:33 | +LL | impl FooTrait for Foo { LL | fn method(#[rustc_splat] _: (u32, f32)) {} | ^^^^^^^^^^ expected `i8`, found `f32` | note: type in trait --> $DIR/splat-invalid-trait-impl.rs:6:33 | +LL | trait FooTrait { LL | fn method(#[rustc_splat] _: (u32, i8)); | ^^^^^^^^^ = note: expected signature `fn(#[rustc_splat] (_, i8))` @@ -20,12 +22,14 @@ LL + fn method(#[rustc_splat] _: (u32, i8)) {} error[E0053]: method `method` has an incompatible type for trait --> $DIR/splat-invalid-trait-impl.rs:19:33 | +LL | impl FooTrait for Foo1 { LL | fn method(#[rustc_splat] _: (f32, i8)) {} | ^^^^^^^^^ expected `u32`, found `f32` | note: type in trait --> $DIR/splat-invalid-trait-impl.rs:6:33 | +LL | trait FooTrait { LL | fn method(#[rustc_splat] _: (u32, i8)); | ^^^^^^^^^ = note: expected signature `fn(#[rustc_splat] (u32, _))` @@ -39,12 +43,14 @@ LL + fn method(#[rustc_splat] _: (u32, i8)) {} error[E0053]: method `method` has an incompatible type for trait --> $DIR/splat-invalid-trait-impl.rs:24:33 | +LL | impl FooTrait for Foo2 { LL | fn method(#[rustc_splat] _: (f32, f64)) {} | ^^^^^^^^^^ expected `u32`, found `f32` | note: type in trait --> $DIR/splat-invalid-trait-impl.rs:6:33 | +LL | trait FooTrait { LL | fn method(#[rustc_splat] _: (u32, i8)); | ^^^^^^^^^ = note: expected signature `fn(#[rustc_splat] (u32, i8))` diff --git a/tests/ui/splat/splat-invalid.stderr b/tests/ui/splat/splat-invalid.stderr index 8681084a3c594..5ef430046ab10 100644 --- a/tests/ui/splat/splat-invalid.stderr +++ b/tests/ui/splat/splat-invalid.stderr @@ -182,12 +182,14 @@ LL | #[rustc_splat] error[E0053]: method `has_splat` has an incompatible type for trait --> $DIR/splat-invalid.rs:59:5 | +LL | impl FooTrait for Foo { LL | fn has_splat(_: ()) {} | ^^^^^^^^^^^^^^^^^^^ expected fn with arg 0 splatted, found fn with no splatted arg | note: type in trait --> $DIR/splat-invalid.rs:51:5 | +LL | trait FooTrait { LL | fn has_splat(#[rustc_splat] _: ()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn(#[rustc_splat] ())` @@ -196,12 +198,16 @@ LL | fn has_splat(#[rustc_splat] _: ()); error[E0053]: method `no_splat` has an incompatible type for trait --> $DIR/splat-invalid.rs:61:5 | +LL | impl FooTrait for Foo { +... LL | fn no_splat(#[rustc_splat] _: (u32, f64)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn with no splatted arg, found fn with arg 0 splatted | note: type in trait --> $DIR/splat-invalid.rs:53:5 | +LL | trait FooTrait { +... LL | fn no_splat(_: (u32, f64)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn((_, _))` diff --git a/tests/ui/splat/splat-non-tuple.stderr b/tests/ui/splat/splat-non-tuple.stderr index b92c257b9b021..21129c92ce6ee 100644 --- a/tests/ui/splat/splat-non-tuple.stderr +++ b/tests/ui/splat/splat-non-tuple.stderr @@ -1,12 +1,14 @@ error[E0053]: method `tuple_1` has an incompatible type for trait --> $DIR/splat-non-tuple.rs:39:5 | +LL | impl FooTrait for Foo { LL | fn tuple_1(_: (u32,)) {} | ^^^^^^^^^^^^^^^^^^^^^ expected fn with arg 0 splatted, found fn with no splatted arg | note: type in trait --> $DIR/splat-non-tuple.rs:17:5 | +LL | trait FooTrait { LL | fn tuple_1(#[rustc_splat] _: (u32,)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn(#[rustc_splat] (_,))` diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr index b6710e5ab28a6..4f8966aa2e6b7 100644 --- a/tests/ui/target-feature/invalid-attribute.stderr +++ b/tests/ui/target-feature/invalid-attribute.stderr @@ -189,12 +189,15 @@ LL | fn foo() {} error[E0053]: method `foo` has an incompatible type for trait --> $DIR/invalid-attribute.rs:92:5 | +LL | impl Quux for Foo { +... LL | fn foo() {} | ^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait --> $DIR/invalid-attribute.rs:84:5 | +LL | trait Quux { LL | fn foo(); | ^^^^^^^^^ = note: expected signature `fn()` diff --git a/tests/ui/traits/const-traits/eval-bad-signature.stderr b/tests/ui/traits/const-traits/eval-bad-signature.stderr index db5f434ee0e98..1230515c79f5c 100644 --- a/tests/ui/traits/const-traits/eval-bad-signature.stderr +++ b/tests/ui/traits/const-traits/eval-bad-signature.stderr @@ -1,12 +1,14 @@ error[E0053]: method `value` has an incompatible type for trait --> $DIR/eval-bad-signature.rs:16:19 | +LL | const impl Value for FortyTwo { LL | fn value() -> i64 { | ^^^ expected `u32`, found `i64` | note: type in trait --> $DIR/eval-bad-signature.rs:6:19 | +LL | const trait Value { LL | fn value() -> u32; | ^^^ = note: expected signature `fn() -> u32` diff --git a/tests/ui/traits/error-reporting/incompatible-method-multiline.stderr b/tests/ui/traits/error-reporting/incompatible-method-multiline.stderr index 4f797dedfa846..ee9a29aa84fd6 100644 --- a/tests/ui/traits/error-reporting/incompatible-method-multiline.stderr +++ b/tests/ui/traits/error-reporting/incompatible-method-multiline.stderr @@ -1,6 +1,8 @@ error[E0053]: method `next` has an incompatible type for trait --> $DIR/incompatible-method-multiline.rs:8:27 | +LL | impl Iterator for S { +LL | type Item = i32; LL | fn next(&mut self) -> Result { Ok(7) } | ^^^^^^^^^^^^^^^^ expected `Option`, found `Result` | diff --git a/tests/ui/traits/impl-method-mismatch.stderr b/tests/ui/traits/impl-method-mismatch.stderr index ca8b35e06c78f..9675edd3d84cb 100644 --- a/tests/ui/traits/impl-method-mismatch.stderr +++ b/tests/ui/traits/impl-method-mismatch.stderr @@ -1,12 +1,15 @@ error[E0053]: method `jumbo` has an incompatible type for trait --> $DIR/impl-method-mismatch.rs:9:5 | +LL | impl Mumbo for usize { +LL | // Cannot have a larger effect than the trait: LL | unsafe fn jumbo(&self, x: &usize) { *self + *x; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait --> $DIR/impl-method-mismatch.rs:4:5 | +LL | trait Mumbo { LL | fn jumbo(&self, x: &usize) -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn(&_, &_) -> usize` diff --git a/tests/ui/traits/issue-35869.stderr b/tests/ui/traits/issue-35869.stderr index 98cbd4650007b..17adad92611cc 100644 --- a/tests/ui/traits/issue-35869.stderr +++ b/tests/ui/traits/issue-35869.stderr @@ -1,12 +1,14 @@ error[E0053]: method `foo` has an incompatible type for trait --> $DIR/issue-35869.rs:11:15 | +LL | impl Foo for Bar { LL | fn foo(_: fn(u16) -> ()) {} | ^^^^^^^^^^^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:2:15 | +LL | trait Foo { LL | fn foo(_: fn(u8) -> ()); | ^^^^^^^^^^^^ = note: expected signature `fn(fn(u8))` @@ -20,12 +22,16 @@ LL + fn foo(_: fn(u8)) {} error[E0053]: method `bar` has an incompatible type for trait --> $DIR/issue-35869.rs:13:15 | +LL | impl Foo for Bar { +... LL | fn bar(_: Option) {} | ^^^^^^^^^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:3:15 | +LL | trait Foo { +LL | fn foo(_: fn(u8) -> ()); LL | fn bar(_: Option); | ^^^^^^^^^^ = note: expected signature `fn(Option)` @@ -39,12 +45,16 @@ LL + fn bar(_: std::option::Option) {} error[E0053]: method `baz` has an incompatible type for trait --> $DIR/issue-35869.rs:15:15 | +LL | impl Foo for Bar { +... LL | fn baz(_: (u16, u16)) {} | ^^^^^^^^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:4:15 | +LL | trait Foo { +... LL | fn baz(_: (u8, u16)); | ^^^^^^^^^ = note: expected signature `fn((u8, _))` @@ -58,12 +68,16 @@ LL + fn baz(_: (u8, u16)) {} error[E0053]: method `qux` has an incompatible type for trait --> $DIR/issue-35869.rs:17:17 | +LL | impl Foo for Bar { +... LL | fn qux() -> u16 { 5u16 } | ^^^ expected `u8`, found `u16` | note: type in trait --> $DIR/issue-35869.rs:5:17 | +LL | trait Foo { +... LL | fn qux() -> u8; | ^^ = note: expected signature `fn() -> u8` diff --git a/tests/ui/traits/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr index d119274352f81..6d520e5b958e5 100644 --- a/tests/ui/traits/wrong-mul-method-signature.stderr +++ b/tests/ui/traits/wrong-mul-method-signature.stderr @@ -1,6 +1,8 @@ error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:16:21 | +LL | impl Mul for Vec1 { +... LL | fn mul(self, s: &f64) -> Vec1 { | ^^^^ expected `f64`, found `&f64` | @@ -17,6 +19,8 @@ LL + fn mul(self, s: f64) -> Vec1 { error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:33:21 | +LL | impl Mul for Vec2 { +... LL | fn mul(self, s: f64) -> Vec2 { | ^^^ expected `Vec2`, found `f64` | @@ -33,6 +37,8 @@ LL + fn mul(self, s: crate::Vec2) -> Vec2 { error[E0053]: method `mul` has an incompatible type for trait --> $DIR/wrong-mul-method-signature.rs:52:29 | +LL | impl Mul for Vec3 { +... LL | fn mul(self, s: f64) -> f64 { | ^^^ expected `i32`, found `f64` | diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr index 48fe7ba275fce..ca55fc350fb3d 100644 --- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr +++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr @@ -3,13 +3,15 @@ error[E0053]: method `dont_define_this` has an incompatible type for trait | LL | type MyPrivate = impl Sized; | ---------- the found opaque type -... +LL | impl Trait for u32 { +LL | #[define_opaque(MyPrivate)] LL | fn dont_define_this(private: MyPrivate) { | ^^^^^^^^^ expected `Private`, found opaque type | note: type in trait --> $DIR/unnameable_type.rs:10:39 | +LL | pub trait Trait { LL | fn dont_define_this(_private: Private) {} | ^^^^^^^ = note: expected signature `fn(Private)` diff --git a/tests/ui/typeck/mismatched-map-under-self.stderr b/tests/ui/typeck/mismatched-map-under-self.stderr index 541de25749e38..8e5bae258f976 100644 --- a/tests/ui/typeck/mismatched-map-under-self.stderr +++ b/tests/ui/typeck/mismatched-map-under-self.stderr @@ -1,12 +1,16 @@ error[E0053]: method `values` has an incompatible type for trait --> $DIR/mismatched-map-under-self.rs:10:15 | +LL | impl Insertable for Option { +... LL | fn values(self) -> Self::Values { | ^^^^ expected `&Option`, found `Option` | note: type in trait --> $DIR/mismatched-map-under-self.rs:4:15 | +LL | pub trait Insertable { +... LL | fn values(&self) -> Self::Values; | ^^^^^ = note: expected signature `fn(&Option<_>)` diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr index 7b5f7cd9f7033..e0d6d88fca075 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -1,12 +1,16 @@ error[E0053]: method `dummy2` has an incompatible type for trait --> $DIR/ufcs-explicit-self-bad.rs:37:21 | +LL | impl<'a, T> SomeTrait for &'a Bar { +LL | fn dummy1(self: &&'a Bar) { } LL | fn dummy2(self: &Bar) {} | ^^^^^^^ expected `&'a Bar`, found `Bar` | note: type in trait --> $DIR/ufcs-explicit-self-bad.rs:31:15 | +LL | trait SomeTrait { +LL | fn dummy1(&self); LL | fn dummy2(&self); | ^^^^^ = note: expected signature `fn(&&'a Bar<_>)` diff --git a/tests/ui/unsafe/unsafe-trait-impl.stderr b/tests/ui/unsafe/unsafe-trait-impl.stderr index 8febbb736634d..250d1f1dcbcf7 100644 --- a/tests/ui/unsafe/unsafe-trait-impl.stderr +++ b/tests/ui/unsafe/unsafe-trait-impl.stderr @@ -1,12 +1,14 @@ error[E0053]: method `len` has an incompatible type for trait --> $DIR/unsafe-trait-impl.rs:10:5 | +LL | impl Foo for u32 { LL | fn len(&self) -> u32 { *self } | ^^^^^^^^^^^^^^^^^^^^ expected unsafe fn, found safe fn | note: type in trait --> $DIR/unsafe-trait-impl.rs:6:5 | +LL | trait Foo { LL | unsafe fn len(&self) -> u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `unsafe fn(&_) -> _` From 7518566f4ddfc60f48c4a48865b59a100a548e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 5 Oct 2026 21:58:01 +0000 Subject: [PATCH 5/8] Streamline output by moving span label of type parameter default to "type in trait" note ``` error[E0053]: method `foo` has an incompatible type for trait --> $DIR/default-type-parameter.rs:8:17 | LL | impl Trait for S { LL | fn foo() -> u32 { 0 } | ^^^ expected `()`, found `u32` | note: type in trait --> $DIR/default-type-parameter.rs:2:17 | LL | trait Trait { | ------ expected to match the default of type parameter `T` LL | fn foo() -> T; | ^ = note: expected signature `fn() -> ()` found signature `fn() -> u32` help: change the output type to match the trait | LL - fn foo() -> u32 { 0 } LL + fn foo() -> () { 0 } | ``` --- .../src/check/compare_impl_item.rs | 48 +++++++++++-------- .../default-type-parameter.stderr | 12 +---- .../traits/wrong-mul-method-signature.stderr | 4 -- 3 files changed, 30 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 6c371a9cd1788..4a3f71cd311da 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1084,24 +1084,9 @@ fn report_trait_method_mismatch<'tcx>( } cause.span = impl_err_span; - infcx.err_ctxt().note_type_err( - &mut diag, - &cause, - trait_err_span.map(|sp| { - let mut span: MultiSpan = sp.into(); - span.push_span_context(tcx.def_span(trait_m.container_id(tcx)).shrink_to_lo()); - span.push_span_context(tcx.def_span(trait_m.def_id).shrink_to_lo()); - (span, Cow::from("type in trait"), false) - }), - Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound { - expected: ty::Binder::dummy(trait_sig), - found: ty::Binder::dummy(impl_sig), - }))), - terr, - false, - None, - ); + let mut labels = vec![]; + let mut context = vec![]; if let TypeError::ArgumentSorts(_, i) = &terr && let Some(ty) = tcx.fn_sig(trait_m.def_id).skip_binder().inputs_and_output().skip_binder().get(*i) @@ -1112,8 +1097,7 @@ fn report_trait_method_mismatch<'tcx>( && let param = generics.type_param(*param, tcx) && let GenericParamDefKind::Type { has_default: true, .. } = param.kind { - let mut span: MultiSpan = tcx.def_span(param.def_id).into(); - span.push_span_context(tcx.def_span(trait_m.container_id(tcx)).shrink_to_lo()); + context.push(tcx.def_span(trait_m.container_id(tcx)).shrink_to_lo()); let param_name = param.name; let msg = if let Some(ty) = trait_sig.inputs_and_output.get(*i) @@ -1129,9 +1113,33 @@ fn report_trait_method_mismatch<'tcx>( } else { format!("expected to match type parameter `{param_name}`") }; - diag.span_note(span, msg); + labels.push((tcx.def_span(param.def_id), msg)); } + infcx.err_ctxt().note_type_err( + &mut diag, + &cause, + trait_err_span.map(|sp| { + let mut span: MultiSpan = sp.into(); + span.push_span_context(tcx.def_span(trait_m.container_id(tcx)).shrink_to_lo()); + span.push_span_context(tcx.def_span(trait_m.def_id).shrink_to_lo()); + for (sp, label) in labels { + span.push_span_label(sp, label); + } + for sp in context { + span.push_span_context(sp); + } + (span, Cow::from("type in trait"), false) + }), + Some(param_env.and(infer::ValuePairs::PolySigs(ExpectedFound { + expected: ty::Binder::dummy(trait_sig), + found: ty::Binder::dummy(impl_sig), + }))), + terr, + false, + None, + ); + diag.emit_err() } diff --git a/tests/ui/compare-method/default-type-parameter.stderr b/tests/ui/compare-method/default-type-parameter.stderr index 6b66aaa804ed0..83517ab76729e 100644 --- a/tests/ui/compare-method/default-type-parameter.stderr +++ b/tests/ui/compare-method/default-type-parameter.stderr @@ -9,15 +9,11 @@ note: type in trait --> $DIR/default-type-parameter.rs:2:17 | LL | trait Trait { + | ------ expected to match the default of type parameter `T` LL | fn foo() -> T; | ^ = note: expected signature `fn() -> ()` found signature `fn() -> u32` -note: expected to match the default of type parameter `T` - --> $DIR/default-type-parameter.rs:1:13 - | -LL | trait Trait { - | ^^^^^^ help: change the output type to match the trait | LL - fn foo() -> u32 { 0 } @@ -35,15 +31,11 @@ note: type in trait --> $DIR/default-type-parameter.rs:2:17 | LL | trait Trait { + | ------ expected to match type parameter `T` LL | fn foo() -> T; | ^ = note: expected signature `fn() -> i32` found signature `fn() -> u32` -note: expected to match type parameter `T` - --> $DIR/default-type-parameter.rs:1:13 - | -LL | trait Trait { - | ^^^^^^ help: change the output type to match the trait | LL - fn foo() -> u32 { 0 } diff --git a/tests/ui/traits/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr index 6d520e5b958e5..ea07a07e09de9 100644 --- a/tests/ui/traits/wrong-mul-method-signature.stderr +++ b/tests/ui/traits/wrong-mul-method-signature.stderr @@ -8,8 +8,6 @@ LL | fn mul(self, s: &f64) -> Vec1 { | = note: expected signature `fn(Vec1, _) -> Vec1` found signature `fn(Vec1, &_) -> Vec1` -note: expected to match type parameter `Rhs` - --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the parameter type to match the trait | LL - fn mul(self, s: &f64) -> Vec1 { @@ -26,8 +24,6 @@ LL | fn mul(self, s: f64) -> Vec2 { | = note: expected signature `fn(Vec2, Vec2) -> f64` found signature `fn(Vec2, f64) -> Vec2` -note: expected to match the `Self` default of type parameter `Rhs` - --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the parameter type to match the trait | LL - fn mul(self, s: f64) -> Vec2 { From b6b1d7aa55fe6914bb77b64ef289a2833f8b2c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 5 Oct 2026 23:20:36 +0000 Subject: [PATCH 6/8] fix test --- tests/ui/compare-method/default-type-parameter.rs | 1 + tests/ui/compare-method/default-type-parameter.stderr | 8 ++++---- .../feature-gate-effective-target-features.default.stderr | 3 +++ .../feature-gate-effective-target-features.feature.stderr | 3 +++ .../ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr | 3 +++ 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/ui/compare-method/default-type-parameter.rs b/tests/ui/compare-method/default-type-parameter.rs index 92746fb4ebcad..612e763f23737 100644 --- a/tests/ui/compare-method/default-type-parameter.rs +++ b/tests/ui/compare-method/default-type-parameter.rs @@ -1,3 +1,4 @@ +// Regression test for https://github.com/rust-lang/rust/issues/67991 trait Trait { fn foo() -> T; } diff --git a/tests/ui/compare-method/default-type-parameter.stderr b/tests/ui/compare-method/default-type-parameter.stderr index 83517ab76729e..a000922b6307d 100644 --- a/tests/ui/compare-method/default-type-parameter.stderr +++ b/tests/ui/compare-method/default-type-parameter.stderr @@ -1,12 +1,12 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/default-type-parameter.rs:8:17 + --> $DIR/default-type-parameter.rs:9:17 | LL | impl Trait for S { LL | fn foo() -> u32 { 0 } | ^^^ expected `()`, found `u32` | note: type in trait - --> $DIR/default-type-parameter.rs:2:17 + --> $DIR/default-type-parameter.rs:3:17 | LL | trait Trait { | ------ expected to match the default of type parameter `T` @@ -21,14 +21,14 @@ LL + fn foo() -> () { 0 } | error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/default-type-parameter.rs:11:17 + --> $DIR/default-type-parameter.rs:12:17 | LL | impl Trait for () { LL | fn foo() -> u32 { 0 } | ^^^ expected `i32`, found `u32` | note: type in trait - --> $DIR/default-type-parameter.rs:2:17 + --> $DIR/default-type-parameter.rs:3:17 | LL | trait Trait { | ------ expected to match type parameter `T` diff --git a/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr b/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr index 1bad811ada64a..7b8ba0e660ece 100644 --- a/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr +++ b/tests/ui/feature-gates/feature-gate-effective-target-features.default.stderr @@ -20,12 +20,15 @@ LL | fn foo(&self) {} error[E0053]: method `foo` has an incompatible type for trait --> $DIR/feature-gate-effective-target-features.rs:24:5 | +LL | impl Foo for Bar2 { +... LL | fn foo(&self) {} | ^^^^^^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait --> $DIR/feature-gate-effective-target-features.rs:8:5 | +LL | trait Foo { LL | fn foo(&self); | ^^^^^^^^^^^^^^ = note: expected signature `fn(&Bar2)` diff --git a/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr b/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr index 06090cbbef6fe..d1939e35d4aba 100644 --- a/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr +++ b/tests/ui/feature-gates/feature-gate-effective-target-features.feature.stderr @@ -23,12 +23,15 @@ LL | fn foo(&self) {} error[E0053]: method `foo` has an incompatible type for trait --> $DIR/feature-gate-effective-target-features.rs:24:5 | +LL | impl Foo for Bar2 { +... LL | fn foo(&self) {} | ^^^^^^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait --> $DIR/feature-gate-effective-target-features.rs:8:5 | +LL | trait Foo { LL | fn foo(&self); | ^^^^^^^^^^^^^^ = note: expected signature `fn(&Bar2)` diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr index 39b0e5ea18f7d..86634e54aa3e1 100644 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr +++ b/tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr @@ -10,12 +10,15 @@ LL | fn foo(&self) {} error[E0053]: method `foo` has an incompatible type for trait --> $DIR/trait-impl.rs:13:5 | +LL | impl Foo for Bar { +... LL | fn foo(&self) {} | ^^^^^^^^^^^^^ expected safe fn, found unsafe fn | note: type in trait --> $DIR/trait-impl.rs:4:5 | +LL | trait Foo { LL | fn foo(&self); | ^^^^^^^^^^^^^^ = note: expected signature `fn(&Bar)` From b9b3dbac1edf71a211506bbd161f45e5ec62347c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 20 Oct 2026 20:31:57 +0000 Subject: [PATCH 7/8] Fix rebase --- compiler/rustc_hir_analysis/src/check/compare_impl_item.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 4a3f71cd311da..711c5e366404e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -2238,7 +2238,8 @@ fn compare_const_generic_param_types<'tcx>( infcx.err_ctxt().note_type_err( &mut diag, &cause, - param_trait_ty_span.map(|span| (span, Cow::from("type in trait"), false)), + param_trait_ty_span + .map(|span| (span.into(), Cow::from("type in trait"), false)), Some(param_env.and(infer::ValuePairs::Terms(ExpectedFound { expected: trait_ty.into(), found: impl_ty.into(), From 2885a3299c964311f670f4628815859d4c45a5b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Oct 2026 16:54:26 +0000 Subject: [PATCH 8/8] Excercise all new diagnostic changes in existing tests --- .../async-example-desugared-boxed-in-trait.rs | 3 +- ...nc-example-desugared-boxed-in-trait.stderr | 9 +- .../compare-method/default-type-parameter.rs | 14 ++- .../default-type-parameter.stderr | 86 ++++++++++++++++--- 4 files changed, 92 insertions(+), 20 deletions(-) diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs index 8d3dbaf6ca1f1..217eadeb26229 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.rs @@ -4,7 +4,8 @@ use std::future::Future; use std::pin::Pin; trait MyTrait { - fn foo(&self) -> Pin + '_>>; + fn foo(&self) + -> Pin + '_>>; } impl MyTrait for i32 { diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index 6fcba3870cb0c..387626907f1f5 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -1,16 +1,17 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:11:28 + --> $DIR/async-example-desugared-boxed-in-trait.rs:12:28 | LL | impl MyTrait for i32 { LL | async fn foo(&self) -> i32 { | ^^^ expected `Pin>>`, found future | note: type in trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:7:22 + --> $DIR/async-example-desugared-boxed-in-trait.rs:8:8 | LL | trait MyTrait { -LL | fn foo(&self) -> Pin + '_>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo(&self) +LL | -> Pin + '_>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected signature `fn(&_) -> Pin>>` found signature `fn(&_) -> impl Future` diff --git a/tests/ui/compare-method/default-type-parameter.rs b/tests/ui/compare-method/default-type-parameter.rs index 612e763f23737..bdf65d1479239 100644 --- a/tests/ui/compare-method/default-type-parameter.rs +++ b/tests/ui/compare-method/default-type-parameter.rs @@ -1,15 +1,25 @@ // Regression test for https://github.com/rust-lang/rust/issues/67991 -trait Trait { - fn foo() -> T; +// The weird indentation is to excercise the span context that shows the enclosing items in the +// diagnostics being emitted. +trait Trait< + T = (), + K = Self, +> { + fn foo() + -> T; + fn bar() + -> K; } struct S; impl Trait for S { fn foo() -> u32 { 0 } //~ ERROR + fn bar() -> u32 { 0 } //~ ERROR } impl Trait for () { fn foo() -> u32 { 0 } //~ ERROR + fn bar() -> u32 { 0 } //~ ERROR } fn main() {} diff --git a/tests/ui/compare-method/default-type-parameter.stderr b/tests/ui/compare-method/default-type-parameter.stderr index a000922b6307d..e3109566d7fac 100644 --- a/tests/ui/compare-method/default-type-parameter.stderr +++ b/tests/ui/compare-method/default-type-parameter.stderr @@ -1,17 +1,20 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/default-type-parameter.rs:9:17 + --> $DIR/default-type-parameter.rs:17:17 | LL | impl Trait for S { LL | fn foo() -> u32 { 0 } | ^^^ expected `()`, found `u32` | note: type in trait - --> $DIR/default-type-parameter.rs:3:17 + --> $DIR/default-type-parameter.rs:9:8 | -LL | trait Trait { - | ------ expected to match the default of type parameter `T` -LL | fn foo() -> T; - | ^ +LL | trait Trait< +LL | T = (), + | ------ expected to match the default of type parameter `T` +... +LL | fn foo() +LL | -> T; + | ^ = note: expected signature `fn() -> ()` found signature `fn() -> u32` help: change the output type to match the trait @@ -20,20 +23,50 @@ LL - fn foo() -> u32 { 0 } LL + fn foo() -> () { 0 } | +error[E0053]: method `bar` has an incompatible type for trait + --> $DIR/default-type-parameter.rs:18:17 + | +LL | impl Trait for S { +LL | fn foo() -> u32 { 0 } +LL | fn bar() -> u32 { 0 } + | ^^^ expected `S`, found `u32` + | +note: type in trait + --> $DIR/default-type-parameter.rs:11:8 + | +LL | trait Trait< +LL | T = (), +LL | K = Self, + | -------- expected to match the `Self` default of type parameter `K` +... +LL | fn bar() +LL | -> K; + | ^ + = note: expected signature `fn() -> S` + found signature `fn() -> u32` +help: change the output type to match the trait + | +LL - fn bar() -> u32 { 0 } +LL + fn bar() -> S { 0 } + | + error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/default-type-parameter.rs:12:17 + --> $DIR/default-type-parameter.rs:21:17 | LL | impl Trait for () { LL | fn foo() -> u32 { 0 } | ^^^ expected `i32`, found `u32` | note: type in trait - --> $DIR/default-type-parameter.rs:3:17 + --> $DIR/default-type-parameter.rs:9:8 | -LL | trait Trait { - | ------ expected to match type parameter `T` -LL | fn foo() -> T; - | ^ +LL | trait Trait< +LL | T = (), + | ------ expected to match type parameter `T` +... +LL | fn foo() +LL | -> T; + | ^ = note: expected signature `fn() -> i32` found signature `fn() -> u32` help: change the output type to match the trait @@ -42,6 +75,33 @@ LL - fn foo() -> u32 { 0 } LL + fn foo() -> i32 { 0 } | -error: aborting due to 2 previous errors +error[E0053]: method `bar` has an incompatible type for trait + --> $DIR/default-type-parameter.rs:22:17 + | +LL | impl Trait for () { +LL | fn foo() -> u32 { 0 } +LL | fn bar() -> u32 { 0 } + | ^^^ expected `()`, found `u32` + | +note: type in trait + --> $DIR/default-type-parameter.rs:11:8 + | +LL | trait Trait< +LL | T = (), +LL | K = Self, + | -------- expected to match the `Self` default of type parameter `K` +... +LL | fn bar() +LL | -> K; + | ^ + = note: expected signature `fn() -> ()` + found signature `fn() -> u32` +help: change the output type to match the trait + | +LL - fn bar() -> u32 { 0 } +LL + fn bar() -> () { 0 } + | + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0053`.