Repository: rust-lang/rust
Pull request: Fix associated type bound suggestion span issue

Fixes rust-lang/rust#145586

Changed files:
filename: compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
patch: @@ -105,7 +105,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         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))

filename: tests/ui/trait-bounds/associated-error-bound-issue-145586.fixed
patch: @@ -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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>;
+}
+
+struct Wrapper<'de, T, E>(Result<T, E>, 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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        match self.0 {
+            Ok(deserializer) => deserializer.deserialize_ignored_any(visitor), //~ ERROR mismatched types
+            Err(error) => Err(error),
+        }
+    }
+}
+
+fn main() {}

filename: tests/ui/trait-bounds/associated-error-bound-issue-145586.rs
patch: @@ -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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>;
+}
+
+struct Wrapper<'de, T, E>(Result<T, E>, PhantomData<&'de ()>);
+
+impl<'de, T, E> Deserializer<'de> for Wrapper<'de, T, E>
+where
+    T: Deserializer<'de>,
+{
+    type Error = E;
+
+    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        match self.0 {
+            Ok(deserializer) => deserializer.deserialize_ignored_any(visitor), //~ ERROR mismatched types
+            Err(error) => Err(error),
+        }
+    }
+}
+
+fn main() {}

filename: tests/ui/trait-bounds/associated-error-bound-issue-145586.stderr
patch: @@ -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<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+   |                                                        ----------------------------- expected `Result<<V as Visitor<'de>>::Value, E>` because of return type
+...
+LL |             Ok(deserializer) => deserializer.deserialize_ignored_any(visitor),
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result<<V as Visitor<'_>>::Value, E>`, found `Result<<V as Visitor<'_>>::Value, ...>`
+   |
+   = note: expected enum `Result<_, E>`
+              found enum `Result<_, <T as Deserializer<'de>>::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`.

filename: tests/ui/trait-bounds/deep-level-send-bound-check-issue-40827.stderr
patch: @@ -1,5 +1,5 @@
 error[E0277]: `Rc<Foo>` 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<Foo>` 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<Foo>`
 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<Bar>` 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<Bar>);
    |        ^^^
 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: Send>(_: T) {}
    |         ^^^^ required by this bound in `f`
 
 error[E0277]: `Rc<Foo>` 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<Foo>` 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<Foo>`
 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<Bar>` 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<Bar>);
    |        ^^^
 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: Send>(_: T) {}
    |         ^^^^ required by this bound in `f`