aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r--crates/ra_hir_def/src/generics.rs27
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)]
55pub struct WherePredicate { 55pub 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)]
61pub enum WherePredicateTarget {
62 TypeRef(TypeRef),
63 /// For desugared where predicates that can directly refer to a type param.
64 TypeParam(LocalTypeParamId)
65}
66
60type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::TraitDef, ast::TypeParam>>; 67type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::TraitDef, ast::TypeParam>>;
61 68
62impl GenericParams { 69impl 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
216impl HasChildSource for GenericDefId { 235impl HasChildSource for GenericDefId {