diff options
author | Seivan Heidari <[email protected]> | 2019-11-22 00:54:34 +0000 |
---|---|---|
committer | Seivan Heidari <[email protected]> | 2019-11-22 00:54:34 +0000 |
commit | a63a269ec84192114cc1ac7f079e96144ae877a1 (patch) | |
tree | bfa5b8496a958e825423d09f6abbdf5db5c54efa /crates/ra_hir/src/resolve.rs | |
parent | 358a1bcd708c622836723e5201b6de77cc9ff327 (diff) | |
parent | c9273828b3c44fba62d1b989480c287d923839d2 (diff) |
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes
Diffstat (limited to 'crates/ra_hir/src/resolve.rs')
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 588 |
1 files changed, 0 insertions, 588 deletions
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs deleted file mode 100644 index eca8e0596..000000000 --- a/crates/ra_hir/src/resolve.rs +++ /dev/null | |||
@@ -1,588 +0,0 @@ | |||
1 | //! Name resolution. | ||
2 | use std::sync::Arc; | ||
3 | |||
4 | use hir_def::{ | ||
5 | builtin_type::BuiltinType, | ||
6 | nameres::CrateDefMap, | ||
7 | path::{Path, PathKind}, | ||
8 | AdtId, CrateModuleId, ModuleDefId, | ||
9 | }; | ||
10 | use hir_expand::name::{self, Name}; | ||
11 | use rustc_hash::FxHashSet; | ||
12 | |||
13 | use crate::{ | ||
14 | code_model::Crate, | ||
15 | db::{DefDatabase, HirDatabase}, | ||
16 | expr::{ExprScopes, PatId, ScopeId}, | ||
17 | generics::{GenericParams, HasGenericParams}, | ||
18 | Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, | ||
19 | MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, | ||
20 | }; | ||
21 | |||
22 | #[derive(Debug, Clone, Default)] | ||
23 | pub(crate) struct Resolver { | ||
24 | scopes: Vec<Scope>, | ||
25 | } | ||
26 | |||
27 | // FIXME how to store these best | ||
28 | #[derive(Debug, Clone)] | ||
29 | pub(crate) struct ModuleItemMap { | ||
30 | crate_def_map: Arc<CrateDefMap>, | ||
31 | module_id: CrateModuleId, | ||
32 | } | ||
33 | |||
34 | #[derive(Debug, Clone)] | ||
35 | pub(crate) struct ExprScope { | ||
36 | owner: DefWithBody, | ||
37 | expr_scopes: Arc<ExprScopes>, | ||
38 | scope_id: ScopeId, | ||
39 | } | ||
40 | |||
41 | #[derive(Debug, Clone)] | ||
42 | pub(crate) enum Scope { | ||
43 | /// All the items and imported names of a module | ||
44 | ModuleScope(ModuleItemMap), | ||
45 | /// Brings the generic parameters of an item into scope | ||
46 | GenericParams { def: GenericDef, params: Arc<GenericParams> }, | ||
47 | /// Brings `Self` in `impl` block into scope | ||
48 | ImplBlockScope(ImplBlock), | ||
49 | /// Brings `Self` in enum, struct and union definitions into scope | ||
50 | AdtScope(Adt), | ||
51 | /// Local bindings | ||
52 | ExprScope(ExprScope), | ||
53 | } | ||
54 | |||
55 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
56 | pub(crate) enum TypeNs { | ||
57 | SelfType(ImplBlock), | ||
58 | GenericParam(u32), | ||
59 | Adt(Adt), | ||
60 | AdtSelfType(Adt), | ||
61 | EnumVariant(EnumVariant), | ||
62 | TypeAlias(TypeAlias), | ||
63 | BuiltinType(BuiltinType), | ||
64 | Trait(Trait), | ||
65 | // Module belong to type ns, but the resolver is used when all module paths | ||
66 | // are fully resolved. | ||
67 | // Module(Module) | ||
68 | } | ||
69 | |||
70 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
71 | pub(crate) enum ResolveValueResult { | ||
72 | ValueNs(ValueNs), | ||
73 | Partial(TypeNs, usize), | ||
74 | } | ||
75 | |||
76 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
77 | pub(crate) enum ValueNs { | ||
78 | LocalBinding(PatId), | ||
79 | Function(Function), | ||
80 | Const(Const), | ||
81 | Static(Static), | ||
82 | Struct(Struct), | ||
83 | EnumVariant(EnumVariant), | ||
84 | } | ||
85 | |||
86 | impl Resolver { | ||
87 | /// Resolve known trait from std, like `std::futures::Future` | ||
88 | pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option<Trait> { | ||
89 | let res = self.resolve_module_path(db, path).take_types()?; | ||
90 | match res { | ||
91 | ModuleDefId::TraitId(it) => Some(it.into()), | ||
92 | _ => None, | ||
93 | } | ||
94 | } | ||
95 | |||
96 | /// Resolve known struct from std, like `std::boxed::Box` | ||
97 | pub(crate) fn resolve_known_struct( | ||
98 | &self, | ||
99 | db: &impl HirDatabase, | ||
100 | path: &Path, | ||
101 | ) -> Option<Struct> { | ||
102 | let res = self.resolve_module_path(db, path).take_types()?; | ||
103 | match res { | ||
104 | ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it.into()), | ||
105 | _ => None, | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /// Resolve known enum from std, like `std::result::Result` | ||
110 | pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option<Enum> { | ||
111 | let res = self.resolve_module_path(db, path).take_types()?; | ||
112 | match res { | ||
113 | ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it.into()), | ||
114 | _ => None, | ||
115 | } | ||
116 | } | ||
117 | |||
118 | /// pub only for source-binder | ||
119 | pub(crate) fn resolve_module_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs { | ||
120 | let (item_map, module) = match self.module() { | ||
121 | Some(it) => it, | ||
122 | None => return PerNs::none(), | ||
123 | }; | ||
124 | let (module_res, segment_index) = item_map.resolve_path(db, module, path); | ||
125 | if segment_index.is_some() { | ||
126 | return PerNs::none(); | ||
127 | } | ||
128 | module_res | ||
129 | } | ||
130 | |||
131 | pub(crate) fn resolve_path_in_type_ns( | ||
132 | &self, | ||
133 | db: &impl HirDatabase, | ||
134 | path: &Path, | ||
135 | ) -> Option<(TypeNs, Option<usize>)> { | ||
136 | if path.is_type_relative() { | ||
137 | return None; | ||
138 | } | ||
139 | let first_name = &path.segments.first()?.name; | ||
140 | let skip_to_mod = path.kind != PathKind::Plain; | ||
141 | for scope in self.scopes.iter().rev() { | ||
142 | match scope { | ||
143 | Scope::ExprScope(_) => continue, | ||
144 | Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue, | ||
145 | |||
146 | Scope::GenericParams { params, .. } => { | ||
147 | if let Some(param) = params.find_by_name(first_name) { | ||
148 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | ||
149 | return Some((TypeNs::GenericParam(param.idx), idx)); | ||
150 | } | ||
151 | } | ||
152 | Scope::ImplBlockScope(impl_) => { | ||
153 | if first_name == &name::SELF_TYPE { | ||
154 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | ||
155 | return Some((TypeNs::SelfType(*impl_), idx)); | ||
156 | } | ||
157 | } | ||
158 | Scope::AdtScope(adt) => { | ||
159 | if first_name == &name::SELF_TYPE { | ||
160 | let idx = if path.segments.len() == 1 { None } else { Some(1) }; | ||
161 | return Some((TypeNs::AdtSelfType(*adt), idx)); | ||
162 | } | ||
163 | } | ||
164 | Scope::ModuleScope(m) => { | ||
165 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | ||
166 | let res = match module_def.take_types()? { | ||
167 | ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), | ||
168 | ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariant(it.into()), | ||
169 | |||
170 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), | ||
171 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | ||
172 | |||
173 | ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), | ||
174 | |||
175 | ModuleDefId::FunctionId(_) | ||
176 | | ModuleDefId::ConstId(_) | ||
177 | | ModuleDefId::StaticId(_) | ||
178 | | ModuleDefId::ModuleId(_) => return None, | ||
179 | }; | ||
180 | return Some((res, idx)); | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | None | ||
185 | } | ||
186 | |||
187 | pub(crate) fn resolve_path_in_type_ns_fully( | ||
188 | &self, | ||
189 | db: &impl HirDatabase, | ||
190 | path: &Path, | ||
191 | ) -> Option<TypeNs> { | ||
192 | let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; | ||
193 | if unresolved.is_some() { | ||
194 | return None; | ||
195 | } | ||
196 | Some(res) | ||
197 | } | ||
198 | |||
199 | pub(crate) fn resolve_path_in_value_ns<'p>( | ||
200 | &self, | ||
201 | db: &impl HirDatabase, | ||
202 | path: &'p Path, | ||
203 | ) -> Option<ResolveValueResult> { | ||
204 | if path.is_type_relative() { | ||
205 | return None; | ||
206 | } | ||
207 | let n_segments = path.segments.len(); | ||
208 | let tmp = name::SELF_PARAM; | ||
209 | let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name }; | ||
210 | let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); | ||
211 | for scope in self.scopes.iter().rev() { | ||
212 | match scope { | ||
213 | Scope::AdtScope(_) | ||
214 | | Scope::ExprScope(_) | ||
215 | | Scope::GenericParams { .. } | ||
216 | | Scope::ImplBlockScope(_) | ||
217 | if skip_to_mod => | ||
218 | { | ||
219 | continue | ||
220 | } | ||
221 | |||
222 | Scope::ExprScope(scope) if n_segments <= 1 => { | ||
223 | let entry = scope | ||
224 | .expr_scopes | ||
225 | .entries(scope.scope_id) | ||
226 | .iter() | ||
227 | .find(|entry| entry.name() == first_name); | ||
228 | |||
229 | if let Some(e) = entry { | ||
230 | return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(e.pat()))); | ||
231 | } | ||
232 | } | ||
233 | Scope::ExprScope(_) => continue, | ||
234 | |||
235 | Scope::GenericParams { params, .. } if n_segments > 1 => { | ||
236 | if let Some(param) = params.find_by_name(first_name) { | ||
237 | let ty = TypeNs::GenericParam(param.idx); | ||
238 | return Some(ResolveValueResult::Partial(ty, 1)); | ||
239 | } | ||
240 | } | ||
241 | Scope::GenericParams { .. } => continue, | ||
242 | |||
243 | Scope::ImplBlockScope(impl_) if n_segments > 1 => { | ||
244 | if first_name == &name::SELF_TYPE { | ||
245 | let ty = TypeNs::SelfType(*impl_); | ||
246 | return Some(ResolveValueResult::Partial(ty, 1)); | ||
247 | } | ||
248 | } | ||
249 | Scope::AdtScope(adt) if n_segments > 1 => { | ||
250 | if first_name == &name::SELF_TYPE { | ||
251 | let ty = TypeNs::AdtSelfType(*adt); | ||
252 | return Some(ResolveValueResult::Partial(ty, 1)); | ||
253 | } | ||
254 | } | ||
255 | Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue, | ||
256 | |||
257 | Scope::ModuleScope(m) => { | ||
258 | let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); | ||
259 | return match idx { | ||
260 | None => { | ||
261 | let value = match module_def.take_values()? { | ||
262 | ModuleDefId::FunctionId(it) => ValueNs::Function(it.into()), | ||
263 | ModuleDefId::AdtId(AdtId::StructId(it)) => { | ||
264 | ValueNs::Struct(it.into()) | ||
265 | } | ||
266 | ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariant(it.into()), | ||
267 | ModuleDefId::ConstId(it) => ValueNs::Const(it.into()), | ||
268 | ModuleDefId::StaticId(it) => ValueNs::Static(it.into()), | ||
269 | |||
270 | ModuleDefId::AdtId(AdtId::EnumId(_)) | ||
271 | | ModuleDefId::AdtId(AdtId::UnionId(_)) | ||
272 | | ModuleDefId::TraitId(_) | ||
273 | | ModuleDefId::TypeAliasId(_) | ||
274 | | ModuleDefId::BuiltinType(_) | ||
275 | | ModuleDefId::ModuleId(_) => return None, | ||
276 | }; | ||
277 | Some(ResolveValueResult::ValueNs(value)) | ||
278 | } | ||
279 | Some(idx) => { | ||
280 | let ty = match module_def.take_types()? { | ||
281 | ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), | ||
282 | ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), | ||
283 | ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), | ||
284 | ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), | ||
285 | |||
286 | ModuleDefId::ModuleId(_) | ||
287 | | ModuleDefId::FunctionId(_) | ||
288 | | ModuleDefId::EnumVariantId(_) | ||
289 | | ModuleDefId::ConstId(_) | ||
290 | | ModuleDefId::StaticId(_) => return None, | ||
291 | }; | ||
292 | Some(ResolveValueResult::Partial(ty, idx)) | ||
293 | } | ||
294 | }; | ||
295 | } | ||
296 | } | ||
297 | } | ||
298 | None | ||
299 | } | ||
300 | |||
301 | pub(crate) fn resolve_path_in_value_ns_fully( | ||
302 | &self, | ||
303 | db: &impl HirDatabase, | ||
304 | path: &Path, | ||
305 | ) -> Option<ValueNs> { | ||
306 | match self.resolve_path_in_value_ns(db, path)? { | ||
307 | ResolveValueResult::ValueNs(it) => Some(it), | ||
308 | ResolveValueResult::Partial(..) => None, | ||
309 | } | ||
310 | } | ||
311 | |||
312 | pub(crate) fn resolve_path_as_macro( | ||
313 | &self, | ||
314 | db: &impl DefDatabase, | ||
315 | path: &Path, | ||
316 | ) -> Option<MacroDef> { | ||
317 | let (item_map, module) = self.module()?; | ||
318 | item_map.resolve_path(db, module, path).0.get_macros().map(MacroDef::from) | ||
319 | } | ||
320 | |||
321 | pub(crate) fn process_all_names( | ||
322 | &self, | ||
323 | db: &impl HirDatabase, | ||
324 | f: &mut dyn FnMut(Name, ScopeDef), | ||
325 | ) { | ||
326 | for scope in self.scopes.iter().rev() { | ||
327 | scope.process_names(db, f); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet<Trait> { | ||
332 | let mut traits = FxHashSet::default(); | ||
333 | for scope in &self.scopes { | ||
334 | if let Scope::ModuleScope(m) = scope { | ||
335 | if let Some(prelude) = m.crate_def_map.prelude() { | ||
336 | let prelude_def_map = db.crate_def_map(prelude.krate); | ||
337 | traits | ||
338 | .extend(prelude_def_map[prelude.module_id].scope.traits().map(Trait::from)); | ||
339 | } | ||
340 | traits.extend(m.crate_def_map[m.module_id].scope.traits().map(Trait::from)); | ||
341 | } | ||
342 | } | ||
343 | traits | ||
344 | } | ||
345 | |||
346 | fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { | ||
347 | self.scopes.iter().rev().find_map(|scope| match scope { | ||
348 | Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)), | ||
349 | |||
350 | _ => None, | ||
351 | }) | ||
352 | } | ||
353 | |||
354 | pub(crate) fn krate(&self) -> Option<Crate> { | ||
355 | self.module().map(|t| Crate { crate_id: t.0.krate() }) | ||
356 | } | ||
357 | |||
358 | pub(crate) fn where_predicates_in_scope<'a>( | ||
359 | &'a self, | ||
360 | ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a { | ||
361 | self.scopes | ||
362 | .iter() | ||
363 | .filter_map(|scope| match scope { | ||
364 | Scope::GenericParams { params, .. } => Some(params), | ||
365 | _ => None, | ||
366 | }) | ||
367 | .flat_map(|params| params.where_predicates.iter()) | ||
368 | } | ||
369 | |||
370 | pub(crate) fn generic_def(&self) -> Option<crate::generics::GenericDef> { | ||
371 | self.scopes.iter().find_map(|scope| match scope { | ||
372 | Scope::GenericParams { def, .. } => Some(*def), | ||
373 | _ => None, | ||
374 | }) | ||
375 | } | ||
376 | } | ||
377 | |||
378 | impl Resolver { | ||
379 | pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver { | ||
380 | self.scopes.push(scope); | ||
381 | self | ||
382 | } | ||
383 | |||
384 | pub(crate) fn push_generic_params_scope( | ||
385 | self, | ||
386 | db: &impl DefDatabase, | ||
387 | def: GenericDef, | ||
388 | ) -> Resolver { | ||
389 | let params = def.generic_params(db); | ||
390 | if params.params.is_empty() { | ||
391 | self | ||
392 | } else { | ||
393 | self.push_scope(Scope::GenericParams { def, params }) | ||
394 | } | ||
395 | } | ||
396 | |||
397 | pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { | ||
398 | self.push_scope(Scope::ImplBlockScope(impl_block)) | ||
399 | } | ||
400 | |||
401 | pub(crate) fn push_module_scope( | ||
402 | self, | ||
403 | crate_def_map: Arc<CrateDefMap>, | ||
404 | module_id: CrateModuleId, | ||
405 | ) -> Resolver { | ||
406 | self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) | ||
407 | } | ||
408 | |||
409 | pub(crate) fn push_expr_scope( | ||
410 | self, | ||
411 | owner: DefWithBody, | ||
412 | expr_scopes: Arc<ExprScopes>, | ||
413 | scope_id: ScopeId, | ||
414 | ) -> Resolver { | ||
415 | self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })) | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /// For IDE only | ||
420 | pub enum ScopeDef { | ||
421 | ModuleDef(ModuleDef), | ||
422 | MacroDef(MacroDef), | ||
423 | GenericParam(u32), | ||
424 | ImplSelfType(ImplBlock), | ||
425 | AdtSelfType(Adt), | ||
426 | Local(Local), | ||
427 | Unknown, | ||
428 | } | ||
429 | |||
430 | impl From<PerNs> for ScopeDef { | ||
431 | fn from(def: PerNs) -> Self { | ||
432 | def.take_types() | ||
433 | .or_else(|| def.take_values()) | ||
434 | .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) | ||
435 | .or_else(|| { | ||
436 | def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) | ||
437 | }) | ||
438 | .unwrap_or(ScopeDef::Unknown) | ||
439 | } | ||
440 | } | ||
441 | |||
442 | impl Scope { | ||
443 | fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { | ||
444 | match self { | ||
445 | Scope::ModuleScope(m) => { | ||
446 | // FIXME: should we provide `self` here? | ||
447 | // f( | ||
448 | // Name::self_param(), | ||
449 | // PerNs::types(Resolution::Def { | ||
450 | // def: m.module.into(), | ||
451 | // }), | ||
452 | // ); | ||
453 | m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { | ||
454 | f(name.clone(), res.def.into()); | ||
455 | }); | ||
456 | m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { | ||
457 | f(name.clone(), ScopeDef::MacroDef(macro_.into())); | ||
458 | }); | ||
459 | m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| { | ||
460 | f(name.clone(), ScopeDef::ModuleDef(def.into())); | ||
461 | }); | ||
462 | if let Some(prelude) = m.crate_def_map.prelude() { | ||
463 | let prelude_def_map = db.crate_def_map(prelude.krate); | ||
464 | prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { | ||
465 | f(name.clone(), res.def.into()); | ||
466 | }); | ||
467 | } | ||
468 | } | ||
469 | Scope::GenericParams { params, .. } => { | ||
470 | for param in params.params.iter() { | ||
471 | f(param.name.clone(), ScopeDef::GenericParam(param.idx)) | ||
472 | } | ||
473 | } | ||
474 | Scope::ImplBlockScope(i) => { | ||
475 | f(name::SELF_TYPE, ScopeDef::ImplSelfType(*i)); | ||
476 | } | ||
477 | Scope::AdtScope(i) => { | ||
478 | f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i)); | ||
479 | } | ||
480 | Scope::ExprScope(scope) => { | ||
481 | scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { | ||
482 | let local = Local { parent: scope.owner, pat_id: e.pat() }; | ||
483 | f(e.name().clone(), ScopeDef::Local(local)); | ||
484 | }); | ||
485 | } | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | |||
490 | pub(crate) trait HasResolver { | ||
491 | /// Builds a resolver for type references inside this def. | ||
492 | fn resolver(self, db: &impl DefDatabase) -> Resolver; | ||
493 | } | ||
494 | |||
495 | impl HasResolver for Module { | ||
496 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
497 | let def_map = db.crate_def_map(self.id.krate); | ||
498 | Resolver::default().push_module_scope(def_map, self.id.module_id) | ||
499 | } | ||
500 | } | ||
501 | |||
502 | impl HasResolver for Trait { | ||
503 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
504 | self.module(db).resolver(db).push_generic_params_scope(db, self.into()) | ||
505 | } | ||
506 | } | ||
507 | |||
508 | impl<T: Into<Adt>> HasResolver for T { | ||
509 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
510 | let def = self.into(); | ||
511 | def.module(db) | ||
512 | .resolver(db) | ||
513 | .push_generic_params_scope(db, def.into()) | ||
514 | .push_scope(Scope::AdtScope(def)) | ||
515 | } | ||
516 | } | ||
517 | |||
518 | impl HasResolver for Function { | ||
519 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
520 | self.container(db) | ||
521 | .map(|c| c.resolver(db)) | ||
522 | .unwrap_or_else(|| self.module(db).resolver(db)) | ||
523 | .push_generic_params_scope(db, self.into()) | ||
524 | } | ||
525 | } | ||
526 | |||
527 | impl HasResolver for DefWithBody { | ||
528 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
529 | match self { | ||
530 | DefWithBody::Const(c) => c.resolver(db), | ||
531 | DefWithBody::Function(f) => f.resolver(db), | ||
532 | DefWithBody::Static(s) => s.resolver(db), | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | |||
537 | impl HasResolver for Const { | ||
538 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
539 | self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db)) | ||
540 | } | ||
541 | } | ||
542 | |||
543 | impl HasResolver for Static { | ||
544 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
545 | self.module(db).resolver(db) | ||
546 | } | ||
547 | } | ||
548 | |||
549 | impl HasResolver for TypeAlias { | ||
550 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
551 | self.container(db) | ||
552 | .map(|ib| ib.resolver(db)) | ||
553 | .unwrap_or_else(|| self.module(db).resolver(db)) | ||
554 | .push_generic_params_scope(db, self.into()) | ||
555 | } | ||
556 | } | ||
557 | |||
558 | impl HasResolver for Container { | ||
559 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
560 | match self { | ||
561 | Container::Trait(trait_) => trait_.resolver(db), | ||
562 | Container::ImplBlock(impl_block) => impl_block.resolver(db), | ||
563 | } | ||
564 | } | ||
565 | } | ||
566 | |||
567 | impl HasResolver for GenericDef { | ||
568 | fn resolver(self, db: &impl DefDatabase) -> crate::Resolver { | ||
569 | match self { | ||
570 | GenericDef::Function(inner) => inner.resolver(db), | ||
571 | GenericDef::Adt(adt) => adt.resolver(db), | ||
572 | GenericDef::Trait(inner) => inner.resolver(db), | ||
573 | GenericDef::TypeAlias(inner) => inner.resolver(db), | ||
574 | GenericDef::ImplBlock(inner) => inner.resolver(db), | ||
575 | GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), | ||
576 | GenericDef::Const(inner) => inner.resolver(db), | ||
577 | } | ||
578 | } | ||
579 | } | ||
580 | |||
581 | impl HasResolver for ImplBlock { | ||
582 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | ||
583 | self.module(db) | ||
584 | .resolver(db) | ||
585 | .push_generic_params_scope(db, self.into()) | ||
586 | .push_impl_block_scope(self) | ||
587 | } | ||
588 | } | ||