Skip to content

Commit f47dc4d

Browse files
committed
Check that impl self type matches up with expected self type in path mode
Fixes #3144.
1 parent 1ead9ef commit f47dc4d

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

crates/ra_hir_ty/src/marks.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ test_utils::marks!(
44
type_var_cycles_resolve_completely
55
type_var_cycles_resolve_as_possible
66
type_var_resolves_to_int_var
7+
impl_self_type_match_without_receiver
78
match_ergonomics_ref
89
coerce_merge_fail_fallback
910
);

crates/ra_hir_ty/src/method_resolution.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,15 @@ fn iterate_inherent_methods<T>(
425425
if !is_valid_candidate(db, name, receiver_ty, item, self_ty) {
426426
continue;
427427
}
428+
// we have to check whether the self type unifies with the type
429+
// that the impl is for. If we have a receiver type, this
430+
// already happens in `is_valid_candidate` above; if not, we
431+
// check it here
432+
if receiver_ty.is_none() && inherent_impl_substs(db, impl_block, self_ty).is_none()
433+
{
434+
test_utils::tested_by!(impl_self_type_match_without_receiver);
435+
continue;
436+
}
428437
if let Some(result) = callback(&self_ty.value, item) {
429438
return Some(result);
430439
}

crates/ra_hir_ty/src/tests/method_resolution.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,38 @@ fn test() { S2.into()<|>; }
963963
assert_eq!(t, "{unknown}");
964964
}
965965

966+
#[test]
967+
fn method_resolution_overloaded_method() {
968+
test_utils::covers!(impl_self_type_match_without_receiver);
969+
let t = type_at(
970+
r#"
971+
//- main.rs
972+
struct Wrapper<T>(T);
973+
struct Foo<T>(T);
974+
struct Bar<T>(T);
975+
976+
impl<T> Wrapper<Foo<T>> {
977+
pub fn new(foo_: T) -> Self {
978+
Wrapper(Foo(foo_))
979+
}
980+
}
981+
982+
impl<T> Wrapper<Bar<T>> {
983+
pub fn new(bar_: T) -> Self {
984+
Wrapper(Bar(bar_))
985+
}
986+
}
987+
988+
fn main() {
989+
let a = Wrapper::<Foo<f32>>::new(1.0);
990+
let b = Wrapper::<Bar<f32>>::new(1.0);
991+
(a, b)<|>;
992+
}
993+
"#,
994+
);
995+
assert_eq!(t, "(Wrapper<Foo<f32>>, Wrapper<Bar<f32>>)")
996+
}
997+
966998
#[test]
967999
fn method_resolution_encountering_fn_type() {
9681000
type_at(

0 commit comments

Comments
 (0)