diff --git a/crates/ra_hir_ty/src/marks.rs b/crates/ra_hir_ty/src/marks.rs index ae47855e95..de5cb1d6bc 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 trait_self_implements_self 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( 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); } 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); +struct Foo(T); +struct Bar(T); + +impl Wrapper> { + pub fn new(foo_: T) -> Self { + Wrapper(Foo(foo_)) + } +} + +impl Wrapper> { + pub fn new(bar_: T) -> Self { + Wrapper(Bar(bar_)) + } +} + +fn main() { + let a = Wrapper::>::new(1.0); + let b = Wrapper::>::new(1.0); + (a, b)<|>; +} +"#, + ); + assert_eq!(t, "(Wrapper>, Wrapper>)") +} + #[test] fn method_resolution_encountering_fn_type() { type_at(