aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/resolver.rs
diff options
context:
space:
mode:
authorSeivan Heidari <[email protected]>2019-12-23 14:35:31 +0000
committerSeivan Heidari <[email protected]>2019-12-23 14:35:31 +0000
commitb21d9337d9200e2cfdc90b386591c72c302dc03e (patch)
treef81f5c08f821115cee26fa4d3ceaae88c7807fd5 /crates/ra_hir_def/src/resolver.rs
parent18a0937585b836ec5ed054b9ae48e0156ab6d9ef (diff)
parentce07a2daa9e53aa86a769f8641b14c2878444fbc (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.rs296
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 @@
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use hir_expand::{ 4use hir_expand::{
5 name::{self, Name}, 5 name::{name, Name},
6 MacroDefId, 6 MacroDefId,
7}; 7};
8use ra_db::CrateId; 8use ra_db::CrateId;
@@ -10,20 +10,23 @@ use rustc_hash::FxHashSet;
10 10
11use crate::{ 11use 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)]
26pub struct Resolver { 28pub 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)]
59pub enum TypeNs { 64pub 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
91impl Resolver { 96impl 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
499impl HasResolver for TraitId { 565impl 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
521impl 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
531impl HasResolver for ConstId { 587impl 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
605impl 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
615impl 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
549impl HasResolver for ContainerId { 625impl 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
634impl 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
573impl HasResolver for ImplId { 658impl 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}