From 95d5ecf3ab075e82503f4fb40893ac5899442653 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 1 Apr 2026 09:21:45 +0800 Subject: [PATCH 1/2] Fix associated bound suggestion span issue --- .../error_reporting/infer/note_and_explain.rs | 8 +++- .../associated-error-bound-issue-145586.fixed | 38 +++++++++++++++++++ .../associated-error-bound-issue-145586.rs | 38 +++++++++++++++++++ ...associated-error-bound-issue-145586.stderr | 22 +++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 tests/ui/trait-bounds/associated-error-bound-issue-145586.fixed create mode 100644 tests/ui/trait-bounds/associated-error-bound-issue-145586.rs create mode 100644 tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index 7f53fdbc2c9f..6bfd9c78df5d 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -105,7 +105,13 @@ pub fn note_and_explain_type_err( if !sp.contains(p_span) { diag.span_label(p_span, format!("{expected}this type parameter")); } - let parent = p_def_id.as_local().and_then(|id| { + let param_def_id = match *proj.self_ty().kind() { + ty::Param(param) => { + tcx.generics_of(body_owner_def_id).type_param(param, tcx).def_id + } + _ => p_def_id, + }; + let parent = param_def_id.as_local().and_then(|id| { let local_id = tcx.local_def_id_to_hir_id(id); let generics = tcx.parent_hir_node(local_id).generics()?; Some((id, generics)) diff --git a/tests/ui/trait-bounds/associated-error-bound-issue-145586.fixed b/tests/ui/trait-bounds/associated-error-bound-issue-145586.fixed new file mode 100644 index 000000000000..d5754132e028 --- /dev/null +++ b/tests/ui/trait-bounds/associated-error-bound-issue-145586.fixed @@ -0,0 +1,38 @@ +//@ run-rustfix + +#![allow(dead_code)] + +use std::marker::PhantomData; + +trait Visitor<'de> { + type Value; +} + +trait Deserializer<'de> { + type Error; + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>; +} + +struct Wrapper<'de, T, E>(Result, PhantomData<&'de ()>); + +impl<'de, T, E> Deserializer<'de> for Wrapper<'de, T, E> +where + T: Deserializer<'de, Error = E>, +{ + type Error = E; + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.0 { + Ok(deserializer) => deserializer.deserialize_ignored_any(visitor), //~ ERROR mismatched types + Err(error) => Err(error), + } + } +} + +fn main() {} diff --git a/tests/ui/trait-bounds/associated-error-bound-issue-145586.rs b/tests/ui/trait-bounds/associated-error-bound-issue-145586.rs new file mode 100644 index 000000000000..7b33cecbccd6 --- /dev/null +++ b/tests/ui/trait-bounds/associated-error-bound-issue-145586.rs @@ -0,0 +1,38 @@ +//@ run-rustfix + +#![allow(dead_code)] + +use std::marker::PhantomData; + +trait Visitor<'de> { + type Value; +} + +trait Deserializer<'de> { + type Error; + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>; +} + +struct Wrapper<'de, T, E>(Result, PhantomData<&'de ()>); + +impl<'de, T, E> Deserializer<'de> for Wrapper<'de, T, E> +where + T: Deserializer<'de>, +{ + type Error = E; + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.0 { + Ok(deserializer) => deserializer.deserialize_ignored_any(visitor), //~ ERROR mismatched types + Err(error) => Err(error), + } + } +} + +fn main() {} diff --git a/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr b/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr new file mode 100644 index 000000000000..18cfece99ffa --- /dev/null +++ b/tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/associated-error-bound-issue-145586.rs:32:33 + | +LL | impl<'de, T, E> Deserializer<'de> for Wrapper<'de, T, E> + | - expected this type parameter +... +LL | fn deserialize_ignored_any(self, visitor: V) -> Result + | ----------------------------- expected `Result<>::Value, E>` because of return type +... +LL | Ok(deserializer) => deserializer.deserialize_ignored_any(visitor), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result<>::Value, E>`, found `Result<>::Value, ...>` + | + = note: expected enum `Result<_, E>` + found enum `Result<_, >::Error>` +help: consider further restricting this bound + | +LL | T: Deserializer<'de, Error = E>, + | +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 50c6679c0b60cac63fd02806e776cd27de928b6c Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 1 Apr 2026 09:22:17 +0800 Subject: [PATCH 2/2] fix unit test naming style --- ...> deep-level-send-bound-check-issue-40827.rs} | 0 ...ep-level-send-bound-check-issue-40827.stderr} | 16 ++++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) rename tests/ui/trait-bounds/{deep-level-Send-bound-check-issue-40827.rs => deep-level-send-bound-check-issue-40827.rs} (100%) rename tests/ui/trait-bounds/{deep-level-Send-bound-check-issue-40827.stderr => deep-level-send-bound-check-issue-40827.stderr} (76%) diff --git a/tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.rs b/tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.rs similarity index 100% rename from tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.rs rename to tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.rs diff --git a/tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.stderr b/tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.stderr similarity index 76% rename from tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.stderr rename to tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.stderr index 7b59fe72f431..3776c355318d 100644 --- a/tests/ui/trait-bounds/deep-level-Send-bound-check-issue-40827.stderr +++ b/tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.stderr @@ -1,5 +1,5 @@ error[E0277]: `Rc` cannot be shared between threads safely - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:14:7 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:14:7 | LL | f(Foo(Arc::new(Bar::B(None)))); | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc` cannot be shared between threads safely @@ -8,24 +8,24 @@ LL | f(Foo(Arc::new(Bar::B(None)))); | = help: within `Bar`, the trait `Sync` is not implemented for `Rc` note: required because it appears within the type `Bar` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:6:6 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:6:6 | LL | enum Bar { | ^^^ = note: required for `Arc` to implement `Send` note: required because it appears within the type `Foo` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:4:8 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:4:8 | LL | struct Foo(Arc); | ^^^ note: required by a bound in `f` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:11:9 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:11:9 | LL | fn f(_: T) {} | ^^^^ required by this bound in `f` error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:14:7 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:14:7 | LL | f(Foo(Arc::new(Bar::B(None)))); | - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Rc` cannot be sent between threads safely @@ -34,18 +34,18 @@ LL | f(Foo(Arc::new(Bar::B(None)))); | = help: within `Bar`, the trait `Send` is not implemented for `Rc` note: required because it appears within the type `Bar` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:6:6 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:6:6 | LL | enum Bar { | ^^^ = note: required for `Arc` to implement `Send` note: required because it appears within the type `Foo` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:4:8 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:4:8 | LL | struct Foo(Arc); | ^^^ note: required by a bound in `f` - --> $DIR/deep-level-Send-bound-check-issue-40827.rs:11:9 + --> $DIR/deep-level-send-bound-check-issue-40827.rs:11:9 | LL | fn f(_: T) {} | ^^^^ required by this bound in `f`