Repository: intellij-rust/intellij-rust
Issue: Duplicate trait available for import

```rust
use std::path::PathBuf;
mod a {
    use std::path::Path;
    use std::path::PathBuf;
    pub trait X {
        fn do_x(&self);
    }
    impl<T: AsRef<Path>> X for T {
        fn do_x(&self) {}
    }
}
fn main() {
    let p = PathBuf::new();
    p.do_x();
}
```
When I press Alt+Enter on `do_x` in `main`, the IDE suggests two imports, but they refer to the same trait (`X`). This is probably caused by the fact that `p` is `PathBuf` and can be coerced to `&Path` and both of these types implement the trait. If I replace the trait impl with `impl X for PathBuf { ... }`, the duplicate disappears. The expected behavior is to suggest each trait only once, so a disambiguation menu shouldn't be needed in this case.

Changed files:
src/test/kotlin/org/rust/ide/inspections/import/AutoImportFixTest.kt, src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.kt, src/test/kotlin/org/rust/lang/core/resolve/RsPreciseTraitMatchingTest.kt

diff --git a/src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.kt b/src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.kt
index af4d3e78e..39debacd1 100644
--- a/src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.kt
+++ b/src/main/kotlin/org/rust/lang/core/types/infer/TypeInference.kt
@@ -1212,7 +1212,12 @@ class RsFnInferenceContext(
             traitToCallee.keys.filterInScope(methodCall).forEach {
                 filtered += traitToCallee.getValue(it)
             }
-            filtered
+            if (filtered.isNotEmpty()) {
+                filtered
+            } else {
+                TypeInferenceMarks.methodPickTraitsOutOfScope.hit()
+                list
+            }
         }.singleOrFilter { callee ->
             // 2. Filter methods by trait bounds (try to select all obligations for each impl)
             TypeInferenceMarks.methodPickCheckBounds.hit()
@@ -1873,6 +1878,7 @@ object TypeInferenceMarks {
     val cyclicType = Testmark("cyclicType")
     val questionOperator = Testmark("questionOperator")
     val methodPickTraitScope = Testmark("methodPickTraitScope")
+    val methodPickTraitsOutOfScope = Testmark("methodPickTraitsOutOfScope")
     val methodPickCheckBounds = Testmark("methodPickCheckBounds")
     val methodPickDerefOrder = Testmark("methodPickDerefOrder")
     val methodPickCollapseTraits = Testmark("methodPickCollapseTraits")
diff --git a/src/test/kotlin/org/rust/ide/inspections/import/AutoImportFixTest.kt b/src/test/kotlin/org/rust/ide/inspections/import/AutoImportFixTest.kt
index c28ae6a42..fca60351a 100644
--- a/src/test/kotlin/org/rust/ide/inspections/import/AutoImportFixTest.kt
+++ b/src/test/kotlin/org/rust/ide/inspections/import/AutoImportFixTest.kt
@@ -1372,6 +1372,68 @@ class AutoImportFixTest : AutoImportFixTestBase() {
         }
     """)
 
+    fun `test suggest single method`() = checkAutoImportFixByText("""
+        struct Foo;
+        struct Bar;
+
+        #[lang="deref"]
+        trait Deref {
+            type Target;
+        }
+
+        impl Deref for Bar {
+            type Target = Foo;
+        }
+        mod a {
+            pub trait X {
+                fn do_x(&self);
+            }
+
+            impl X for ::Foo {
+                fn do_x(&self) {}
+            }
+
+            impl X for ::Bar {
+                fn do_x(&self) {}
+            }
+        }
+
+        fn main() {
+            Bar.<error>do_x/*caret*/</error>();
+        }
+    """, """
+        use a::X;
+
+        struct Foo;
+        struct Bar;
+
+        #[lang="deref"]
+        trait Deref {
+            type Target;
+        }
+
+        impl Deref for Bar {
+            type Target = Foo;
+        }
+        mod a {
+            pub trait X {
+                fn do_x(&self);
+            }
+
+            impl X for ::Foo {
+                fn do_x(&self) {}
+            }
+
+            impl X for ::Bar {
+                fn do_x(&self) {}
+            }
+        }
+
+        fn main() {
+            Bar.do_x/*caret*/();
+        }
+    """)
+
     /** Issue [2822](https://github.com/intellij-rust/intellij-rust/issues/2822) */
     fun `test do not try to import trait object method`() = checkAutoImportFixIsUnavailable("""
         mod foo {
@@ -1536,5 +1598,4 @@ class AutoImportFixTest : AutoImportFixTestBase() {
             let a = A;
         }
     """)
-
 }
diff --git a/src/test/kotlin/org/rust/lang/core/resolve/RsPreciseTraitMatchingTest.kt b/src/test/kotlin/org/rust/lang/core/resolve/RsPreciseTraitMatchingTest.kt
index 496cc79c9..fe0271dd0 100644
--- a/src/test/kotlin/org/rust/lang/core/resolve/RsPreciseTraitMatchingTest.kt
+++ b/src/test/kotlin/org/rust/lang/core/resolve/RsPreciseTraitMatchingTest.kt
@@ -263,4 +263,37 @@ class RsPreciseTraitMatchingTest : RsResolveTestBase() {
             S.foo();
         }   //^
     """, TypeInferenceMarks.traitSelectionSpecialization)
+
+    fun `test pick correct method from out of scope traits`() = checkByCode("""
+        struct Foo;
+        struct Bar;
+
+        #[lang="deref"]
+        trait Deref {
+            type Target;
+        }
+
+        impl Deref for Bar {
+            type Target = Foo;
+        }
+        mod a {
+            pub trait X {
+                fn do_x(&self);
+            }
+
+            impl X for ::Foo {
+                fn do_x(&self) {}
+            }
+
+            impl X for ::Bar {
+                fn do_x(&self) {}
+                   //X
+            }
+        }
+
+        fn main() {
+            Bar.do_x();
+               //^
+        }
+    """, TypeInferenceMarks.methodPickTraitsOutOfScope)
 }