diff options
author | Florian Diebold <[email protected]> | 2020-02-14 20:08:25 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-02-14 20:08:25 +0000 |
commit | f47dc4de8d7aadea17dba023ece70e5b170274b1 (patch) | |
tree | 929e3e7731f0ba519721686973775452333615d8 /crates/ra_hir_ty | |
parent | 1ead9ef13bb5da86e470c3d9a69d83795661d3c6 (diff) |
Check that impl self type matches up with expected self type in path mode
Fixes #3144.
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/src/marks.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/method_resolution.rs | 32 |
3 files changed, 42 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/marks.rs b/crates/ra_hir_ty/src/marks.rs index 0f754eb9c..4e0828425 100644 --- a/crates/ra_hir_ty/src/marks.rs +++ b/crates/ra_hir_ty/src/marks.rs | |||
@@ -4,6 +4,7 @@ test_utils::marks!( | |||
4 | type_var_cycles_resolve_completely | 4 | type_var_cycles_resolve_completely |
5 | type_var_cycles_resolve_as_possible | 5 | type_var_cycles_resolve_as_possible |
6 | type_var_resolves_to_int_var | 6 | type_var_resolves_to_int_var |
7 | impl_self_type_match_without_receiver | ||
7 | match_ergonomics_ref | 8 | match_ergonomics_ref |
8 | coerce_merge_fail_fallback | 9 | coerce_merge_fail_fallback |
9 | ); | 10 | ); |
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 5283bff28..4f8c52433 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>( | |||
425 | if !is_valid_candidate(db, name, receiver_ty, item, self_ty) { | 425 | if !is_valid_candidate(db, name, receiver_ty, item, self_ty) { |
426 | continue; | 426 | continue; |
427 | } | 427 | } |
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 | } | ||
428 | if let Some(result) = callback(&self_ty.value, item) { | 437 | if let Some(result) = callback(&self_ty.value, item) { |
429 | return Some(result); | 438 | return Some(result); |
430 | } | 439 | } |
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 1722563aa..1f767d324 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs | |||
@@ -964,6 +964,38 @@ fn test() { S2.into()<|>; } | |||
964 | } | 964 | } |
965 | 965 | ||
966 | #[test] | 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 | |||
998 | #[test] | ||
967 | fn method_resolution_encountering_fn_type() { | 999 | fn method_resolution_encountering_fn_type() { |
968 | type_at( | 1000 | type_at( |
969 | r#" | 1001 | r#" |