diff options
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 21 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 15 |
3 files changed, 32 insertions, 12 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 9873a0440..cf787bdaa 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -212,7 +212,13 @@ fn iterate_trait_method_candidates<T>( | |||
212 | // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) | 212 | // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) |
213 | let env = lower::trait_env(db, resolver); | 213 | let env = lower::trait_env(db, resolver); |
214 | // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope | 214 | // if ty is `impl Trait` or `dyn Trait`, the trait doesn't need to be in scope |
215 | let traits = ty.value.inherent_trait().into_iter().chain(resolver.traits_in_scope(db)); | 215 | let inherent_trait = ty.value.inherent_trait().into_iter(); |
216 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope | ||
217 | let traits_from_env = env | ||
218 | .trait_predicates_for_self_ty(&ty.value) | ||
219 | .map(|tr| tr.trait_) | ||
220 | .flat_map(|t| t.all_super_traits(db)); | ||
221 | let traits = inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db)); | ||
216 | 'traits: for t in traits { | 222 | 'traits: for t in traits { |
217 | let data = t.trait_data(db); | 223 | let data = t.trait_data(db); |
218 | 224 | ||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index c414e6a95..127c69f8a 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -3660,8 +3660,7 @@ fn test<T: foo::Trait>(x: T) { | |||
3660 | } | 3660 | } |
3661 | "#, | 3661 | "#, |
3662 | ); | 3662 | ); |
3663 | // FIXME should be u32 | 3663 | assert_eq!(t, "u32"); |
3664 | assert_eq!(t, "{unknown}"); | ||
3665 | } | 3664 | } |
3666 | 3665 | ||
3667 | #[test] | 3666 | #[test] |
@@ -3673,8 +3672,8 @@ mod foo { | |||
3673 | fn foo(&self) -> u32 {} | 3672 | fn foo(&self) -> u32 {} |
3674 | } | 3673 | } |
3675 | } | 3674 | } |
3676 | trait Trait1: SuperTrait {} | 3675 | trait Trait1: foo::SuperTrait {} |
3677 | trait Trait2 where Self: SuperTrait {} | 3676 | trait Trait2 where Self: foo::SuperTrait {} |
3678 | 3677 | ||
3679 | fn test<T: Trait1, U: Trait2>(x: T, y: U) { | 3678 | fn test<T: Trait1, U: Trait2>(x: T, y: U) { |
3680 | x.foo(); | 3679 | x.foo(); |
@@ -3684,13 +3683,13 @@ fn test<T: Trait1, U: Trait2>(x: T, y: U) { | |||
3684 | @r###" | 3683 | @r###" |
3685 | [50; 54) 'self': &Self | 3684 | [50; 54) 'self': &Self |
3686 | [63; 65) '{}': () | 3685 | [63; 65) '{}': () |
3687 | [172; 173) 'x': T | 3686 | [182; 183) 'x': T |
3688 | [178; 179) 'y': U | 3687 | [188; 189) 'y': U |
3689 | [184; 213) '{ ...o(); }': () | 3688 | [194; 223) '{ ...o(); }': () |
3690 | [190; 191) 'x': T | 3689 | [200; 201) 'x': T |
3691 | [190; 197) 'x.foo()': {unknown} | 3690 | [200; 207) 'x.foo()': {unknown} |
3692 | [203; 204) 'y': U | 3691 | [213; 214) 'y': U |
3693 | [203; 210) 'y.foo()': {unknown} | 3692 | [213; 220) 'y.foo()': {unknown} |
3694 | "### | 3693 | "### |
3695 | ); | 3694 | ); |
3696 | } | 3695 | } |
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index 6e0271a96..c0c132809 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -96,6 +96,21 @@ pub struct TraitEnvironment { | |||
96 | pub predicates: Vec<GenericPredicate>, | 96 | pub predicates: Vec<GenericPredicate>, |
97 | } | 97 | } |
98 | 98 | ||
99 | impl TraitEnvironment { | ||
100 | /// Returns trait refs with the given self type which are supposed to hold | ||
101 | /// in this trait env. E.g. if we are in `foo<T: SomeTrait>()`, this will | ||
102 | /// find that `T: SomeTrait` if we call it for `T`. | ||
103 | pub(crate) fn trait_predicates_for_self_ty<'a>( | ||
104 | &'a self, | ||
105 | ty: &'a Ty, | ||
106 | ) -> impl Iterator<Item = &'a TraitRef> + 'a { | ||
107 | self.predicates.iter().filter_map(move |pred| match pred { | ||
108 | GenericPredicate::Implemented(tr) if tr.self_ty() == ty => Some(tr), | ||
109 | _ => None, | ||
110 | }) | ||
111 | } | ||
112 | } | ||
113 | |||
99 | /// Something (usually a goal), along with an environment. | 114 | /// Something (usually a goal), along with an environment. |
100 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 115 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
101 | pub struct InEnvironment<T> { | 116 | pub struct InEnvironment<T> { |