diff options
author | Laurențiu Nicola <[email protected]> | 2020-02-18 11:26:00 +0000 |
---|---|---|
committer | Laurențiu Nicola <[email protected]> | 2020-02-19 08:46:13 +0000 |
commit | 5b05209744ce7dcd15f814482babbfd163553b57 (patch) | |
tree | a0c23311e82e8bb4db249d76088465a294cb2eb3 | |
parent | 20252efb32bfdfe7392934a95a6c6d6b583d10e7 (diff) |
Exclude methods from non-parameter types introduced by generic constraints
-rw-r--r-- | crates/ra_hir_ty/src/method_resolution.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/method_resolution.rs | 23 |
2 files changed, 34 insertions, 6 deletions
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index 964acdb09..988d83af5 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs | |||
@@ -377,12 +377,17 @@ fn iterate_trait_method_candidates<T>( | |||
377 | ) -> Option<T> { | 377 | ) -> Option<T> { |
378 | // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope | 378 | // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope |
379 | let inherent_trait = self_ty.value.inherent_trait().into_iter(); | 379 | let inherent_trait = self_ty.value.inherent_trait().into_iter(); |
380 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope | 380 | let env_traits = if let Ty::Placeholder(_) = self_ty.value { |
381 | let traits_from_env = env | 381 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope |
382 | .trait_predicates_for_self_ty(&self_ty.value) | 382 | env.trait_predicates_for_self_ty(&self_ty.value) |
383 | .map(|tr| tr.trait_) | 383 | .map(|tr| tr.trait_) |
384 | .flat_map(|t| all_super_traits(db, t)); | 384 | .flat_map(|t| all_super_traits(db, t)) |
385 | let traits = inherent_trait.chain(traits_from_env).chain(traits_in_scope.iter().copied()); | 385 | .collect() |
386 | } else { | ||
387 | Vec::new() | ||
388 | }; | ||
389 | let traits = | ||
390 | inherent_trait.chain(env_traits.into_iter()).chain(traits_in_scope.iter().copied()); | ||
386 | 'traits: for t in traits { | 391 | 'traits: for t in traits { |
387 | let data = db.trait_data(t); | 392 | let data = db.trait_data(t); |
388 | 393 | ||
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 1f767d324..644d59e17 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs | |||
@@ -1008,6 +1008,29 @@ fn test() { foo.call()<|>; } | |||
1008 | } | 1008 | } |
1009 | 1009 | ||
1010 | #[test] | 1010 | #[test] |
1011 | fn method_resolution_non_parameter_type() { | ||
1012 | let t = type_at( | ||
1013 | r#" | ||
1014 | //- /main.rs | ||
1015 | mod a { | ||
1016 | pub trait Foo { | ||
1017 | fn foo(&self); | ||
1018 | } | ||
1019 | } | ||
1020 | |||
1021 | struct Wrapper<T>(T); | ||
1022 | fn foo<T>(t: Wrapper<T>) | ||
1023 | where | ||
1024 | Wrapper<T>: a::Foo, | ||
1025 | { | ||
1026 | t.foo()<|>; | ||
1027 | } | ||
1028 | "#, | ||
1029 | ); | ||
1030 | assert_eq!(t, "{unknown}"); | ||
1031 | } | ||
1032 | |||
1033 | #[test] | ||
1011 | fn method_resolution_slow() { | 1034 | fn method_resolution_slow() { |
1012 | // this can get quite slow if we set the solver size limit too high | 1035 | // this can get quite slow if we set the solver size limit too high |
1013 | let t = type_at( | 1036 | let t = type_at( |