diff options
Diffstat (limited to 'crates/ra_hir/src/generics.rs')
-rw-r--r-- | crates/ra_hir/src/generics.rs | 22 |
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 | ||