aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/generics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/generics.rs')
-rw-r--r--crates/ra_hir_def/src/generics.rs68
1 files changed, 47 insertions, 21 deletions
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index d850244c4..09a5241f7 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -15,6 +15,7 @@ use ra_prof::profile;
15use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; 15use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner};
16 16
17use crate::{ 17use crate::{
18 body::LowerCtx,
18 child_by_source::ChildBySource, 19 child_by_source::ChildBySource,
19 db::DefDatabase, 20 db::DefDatabase,
20 dyn_map::DynMap, 21 dyn_map::DynMap,
@@ -80,11 +81,13 @@ impl GenericParams {
80 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) { 81 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) {
81 let mut generics = GenericParams { types: Arena::default(), where_predicates: Vec::new() }; 82 let mut generics = GenericParams { types: Arena::default(), where_predicates: Vec::new() };
82 let mut sm = ArenaMap::default(); 83 let mut sm = ArenaMap::default();
84
83 // FIXME: add `: Sized` bound for everything except for `Self` in traits 85 // FIXME: add `: Sized` bound for everything except for `Self` in traits
84 let file_id = match def { 86 let file_id = match def {
85 GenericDefId::FunctionId(it) => { 87 GenericDefId::FunctionId(it) => {
86 let src = it.lookup(db).source(db); 88 let src = it.lookup(db).source(db);
87 generics.fill(&mut sm, &src.value); 89 let lower_ctx = LowerCtx::new(db, src.file_id);
90 generics.fill(&lower_ctx, &mut sm, &src.value);
88 // lower `impl Trait` in arguments 91 // lower `impl Trait` in arguments
89 let data = db.function_data(it); 92 let data = db.function_data(it);
90 for param in &data.params { 93 for param in &data.params {
@@ -94,21 +97,25 @@ impl GenericParams {
94 } 97 }
95 GenericDefId::AdtId(AdtId::StructId(it)) => { 98 GenericDefId::AdtId(AdtId::StructId(it)) => {
96 let src = it.lookup(db).source(db); 99 let src = it.lookup(db).source(db);
97 generics.fill(&mut sm, &src.value); 100 let lower_ctx = LowerCtx::new(db, src.file_id);
101 generics.fill(&lower_ctx, &mut sm, &src.value);
98 src.file_id 102 src.file_id
99 } 103 }
100 GenericDefId::AdtId(AdtId::UnionId(it)) => { 104 GenericDefId::AdtId(AdtId::UnionId(it)) => {
101 let src = it.lookup(db).source(db); 105 let src = it.lookup(db).source(db);
102 generics.fill(&mut sm, &src.value); 106 let lower_ctx = LowerCtx::new(db, src.file_id);
107 generics.fill(&lower_ctx, &mut sm, &src.value);
103 src.file_id 108 src.file_id
104 } 109 }
105 GenericDefId::AdtId(AdtId::EnumId(it)) => { 110 GenericDefId::AdtId(AdtId::EnumId(it)) => {
106 let src = it.lookup(db).source(db); 111 let src = it.lookup(db).source(db);
107 generics.fill(&mut sm, &src.value); 112 let lower_ctx = LowerCtx::new(db, src.file_id);
113 generics.fill(&lower_ctx, &mut sm, &src.value);
108 src.file_id 114 src.file_id
109 } 115 }
110 GenericDefId::TraitId(it) => { 116 GenericDefId::TraitId(it) => {
111 let src = it.lookup(db).source(db); 117 let src = it.lookup(db).source(db);
118 let lower_ctx = LowerCtx::new(db, src.file_id);
112 119
113 // traits get the Self type as an implicit first type parameter 120 // traits get the Self type as an implicit first type parameter
114 let self_param_id = generics.types.alloc(TypeParamData { 121 let self_param_id = generics.types.alloc(TypeParamData {
@@ -120,14 +127,16 @@ impl GenericParams {
120 // add super traits as bounds on Self 127 // add super traits as bounds on Self
121 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 128 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
122 let self_param = TypeRef::Path(name![Self].into()); 129 let self_param = TypeRef::Path(name![Self].into());
123 generics.fill_bounds(&src.value, self_param); 130 generics.fill_bounds(&lower_ctx, &src.value, self_param);
124 131
125 generics.fill(&mut sm, &src.value); 132 generics.fill(&lower_ctx, &mut sm, &src.value);
126 src.file_id 133 src.file_id
127 } 134 }
128 GenericDefId::TypeAliasId(it) => { 135 GenericDefId::TypeAliasId(it) => {
129 let src = it.lookup(db).source(db); 136 let src = it.lookup(db).source(db);
130 generics.fill(&mut sm, &src.value); 137 let lower_ctx = LowerCtx::new(db, src.file_id);
138
139 generics.fill(&lower_ctx, &mut sm, &src.value);
131 src.file_id 140 src.file_id
132 } 141 }
133 // Note that we don't add `Self` here: in `impl`s, `Self` is not a 142 // Note that we don't add `Self` here: in `impl`s, `Self` is not a
@@ -135,7 +144,9 @@ impl GenericParams {
135 // type, so this is handled by the resolver. 144 // type, so this is handled by the resolver.
136 GenericDefId::ImplId(it) => { 145 GenericDefId::ImplId(it) => {
137 let src = it.lookup(db).source(db); 146 let src = it.lookup(db).source(db);
138 generics.fill(&mut sm, &src.value); 147 let lower_ctx = LowerCtx::new(db, src.file_id);
148
149 generics.fill(&lower_ctx, &mut sm, &src.value);
139 src.file_id 150 src.file_id
140 } 151 }
141 // We won't be using this ID anyway 152 // We won't be using this ID anyway
@@ -145,28 +156,38 @@ impl GenericParams {
145 (generics, InFile::new(file_id, sm)) 156 (generics, InFile::new(file_id, sm))
146 } 157 }
147 158
148 fn fill(&mut self, sm: &mut SourceMap, node: &dyn TypeParamsOwner) { 159 fn fill(&mut self, lower_ctx: &LowerCtx, sm: &mut SourceMap, node: &dyn TypeParamsOwner) {
149 if let Some(params) = node.type_param_list() { 160 if let Some(params) = node.type_param_list() {
150 self.fill_params(sm, params) 161 self.fill_params(lower_ctx, sm, params)
151 } 162 }
152 if let Some(where_clause) = node.where_clause() { 163 if let Some(where_clause) = node.where_clause() {
153 self.fill_where_predicates(where_clause); 164 self.fill_where_predicates(lower_ctx, where_clause);
154 } 165 }
155 } 166 }
156 167
157 fn fill_bounds(&mut self, node: &dyn ast::TypeBoundsOwner, type_ref: TypeRef) { 168 fn fill_bounds(
169 &mut self,
170 lower_ctx: &LowerCtx,
171 node: &dyn ast::TypeBoundsOwner,
172 type_ref: TypeRef,
173 ) {
158 for bound in 174 for bound in
159 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) 175 node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
160 { 176 {
161 self.add_where_predicate_from_bound(bound, type_ref.clone()); 177 self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone());
162 } 178 }
163 } 179 }
164 180
165 fn fill_params(&mut self, sm: &mut SourceMap, params: ast::TypeParamList) { 181 fn fill_params(
182 &mut self,
183 lower_ctx: &LowerCtx,
184 sm: &mut SourceMap,
185 params: ast::TypeParamList,
186 ) {
166 for type_param in params.type_params() { 187 for type_param in params.type_params() {
167 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); 188 let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
168 // FIXME: Use `Path::from_src` 189 // FIXME: Use `Path::from_src`
169 let default = type_param.default_type().map(TypeRef::from_ast); 190 let default = type_param.default_type().map(|it| TypeRef::from_ast(lower_ctx, it));
170 let param = TypeParamData { 191 let param = TypeParamData {
171 name: Some(name.clone()), 192 name: Some(name.clone()),
172 default, 193 default,
@@ -176,29 +197,34 @@ impl GenericParams {
176 sm.insert(param_id, Either::Right(type_param.clone())); 197 sm.insert(param_id, Either::Right(type_param.clone()));
177 198
178 let type_ref = TypeRef::Path(name.into()); 199 let type_ref = TypeRef::Path(name.into());
179 self.fill_bounds(&type_param, type_ref); 200 self.fill_bounds(&lower_ctx, &type_param, type_ref);
180 } 201 }
181 } 202 }
182 203
183 fn fill_where_predicates(&mut self, where_clause: ast::WhereClause) { 204 fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) {
184 for pred in where_clause.predicates() { 205 for pred in where_clause.predicates() {
185 let type_ref = match pred.type_ref() { 206 let type_ref = match pred.type_ref() {
186 Some(type_ref) => type_ref, 207 Some(type_ref) => type_ref,
187 None => continue, 208 None => continue,
188 }; 209 };
189 let type_ref = TypeRef::from_ast(type_ref); 210 let type_ref = TypeRef::from_ast(lower_ctx, type_ref);
190 for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { 211 for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
191 self.add_where_predicate_from_bound(bound, type_ref.clone()); 212 self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone());
192 } 213 }
193 } 214 }
194 } 215 }
195 216
196 fn add_where_predicate_from_bound(&mut self, bound: ast::TypeBound, type_ref: TypeRef) { 217 fn add_where_predicate_from_bound(
218 &mut self,
219 lower_ctx: &LowerCtx,
220 bound: ast::TypeBound,
221 type_ref: TypeRef,
222 ) {
197 if bound.question_token().is_some() { 223 if bound.question_token().is_some() {
198 // FIXME: remove this bound 224 // FIXME: remove this bound
199 return; 225 return;
200 } 226 }
201 let bound = TypeBound::from_ast(bound); 227 let bound = TypeBound::from_ast(lower_ctx, bound);
202 self.where_predicates 228 self.where_predicates
203 .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound }); 229 .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound });
204 } 230 }