aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/generics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/generics.rs')
-rw-r--r--crates/ra_hir/src/generics.rs22
1 files changed, 14 insertions, 8 deletions
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
index d6728cc9f..c76df0698 100644
--- a/crates/ra_hir/src/generics.rs
+++ b/crates/ra_hir/src/generics.rs
@@ -87,11 +87,15 @@ impl GenericParams {
87 // traits get the Self type as an implicit first type parameter 87 // traits get the Self type as an implicit first type parameter
88 generics.params.push(GenericParam { idx: start, name: SELF_TYPE, default: None }); 88 generics.params.push(GenericParam { idx: start, name: SELF_TYPE, default: None });
89 generics.fill(&it.source(db).ast, start + 1); 89 generics.fill(&it.source(db).ast, start + 1);
90 // add super traits as bounds on Self
91 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
92 let self_param = TypeRef::Path(SELF_TYPE.into());
93 generics.fill_bounds(&it.source(db).ast, self_param);
90 } 94 }
91 GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start), 95 GenericDef::TypeAlias(it) => generics.fill(&it.source(db).ast, start),
92 // Note that we don't add `Self` here: in `impl`s, `Self` is not a 96 // Note that we don't add `Self` here: in `impl`s, `Self` is not a
93 // type-parameter, but rather is a type-alias for impl's target 97 // type-parameter, but rather is a type-alias for impl's target
94 // type, so this is handled by the resovler. 98 // type, so this is handled by the resolver.
95 GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start), 99 GenericDef::ImplBlock(it) => generics.fill(&it.source(db).ast, start),
96 GenericDef::EnumVariant(_) => {} 100 GenericDef::EnumVariant(_) => {}
97 } 101 }
@@ -108,6 +112,14 @@ impl GenericParams {
108 } 112 }
109 } 113 }
110 114
115 fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) {
116 for bound in
117 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
118 {
119 self.add_where_predicate_from_bound(bound, type_ref.clone());
120 }
121 }
122
111 fn fill_params(&mut self, params: ast::TypeParamList, start: u32) { 123 fn fill_params(&mut self, params: ast::TypeParamList, start: u32) {
112 for (idx, type_param) in params.type_params().enumerate() { 124 for (idx, type_param) in params.type_params().enumerate() {
113 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); 125 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
@@ -117,13 +129,7 @@ impl GenericParams {
117 self.params.push(param); 129 self.params.push(param);
118 130
119 let type_ref = TypeRef::Path(name.into()); 131 let type_ref = TypeRef::Path(name.into());
120 for bound in type_param 132 self.fill_bounds(&type_param, type_ref);
121 .type_bound_list()
122 .iter()
123 .flat_map(|type_bound_list| type_bound_list.bounds())
124 {
125 self.add_where_predicate_from_bound(bound, type_ref.clone());
126 }
127 } 133 }
128 } 134 }
129 135