diff options
author | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-12-23 14:35:31 +0000 |
commit | b21d9337d9200e2cfdc90b386591c72c302dc03e (patch) | |
tree | f81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_def/src/resolver.rs | |
parent | 18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff) | |
parent | ce07a2daa9e53aa86a769f8641b14c2878444fbc (diff) |
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_hir_def/src/resolver.rs')
-rw-r--r-- | crates/ra_hir_def/src/resolver.rs | 296 |
1 files changed, 191 insertions, 105 deletions
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 0847f6dcf..cf3c33d78 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use hir_expand::{ | 4 | use hir_expand::{ |
5 | name::{self, Name}, | 5 | name::{name, Name}, |
6 | MacroDefId, | 6 | MacroDefId, |
7 | }; | 7 | }; |
8 | use ra_db::CrateId; | 8 | use ra_db::CrateId; |
@@ -10,20 +10,23 @@ use rustc_hash::FxHashSet; | |||
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | body::scope::{ExprScopes, ScopeId}, | 12 | body::scope::{ExprScopes, ScopeId}, |
13 | body::Body, | ||
13 | builtin_type::BuiltinType, | 14 | builtin_type::BuiltinType, |
14 | db::DefDatabase, | 15 | db::DefDatabase, |
15 | expr::{ExprId, PatId}, | 16 | expr::{ExprId, PatId}, |
16 | generics::GenericParams, | 17 | generics::GenericParams, |
18 | item_scope::BuiltinShadowMode, | ||
17 | nameres::CrateDefMap, | 19 | nameres::CrateDefMap, |
18 | path::{Path, PathKind}, | 20 | path::{ModPath, PathKind}, |
19 | per_ns::PerNs, | 21 | per_ns::PerNs, |
20 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, | 22 | AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, |
21 | GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, | 23 | FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, |
22 | StructId, TraitId, TypeAliasId, | 24 | StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId, |
23 | }; | 25 | }; |
24 | 26 | ||
25 | #[derive(Debug, Clone, Default)] | 27 | #[derive(Debug, Clone, Default)] |
26 | pub struct Resolver { | 28 | pub struct Resolver { |
29 | // FIXME: all usages generally call `.rev`, so maybe reverse once in consturciton? | ||
27 | scopes: Vec<Scope>, | 30 | scopes: Vec<Scope>, |
28 | } | 31 | } |
29 | 32 | ||
@@ -53,12 +56,14 @@ enum Scope { | |||
53 | AdtScope(AdtId), | 56 | AdtScope(AdtId), |
54 | /// Local bindings | 57 | /// Local bindings |
55 | ExprScope(ExprScope), | 58 | ExprScope(ExprScope), |
59 | /// Temporary hack to support local items. | ||
60 | LocalItemsScope(Arc<Body>), | ||
56 | } | 61 | } |
57 | 62 | ||
58 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 63 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
59 | pub enum TypeNs { | 64 | pub enum TypeNs { |
60 | SelfType(ImplId), | 65 | SelfType(ImplId), |
61 | GenericParam(u32), | 66 | GenericParam(TypeParamId), |
62 | AdtId(AdtId), | 67 | AdtId(AdtId), |
63 | AdtSelfType(AdtId), | 68 | AdtSelfType(AdtId), |
64 | // Yup, enum variants are added to the types ns, but any usage of variant as | 69 | // Yup, enum variants are added to the types ns, but any usage of variant as |
@@ -90,8 +95,8 @@ pub enum ValueNs { | |||
90 | 95 | ||
91 | impl Resolver { | 96 | impl Resolver { |
92 | /// Resolve known trait from std, like `std::futures::Future` | 97 | /// Resolve known trait from std, like `std::futures::Future` |
93 | pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option<TraitId> { | 98 | pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &ModPath) -> Option<TraitId> { |
94 | let res = self.resolve_module_path(db, path).take_types()?; | 99 | let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; |
95 | match res { | 100 | match res { |
96 | ModuleDefId::TraitId(it) => Some(it), | 101 | ModuleDefId::TraitId(it) => Some(it), |
97 | _ => None, | 102 | _ => None, |
@@ -99,8 +104,8 @@ impl Resolver { | |||
99 | } | 104 | } |
100 | 105 | ||
101 | /// Resolve known struct from std, like `std::boxed::Box` | 106 | /// Resolve known struct from std, like `std::boxed::Box` |
102 | pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option<StructId> { | 107 | pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &ModPath) -> Option<StructId> { |
103 | let res = self.resolve_module_path(db, path).take_types()?; | 108 | let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; |
104 | match res { | 109 | match res { |
105 | ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), | 110 | ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), |
106 | _ => None, | 111 | _ => None, |
@@ -108,87 +113,116 @@ impl Resolver { | |||
108 | } | 113 | } |
109 | 114 | ||
110 | /// Resolve known enum from std, like `std::result::Result` | 115 | /// Resolve known enum from std, like `std::result::Result` |
111 | pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option<EnumId> { | 116 | pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &ModPath) -> Option<EnumId> { |
112 | let res = self.resolve_module_path(db, path).take_types()?; | 117 | let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; |
113 | match res { | 118 | match res { |
114 | ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), | 119 | ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), |
115 | _ => None, | 120 | _ => None, |
116 | } | 121 | } |
117 | } | 122 | } |
118 | 123 | ||
119 | /// pub only for source-binder | 124 | fn resolve_module_path( |
120 | pub fn resolve_module_path(&self, db: &impl DefDatabase, path: &Path) -> PerNs { | 125 | &self, |
126 | db: &impl DefDatabase, | ||
127 | path: &ModPath, | ||
128 | shadow: BuiltinShadowMode, | ||
129 | ) -> PerNs { | ||
121 | let (item_map, module) = match self.module() { | 130 | let (item_map, module) = match self.module() { |
122 | Some(it) => it, | 131 | Some(it) => it, |
123 | None => return PerNs::none(), | 132 | None => return PerNs::none(), |
124 | }; | 133 | }; |
125 | let (module_res, segment_index) = item_map.resolve_path(db, module, path); | 134 | let (module_res, segment_index) = item_map.resolve_path(db, module, &path, shadow); |
126 | if segment_index.is_some() { | 135 | if segment_index.is_some() { |
127 | return PerNs::none(); | 136 | return PerNs::none(); |
128 | } | 137 | } |
129 | module_res | 138 | module_res |
130 | } | 139 | } |
131 | 140 | ||
141 | pub fn resolve_module_path_in_items(&self, db: &impl DefDatabase, path: &ModPath) -> PerNs { | ||
142 | self.resolve_module_path(db, path, BuiltinShadowMode::Module) | ||
143 | } | ||
144 | |||
132 | pub fn resolve_path_in_type_ns( | 145 | pub fn resolve_path_in_type_ns( |
133 | &self, | 146 | &self, |
134 | db: &impl DefDatabase, | 147 | db: &impl DefDatabase, |
135 | path: &Path, | 148 | path: &ModPath, |
136 | ) -> Option<(TypeNs, Option<usize>)> { | 149 | ) -> Option<(TypeNs, Option<usize>)> { |
137 | if path.is_type_relative() { | 150 | let first_name = path.segments.first()?; |
138 | return None; | ||
139 | } | ||
140 | let first_name = &path.segments.first()?.name; | ||
141 | let skip_to_mod = path.kind != PathKind::Plain; | 151 | let skip_to_mod = path.kind != PathKind::Plain; |
142 | for scope in self.scopes.iter().rev() { | 152 | for scope in self.scopes.iter().rev() { |
143 | match scope { | 153 | match scope { |
144 | Scope::ExprScope(_) => continue, | 154 | Scope::ExprScope(_) => continue, |
145 | Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue, | 155 | Scope::GenericParams { .. } |
156 | | Scope::ImplBlockScope(_) | ||
157 | | Scope::LocalItemsScope(_) | ||
158 | if skip_to_mod => | ||
159 | { | ||
160 | continue | ||
161 | } | ||
146 | 162 | ||
147 | Scope::GenericParams { params, .. } => { | 163 | Scope::GenericParams { params, def } => { |
148 | if let Some(param) = params.find_by_name(first_name) { | 164 | if let Some(local_id) = params.find_by_name(first_name) { |
149 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 165 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; |
150 | return Some((TypeNs::GenericParam(param.idx), idx)); | 166 | return Some(( |
167 | TypeNs::GenericParam(TypeParamId { local_id, parent: *def }), | ||
168 | idx, | ||
169 | )); | ||
151 | } | 170 | } |
152 | } | 171 | } |
153 | Scope::ImplBlockScope(impl_) => { | 172 | Scope::ImplBlockScope(impl_) => { |
154 | if first_name == &name::SELF_TYPE { | 173 | if first_name == &name![Self] { |
155 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 174 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; |
156 | return Some((TypeNs::SelfType(*impl_), idx)); | 175 | return Some((TypeNs::SelfType(*impl_), idx)); |
157 | } | 176 | } |
158 | } | 177 | } |
159 | Scope::AdtScope(adt) => { | 178 | Scope::AdtScope(adt) => { |
160 | if first_name == &name::SELF_TYPE { | 179 | if first_name == &name![Self] { |
161 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | 180 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; |
162 | return Some((TypeNs::AdtSelfType(*adt), idx)); | 181 | return Some((TypeNs::AdtSelfType(*adt), idx)); |
163 | } | 182 | } |
164 | } | 183 | } |
165 | Scope::ModuleScope(m) => { | 184 | Scope::ModuleScope(m) => { |
166 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | 185 | let (module_def, idx) = m.crate_def_map.resolve_path( |
167 | let res = match module_def.take_types()? { | 186 | db, |
168 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), | 187 | m.module_id, |
169 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), | 188 | &path, |
170 | 189 | BuiltinShadowMode::Other, | |
171 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), | 190 | ); |
172 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | 191 | let res = to_type_ns(module_def)?; |
173 | |||
174 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), | ||
175 | |||
176 | ModuleDefId::FunctionId(_) | ||
177 | | ModuleDefId::ConstId(_) | ||
178 | | ModuleDefId::StaticId(_) | ||
179 | | ModuleDefId::ModuleId(_) => return None, | ||
180 | }; | ||
181 | return Some((res, idx)); | 192 | return Some((res, idx)); |
182 | } | 193 | } |
194 | Scope::LocalItemsScope(body) => { | ||
195 | let def = body.item_scope.get(first_name, BuiltinShadowMode::Other); | ||
196 | if let Some(res) = to_type_ns(def) { | ||
197 | return Some((res, None)); | ||
198 | } | ||
199 | } | ||
183 | } | 200 | } |
184 | } | 201 | } |
185 | None | 202 | return None; |
203 | fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> { | ||
204 | let res = match per_ns.take_types()? { | ||
205 | ModuleDefId::AdtId(it) => TypeNs::AdtId(it), | ||
206 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), | ||
207 | |||
208 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), | ||
209 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | ||
210 | |||
211 | ModuleDefId::TraitId(it) => TypeNs::TraitId(it), | ||
212 | |||
213 | ModuleDefId::FunctionId(_) | ||
214 | | ModuleDefId::ConstId(_) | ||
215 | | ModuleDefId::StaticId(_) | ||
216 | | ModuleDefId::ModuleId(_) => return None, | ||
217 | }; | ||
218 | Some(res) | ||
219 | } | ||
186 | } | 220 | } |
187 | 221 | ||
188 | pub fn resolve_path_in_type_ns_fully( | 222 | pub fn resolve_path_in_type_ns_fully( |
189 | &self, | 223 | &self, |
190 | db: &impl DefDatabase, | 224 | db: &impl DefDatabase, |
191 | path: &Path, | 225 | path: &ModPath, |
192 | ) -> Option<TypeNs> { | 226 | ) -> Option<TypeNs> { |
193 | let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; | 227 | let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; |
194 | if unresolved.is_some() { | 228 | if unresolved.is_some() { |
@@ -197,17 +231,14 @@ impl Resolver { | |||
197 | Some(res) | 231 | Some(res) |
198 | } | 232 | } |
199 | 233 | ||
200 | pub fn resolve_path_in_value_ns<'p>( | 234 | pub fn resolve_path_in_value_ns( |
201 | &self, | 235 | &self, |
202 | db: &impl DefDatabase, | 236 | db: &impl DefDatabase, |
203 | path: &'p Path, | 237 | path: &ModPath, |
204 | ) -> Option<ResolveValueResult> { | 238 | ) -> Option<ResolveValueResult> { |
205 | if path.is_type_relative() { | ||
206 | return None; | ||
207 | } | ||
208 | let n_segments = path.segments.len(); | 239 | let n_segments = path.segments.len(); |
209 | let tmp = name::SELF_PARAM; | 240 | let tmp = name![self]; |
210 | let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name }; | 241 | let first_name = if path.is_self() { &tmp } else { &path.segments.first()? }; |
211 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); | 242 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); |
212 | for scope in self.scopes.iter().rev() { | 243 | for scope in self.scopes.iter().rev() { |
213 | match scope { | 244 | match scope { |
@@ -215,6 +246,7 @@ impl Resolver { | |||
215 | | Scope::ExprScope(_) | 246 | | Scope::ExprScope(_) |
216 | | Scope::GenericParams { .. } | 247 | | Scope::GenericParams { .. } |
217 | | Scope::ImplBlockScope(_) | 248 | | Scope::ImplBlockScope(_) |
249 | | Scope::LocalItemsScope(_) | ||
218 | if skip_to_mod => | 250 | if skip_to_mod => |
219 | { | 251 | { |
220 | continue | 252 | continue |
@@ -233,22 +265,22 @@ impl Resolver { | |||
233 | } | 265 | } |
234 | Scope::ExprScope(_) => continue, | 266 | Scope::ExprScope(_) => continue, |
235 | 267 | ||
236 | Scope::GenericParams { params, .. } if n_segments > 1 => { | 268 | Scope::GenericParams { params, def } if n_segments > 1 => { |
237 | if let Some(param) = params.find_by_name(first_name) { | 269 | if let Some(local_id) = params.find_by_name(first_name) { |
238 | let ty = TypeNs::GenericParam(param.idx); | 270 | let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def }); |
239 | return Some(ResolveValueResult::Partial(ty, 1)); | 271 | return Some(ResolveValueResult::Partial(ty, 1)); |
240 | } | 272 | } |
241 | } | 273 | } |
242 | Scope::GenericParams { .. } => continue, | 274 | Scope::GenericParams { .. } => continue, |
243 | 275 | ||
244 | Scope::ImplBlockScope(impl_) if n_segments > 1 => { | 276 | Scope::ImplBlockScope(impl_) if n_segments > 1 => { |
245 | if first_name == &name::SELF_TYPE { | 277 | if first_name == &name![Self] { |
246 | let ty = TypeNs::SelfType(*impl_); | 278 | let ty = TypeNs::SelfType(*impl_); |
247 | return Some(ResolveValueResult::Partial(ty, 1)); | 279 | return Some(ResolveValueResult::Partial(ty, 1)); |
248 | } | 280 | } |
249 | } | 281 | } |
250 | Scope::AdtScope(adt) if n_segments > 1 => { | 282 | Scope::AdtScope(adt) if n_segments > 1 => { |
251 | if first_name == &name::SELF_TYPE { | 283 | if first_name == &name![Self] { |
252 | let ty = TypeNs::AdtSelfType(*adt); | 284 | let ty = TypeNs::AdtSelfType(*adt); |
253 | return Some(ResolveValueResult::Partial(ty, 1)); | 285 | return Some(ResolveValueResult::Partial(ty, 1)); |
254 | } | 286 | } |
@@ -256,23 +288,15 @@ impl Resolver { | |||
256 | Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue, | 288 | Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue, |
257 | 289 | ||
258 | Scope::ModuleScope(m) => { | 290 | Scope::ModuleScope(m) => { |
259 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | 291 | let (module_def, idx) = m.crate_def_map.resolve_path( |
292 | db, | ||
293 | m.module_id, | ||
294 | &path, | ||
295 | BuiltinShadowMode::Other, | ||
296 | ); | ||
260 | return match idx { | 297 | return match idx { |
261 | None => { | 298 | None => { |
262 | let value = match module_def.take_values()? { | 299 | let value = to_value_ns(module_def)?; |
263 | ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it), | ||
264 | ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it), | ||
265 | ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it), | ||
266 | ModuleDefId::ConstId(it) => ValueNs::ConstId(it), | ||
267 | ModuleDefId::StaticId(it) => ValueNs::StaticId(it), | ||
268 | |||
269 | ModuleDefId::AdtId(AdtId::EnumId(_)) | ||
270 | | ModuleDefId::AdtId(AdtId::UnionId(_)) | ||
271 | | ModuleDefId::TraitId(_) | ||
272 | | ModuleDefId::TypeAliasId(_) | ||
273 | | ModuleDefId::BuiltinType(_) | ||
274 | | ModuleDefId::ModuleId(_) => return None, | ||
275 | }; | ||
276 | Some(ResolveValueResult::ValueNs(value)) | 300 | Some(ResolveValueResult::ValueNs(value)) |
277 | } | 301 | } |
278 | Some(idx) => { | 302 | Some(idx) => { |
@@ -292,15 +316,39 @@ impl Resolver { | |||
292 | } | 316 | } |
293 | }; | 317 | }; |
294 | } | 318 | } |
319 | Scope::LocalItemsScope(body) => { | ||
320 | let def = body.item_scope.get(first_name, BuiltinShadowMode::Other); | ||
321 | if let Some(res) = to_value_ns(def) { | ||
322 | return Some(ResolveValueResult::ValueNs(res)); | ||
323 | } | ||
324 | } | ||
295 | } | 325 | } |
296 | } | 326 | } |
297 | None | 327 | return None; |
328 | |||
329 | fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> { | ||
330 | let res = match per_ns.take_values()? { | ||
331 | ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it), | ||
332 | ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it), | ||
333 | ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it), | ||
334 | ModuleDefId::ConstId(it) => ValueNs::ConstId(it), | ||
335 | ModuleDefId::StaticId(it) => ValueNs::StaticId(it), | ||
336 | |||
337 | ModuleDefId::AdtId(AdtId::EnumId(_)) | ||
338 | | ModuleDefId::AdtId(AdtId::UnionId(_)) | ||
339 | | ModuleDefId::TraitId(_) | ||
340 | | ModuleDefId::TypeAliasId(_) | ||
341 | | ModuleDefId::BuiltinType(_) | ||
342 | | ModuleDefId::ModuleId(_) => return None, | ||
343 | }; | ||
344 | Some(res) | ||
345 | } | ||
298 | } | 346 | } |
299 | 347 | ||
300 | pub fn resolve_path_in_value_ns_fully( | 348 | pub fn resolve_path_in_value_ns_fully( |
301 | &self, | 349 | &self, |
302 | db: &impl DefDatabase, | 350 | db: &impl DefDatabase, |
303 | path: &Path, | 351 | path: &ModPath, |
304 | ) -> Option<ValueNs> { | 352 | ) -> Option<ValueNs> { |
305 | match self.resolve_path_in_value_ns(db, path)? { | 353 | match self.resolve_path_in_value_ns(db, path)? { |
306 | ResolveValueResult::ValueNs(it) => Some(it), | 354 | ResolveValueResult::ValueNs(it) => Some(it), |
@@ -308,9 +356,13 @@ impl Resolver { | |||
308 | } | 356 | } |
309 | } | 357 | } |
310 | 358 | ||
311 | pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { | 359 | pub fn resolve_path_as_macro( |
360 | &self, | ||
361 | db: &impl DefDatabase, | ||
362 | path: &ModPath, | ||
363 | ) -> Option<MacroDefId> { | ||
312 | let (item_map, module) = self.module()?; | 364 | let (item_map, module) = self.module()?; |
313 | item_map.resolve_path(db, module, path).0.take_macros() | 365 | item_map.resolve_path(db, module, &path, BuiltinShadowMode::Other).0.take_macros() |
314 | } | 366 | } |
315 | 367 | ||
316 | pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { | 368 | pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { |
@@ -350,6 +402,7 @@ impl Resolver { | |||
350 | ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { | 402 | ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { |
351 | self.scopes | 403 | self.scopes |
352 | .iter() | 404 | .iter() |
405 | .rev() | ||
353 | .filter_map(|scope| match scope { | 406 | .filter_map(|scope| match scope { |
354 | Scope::GenericParams { params, .. } => Some(params), | 407 | Scope::GenericParams { params, .. } => Some(params), |
355 | _ => None, | 408 | _ => None, |
@@ -358,14 +411,14 @@ impl Resolver { | |||
358 | } | 411 | } |
359 | 412 | ||
360 | pub fn generic_def(&self) -> Option<GenericDefId> { | 413 | pub fn generic_def(&self) -> Option<GenericDefId> { |
361 | self.scopes.iter().find_map(|scope| match scope { | 414 | self.scopes.iter().rev().find_map(|scope| match scope { |
362 | Scope::GenericParams { def, .. } => Some(*def), | 415 | Scope::GenericParams { def, .. } => Some(*def), |
363 | _ => None, | 416 | _ => None, |
364 | }) | 417 | }) |
365 | } | 418 | } |
366 | 419 | ||
367 | pub fn body_owner(&self) -> Option<DefWithBodyId> { | 420 | pub fn body_owner(&self) -> Option<DefWithBodyId> { |
368 | self.scopes.iter().find_map(|scope| match scope { | 421 | self.scopes.iter().rev().find_map(|scope| match scope { |
369 | Scope::ExprScope(it) => Some(it.owner), | 422 | Scope::ExprScope(it) => Some(it.owner), |
370 | _ => None, | 423 | _ => None, |
371 | }) | 424 | }) |
@@ -376,7 +429,7 @@ pub enum ScopeDef { | |||
376 | PerNs(PerNs), | 429 | PerNs(PerNs), |
377 | ImplSelfType(ImplId), | 430 | ImplSelfType(ImplId), |
378 | AdtSelfType(AdtId), | 431 | AdtSelfType(AdtId), |
379 | GenericParam(u32), | 432 | GenericParam(TypeParamId), |
380 | Local(PatId), | 433 | Local(PatId), |
381 | } | 434 | } |
382 | 435 | ||
@@ -391,8 +444,8 @@ impl Scope { | |||
391 | // def: m.module.into(), | 444 | // def: m.module.into(), |
392 | // }), | 445 | // }), |
393 | // ); | 446 | // ); |
394 | m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { | 447 | m.crate_def_map[m.module_id].scope.entries().for_each(|(name, def)| { |
395 | f(name.clone(), ScopeDef::PerNs(res.def)); | 448 | f(name.clone(), ScopeDef::PerNs(def)); |
396 | }); | 449 | }); |
397 | m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { | 450 | m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { |
398 | f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); | 451 | f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); |
@@ -402,21 +455,29 @@ impl Scope { | |||
402 | }); | 455 | }); |
403 | if let Some(prelude) = m.crate_def_map.prelude { | 456 | if let Some(prelude) = m.crate_def_map.prelude { |
404 | let prelude_def_map = db.crate_def_map(prelude.krate); | 457 | let prelude_def_map = db.crate_def_map(prelude.krate); |
405 | prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, res)| { | 458 | prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| { |
406 | f(name.clone(), ScopeDef::PerNs(res.def)); | 459 | f(name.clone(), ScopeDef::PerNs(def)); |
407 | }); | 460 | }); |
408 | } | 461 | } |
409 | } | 462 | } |
410 | Scope::GenericParams { params, .. } => { | 463 | Scope::LocalItemsScope(body) => { |
411 | for param in params.params.iter() { | 464 | body.item_scope.entries_without_primitives().for_each(|(name, def)| { |
412 | f(param.name.clone(), ScopeDef::GenericParam(param.idx)) | 465 | f(name.clone(), ScopeDef::PerNs(def)); |
466 | }) | ||
467 | } | ||
468 | Scope::GenericParams { params, def } => { | ||
469 | for (local_id, param) in params.types.iter() { | ||
470 | f( | ||
471 | param.name.clone(), | ||
472 | ScopeDef::GenericParam(TypeParamId { local_id, parent: *def }), | ||
473 | ) | ||
413 | } | 474 | } |
414 | } | 475 | } |
415 | Scope::ImplBlockScope(i) => { | 476 | Scope::ImplBlockScope(i) => { |
416 | f(name::SELF_TYPE, ScopeDef::ImplSelfType((*i).into())); | 477 | f(name![Self], ScopeDef::ImplSelfType((*i).into())); |
417 | } | 478 | } |
418 | Scope::AdtScope(i) => { | 479 | Scope::AdtScope(i) => { |
419 | f(name::SELF_TYPE, ScopeDef::AdtSelfType((*i).into())); | 480 | f(name![Self], ScopeDef::AdtSelfType((*i).into())); |
420 | } | 481 | } |
421 | Scope::ExprScope(scope) => { | 482 | Scope::ExprScope(scope) => { |
422 | scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { | 483 | scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { |
@@ -439,6 +500,7 @@ pub fn resolver_for_scope( | |||
439 | scope_id: Option<ScopeId>, | 500 | scope_id: Option<ScopeId>, |
440 | ) -> Resolver { | 501 | ) -> Resolver { |
441 | let mut r = owner.resolver(db); | 502 | let mut r = owner.resolver(db); |
503 | r = r.push_local_items_scope(db.body(owner)); | ||
442 | let scopes = db.expr_scopes(owner); | 504 | let scopes = db.expr_scopes(owner); |
443 | let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); | 505 | let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); |
444 | for scope in scope_chain.into_iter().rev() { | 506 | for scope in scope_chain.into_iter().rev() { |
@@ -455,7 +517,7 @@ impl Resolver { | |||
455 | 517 | ||
456 | fn push_generic_params_scope(self, db: &impl DefDatabase, def: GenericDefId) -> Resolver { | 518 | fn push_generic_params_scope(self, db: &impl DefDatabase, def: GenericDefId) -> Resolver { |
457 | let params = db.generic_params(def); | 519 | let params = db.generic_params(def); |
458 | if params.params.is_empty() { | 520 | if params.types.is_empty() { |
459 | self | 521 | self |
460 | } else { | 522 | } else { |
461 | self.push_scope(Scope::GenericParams { def, params }) | 523 | self.push_scope(Scope::GenericParams { def, params }) |
@@ -474,6 +536,10 @@ impl Resolver { | |||
474 | self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) | 536 | self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) |
475 | } | 537 | } |
476 | 538 | ||
539 | fn push_local_items_scope(self, body: Arc<Body>) -> Resolver { | ||
540 | self.push_scope(Scope::LocalItemsScope(body)) | ||
541 | } | ||
542 | |||
477 | fn push_expr_scope( | 543 | fn push_expr_scope( |
478 | self, | 544 | self, |
479 | owner: DefWithBodyId, | 545 | owner: DefWithBodyId, |
@@ -498,7 +564,7 @@ impl HasResolver for ModuleId { | |||
498 | 564 | ||
499 | impl HasResolver for TraitId { | 565 | impl HasResolver for TraitId { |
500 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 566 | fn resolver(self, db: &impl DefDatabase) -> Resolver { |
501 | self.module(db).resolver(db).push_generic_params_scope(db, self.into()) | 567 | self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) |
502 | } | 568 | } |
503 | } | 569 | } |
504 | 570 | ||
@@ -518,16 +584,6 @@ impl HasResolver for FunctionId { | |||
518 | } | 584 | } |
519 | } | 585 | } |
520 | 586 | ||
521 | impl HasResolver for DefWithBodyId { | ||
522 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
523 | match self { | ||
524 | DefWithBodyId::ConstId(c) => c.resolver(db), | ||
525 | DefWithBodyId::FunctionId(f) => f.resolver(db), | ||
526 | DefWithBodyId::StaticId(s) => s.resolver(db), | ||
527 | } | ||
528 | } | ||
529 | } | ||
530 | |||
531 | impl HasResolver for ConstId { | 587 | impl HasResolver for ConstId { |
532 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 588 | fn resolver(self, db: &impl DefDatabase) -> Resolver { |
533 | self.lookup(db).container.resolver(db) | 589 | self.lookup(db).container.resolver(db) |
@@ -546,12 +602,41 @@ impl HasResolver for TypeAliasId { | |||
546 | } | 602 | } |
547 | } | 603 | } |
548 | 604 | ||
605 | impl HasResolver for ImplId { | ||
606 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
607 | self.lookup(db) | ||
608 | .container | ||
609 | .resolver(db) | ||
610 | .push_generic_params_scope(db, self.into()) | ||
611 | .push_impl_block_scope(self) | ||
612 | } | ||
613 | } | ||
614 | |||
615 | impl HasResolver for DefWithBodyId { | ||
616 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
617 | match self { | ||
618 | DefWithBodyId::ConstId(c) => c.resolver(db), | ||
619 | DefWithBodyId::FunctionId(f) => f.resolver(db), | ||
620 | DefWithBodyId::StaticId(s) => s.resolver(db), | ||
621 | } | ||
622 | } | ||
623 | } | ||
624 | |||
549 | impl HasResolver for ContainerId { | 625 | impl HasResolver for ContainerId { |
550 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 626 | fn resolver(self, db: &impl DefDatabase) -> Resolver { |
551 | match self { | 627 | match self { |
552 | ContainerId::TraitId(it) => it.resolver(db), | ||
553 | ContainerId::ImplId(it) => it.resolver(db), | ||
554 | ContainerId::ModuleId(it) => it.resolver(db), | 628 | ContainerId::ModuleId(it) => it.resolver(db), |
629 | ContainerId::DefWithBodyId(it) => it.resolver(db), | ||
630 | } | ||
631 | } | ||
632 | } | ||
633 | |||
634 | impl HasResolver for AssocContainerId { | ||
635 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
636 | match self { | ||
637 | AssocContainerId::ContainerId(it) => it.resolver(db), | ||
638 | AssocContainerId::TraitId(it) => it.resolver(db), | ||
639 | AssocContainerId::ImplId(it) => it.resolver(db), | ||
555 | } | 640 | } |
556 | } | 641 | } |
557 | } | 642 | } |
@@ -570,11 +655,12 @@ impl HasResolver for GenericDefId { | |||
570 | } | 655 | } |
571 | } | 656 | } |
572 | 657 | ||
573 | impl HasResolver for ImplId { | 658 | impl HasResolver for VariantId { |
574 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 659 | fn resolver(self, db: &impl DefDatabase) -> Resolver { |
575 | self.module(db) | 660 | match self { |
576 | .resolver(db) | 661 | VariantId::EnumVariantId(it) => it.parent.resolver(db), |
577 | .push_generic_params_scope(db, self.into()) | 662 | VariantId::StructId(it) => it.resolver(db), |
578 | .push_impl_block_scope(self) | 663 | VariantId::UnionId(it) => it.resolver(db), |
664 | } | ||
579 | } | 665 | } |
580 | } | 666 | } |