Repository: rust-analyzer/rust-analyzer (rust)

Issue:
Wrong type deduced when implementing same method for different types
Rust-analyzer deduces the wrong type when for a given generic type, there are multiple implementations of a same method with the same signature.

```rust
pub struct Wrapper<T>(T);
pub struct Foo<T>(T);
pub struct Bar<T>(T);

impl<T> Wrapper<Foo<T>> {
    pub fn new(foo_: T) -> Self {
        Wrapper(Foo(foo_))
    }
}

impl<T> Wrapper<Bar<T>> {
    pub fn new(bar_: T) -> Self {
        Wrapper(Bar(bar_))
    }
}

fn main() {
    let _a = Wrapper::<Foo<f32>>::new(1.0);
    let _b = Wrapper::<Bar<f32>>::new(1.0);
}
```
In this example, type of ```_b``` is incorreclty deduced to ```Wrapper::<Foo<f64>>``` even with the turbofish type hinting.

![Sans titre](https://user-images.githubusercontent.com/39058530/74556525-8976b600-4f5e-11ea-8c93-d12e9031c753.png)

I can add myself the type of ```_b```, but the argument inlay hint for the ```new``` method will still be incorrect (displaying ```foo_``` instead of ```bar_```, and the "Go to definition" functionality will still go the the wrong definition.

It seems that rust-analyzer looks only at the first definition of the ```new``` method, even if there are better matches below.

I'm using the latest release of rust-analyzer (2020-02-11) with the latest version of the vscode extension.

I have first encountered this problem when using the method ```palette::rgb::Srgba::new``` from the ```palette``` crate.


Pull request:
Check that impl self type matches up with expected self type in path mode
Fixes #3144.

Patch:
diff --git a/crates/ra_hir_ty/src/marks.rs b/crates/ra_hir_ty/src/marks.rs
index 0f754eb9c7..4e08284250 100644
--- a/crates/ra_hir_ty/src/marks.rs
+++ b/crates/ra_hir_ty/src/marks.rs
@@ -4,6 +4,7 @@ test_utils::marks!(
     type_var_cycles_resolve_completely
     type_var_cycles_resolve_as_possible
     type_var_resolves_to_int_var
+    impl_self_type_match_without_receiver
     match_ergonomics_ref
     coerce_merge_fail_fallback
 );
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 5283bff28f..4f8c524336 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -425,6 +425,15 @@ fn iterate_inherent_methods<T>(
                 if !is_valid_candidate(db, name, receiver_ty, item, self_ty) {
                     continue;
                 }
+                // we have to check whether the self type unifies with the type
+                // that the impl is for. If we have a receiver type, this
+                // already happens in `is_valid_candidate` above; if not, we
+                // check it here
+                if receiver_ty.is_none() && inherent_impl_substs(db, impl_block, self_ty).is_none()
+                {
+                    test_utils::tested_by!(impl_self_type_match_without_receiver);
+                    continue;
+                }
                 if let Some(result) = callback(&self_ty.value, item) {
                     return Some(result);
                 }


Test patch:
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index 1722563aa1..1f767d324f 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -963,6 +963,38 @@ fn test() { S2.into()<|>; }
     assert_eq!(t, "{unknown}");
 }
 
+#[test]
+fn method_resolution_overloaded_method() {
+    test_utils::covers!(impl_self_type_match_without_receiver);
+    let t = type_at(
+        r#"
+//- main.rs
+struct Wrapper<T>(T);
+struct Foo<T>(T);
+struct Bar<T>(T);
+
+impl<T> Wrapper<Foo<T>> {
+    pub fn new(foo_: T) -> Self {
+        Wrapper(Foo(foo_))
+    }
+}
+
+impl<T> Wrapper<Bar<T>> {
+    pub fn new(bar_: T) -> Self {
+        Wrapper(Bar(bar_))
+    }
+}
+
+fn main() {
+    let a = Wrapper::<Foo<f32>>::new(1.0);
+    let b = Wrapper::<Bar<f32>>::new(1.0);
+    (a, b)<|>;
+}
+"#,
+    );
+    assert_eq!(t, "(Wrapper<Foo<f32>>, Wrapper<Bar<f32>>)")
+}
+
 #[test]
 fn method_resolution_encountering_fn_type() {
     type_at(