diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/generics.rs | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 7553d8a87..e4e616519 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs | |||
@@ -53,10 +53,17 @@ pub struct GenericParams { | |||
53 | /// associated type bindings like `Iterator<Item = u32>`. | 53 | /// associated type bindings like `Iterator<Item = u32>`. |
54 | #[derive(Clone, PartialEq, Eq, Debug)] | 54 | #[derive(Clone, PartialEq, Eq, Debug)] |
55 | pub struct WherePredicate { | 55 | pub struct WherePredicate { |
56 | pub type_ref: TypeRef, | 56 | pub target: WherePredicateTarget, |
57 | pub bound: TypeBound, | 57 | pub bound: TypeBound, |
58 | } | 58 | } |
59 | 59 | ||
60 | #[derive(Clone, PartialEq, Eq, Debug)] | ||
61 | pub enum WherePredicateTarget { | ||
62 | TypeRef(TypeRef), | ||
63 | /// For desugared where predicates that can directly refer to a type param. | ||
64 | TypeParam(LocalTypeParamId) | ||
65 | } | ||
66 | |||
60 | type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::TraitDef, ast::TypeParam>>; | 67 | type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::TraitDef, ast::TypeParam>>; |
61 | 68 | ||
62 | impl GenericParams { | 69 | impl GenericParams { |
@@ -190,18 +197,24 @@ impl GenericParams { | |||
190 | return; | 197 | return; |
191 | } | 198 | } |
192 | let bound = TypeBound::from_ast(bound); | 199 | let bound = TypeBound::from_ast(bound); |
193 | self.where_predicates.push(WherePredicate { type_ref, bound }); | 200 | self.where_predicates.push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); |
194 | } | 201 | } |
195 | 202 | ||
196 | fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) { | 203 | fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) { |
197 | type_ref.walk(&mut |type_ref| { | 204 | type_ref.walk(&mut |type_ref| { |
198 | if let TypeRef::ImplTrait(_) = type_ref { | 205 | if let TypeRef::ImplTrait(bounds) = type_ref { |
199 | let param = TypeParamData { | 206 | let param = TypeParamData { |
200 | name: None, | 207 | name: None, |
201 | default: None, | 208 | default: None, |
202 | provenance: TypeParamProvenance::ArgumentImplTrait, | 209 | provenance: TypeParamProvenance::ArgumentImplTrait, |
203 | }; | 210 | }; |
204 | let _param_id = self.types.alloc(param); | 211 | let param_id = self.types.alloc(param); |
212 | for bound in bounds { | ||
213 | self.where_predicates.push(WherePredicate { | ||
214 | target: WherePredicateTarget::TypeParam(param_id), | ||
215 | bound: bound.clone() | ||
216 | }); | ||
217 | } | ||
205 | } | 218 | } |
206 | }); | 219 | }); |
207 | } | 220 | } |
@@ -211,6 +224,12 @@ impl GenericParams { | |||
211 | .iter() | 224 | .iter() |
212 | .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None }) | 225 | .find_map(|(id, p)| if p.name.as_ref() == Some(name) { Some(id) } else { None }) |
213 | } | 226 | } |
227 | |||
228 | pub fn find_trait_self_param(&self) -> Option<LocalTypeParamId> { | ||
229 | self.types | ||
230 | .iter() | ||
231 | .find_map(|(id, p)| if p.provenance == TypeParamProvenance::TraitSelf { Some(id) } else { None }) | ||
232 | } | ||
214 | } | 233 | } |
215 | 234 | ||
216 | impl HasChildSource for GenericDefId { | 235 | impl HasChildSource for GenericDefId { |