]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/resolver.rs
Merge remote-tracking branch 'upstream/master' into 503-hover-doc-links
[rust.git] / crates / hir_def / src / resolver.rs
1 //! Name resolution façade.
2 use std::sync::Arc;
3
4 use base_db::CrateId;
5 use hir_expand::{
6     name::{name, Name},
7     MacroDefId,
8 };
9 use rustc_hash::FxHashSet;
10
11 use crate::{
12     body::scope::{ExprScopes, ScopeId},
13     body::Body,
14     builtin_type::BuiltinType,
15     db::DefDatabase,
16     expr::{ExprId, PatId},
17     generics::GenericParams,
18     item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
19     nameres::CrateDefMap,
20     path::{ModPath, PathKind},
21     per_ns::PerNs,
22     visibility::{RawVisibility, Visibility},
23     AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
24     FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
25     StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
26 };
27
28 #[derive(Debug, Clone, Default)]
29 pub struct Resolver {
30     // FIXME: all usages generally call `.rev`, so maybe reverse once in consturciton?
31     scopes: Vec<Scope>,
32 }
33
34 // FIXME how to store these best
35 #[derive(Debug, Clone)]
36 struct ModuleItemMap {
37     crate_def_map: Arc<CrateDefMap>,
38     module_id: LocalModuleId,
39 }
40
41 #[derive(Debug, Clone)]
42 struct ExprScope {
43     owner: DefWithBodyId,
44     expr_scopes: Arc<ExprScopes>,
45     scope_id: ScopeId,
46 }
47
48 #[derive(Debug, Clone)]
49 enum Scope {
50     /// All the items and imported names of a module
51     ModuleScope(ModuleItemMap),
52     /// Brings the generic parameters of an item into scope
53     GenericParams { def: GenericDefId, params: Arc<GenericParams> },
54     /// Brings `Self` in `impl` block into scope
55     ImplDefScope(ImplId),
56     /// Brings `Self` in enum, struct and union definitions into scope
57     AdtScope(AdtId),
58     /// Local bindings
59     ExprScope(ExprScope),
60     /// Temporary hack to support local items.
61     LocalItemsScope(Arc<Body>),
62 }
63
64 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
65 pub enum TypeNs {
66     SelfType(ImplId),
67     GenericParam(TypeParamId),
68     AdtId(AdtId),
69     AdtSelfType(AdtId),
70     // Yup, enum variants are added to the types ns, but any usage of variant as
71     // type is an error.
72     EnumVariantId(EnumVariantId),
73     TypeAliasId(TypeAliasId),
74     BuiltinType(BuiltinType),
75     TraitId(TraitId),
76     // Module belong to type ns, but the resolver is used when all module paths
77     // are fully resolved.
78     // ModuleId(ModuleId)
79 }
80
81 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
82 pub enum ResolveValueResult {
83     ValueNs(ValueNs),
84     Partial(TypeNs, usize),
85 }
86
87 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
88 pub enum ValueNs {
89     ImplSelf(ImplId),
90     LocalBinding(PatId),
91     FunctionId(FunctionId),
92     ConstId(ConstId),
93     StaticId(StaticId),
94     StructId(StructId),
95     EnumVariantId(EnumVariantId),
96 }
97
98 impl Resolver {
99     /// Resolve known trait from std, like `std::futures::Future`
100     pub fn resolve_known_trait(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<TraitId> {
101         let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
102         match res {
103             ModuleDefId::TraitId(it) => Some(it),
104             _ => None,
105         }
106     }
107
108     /// Resolve known struct from std, like `std::boxed::Box`
109     pub fn resolve_known_struct(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<StructId> {
110         let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
111         match res {
112             ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it),
113             _ => None,
114         }
115     }
116
117     /// Resolve known enum from std, like `std::result::Result`
118     pub fn resolve_known_enum(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<EnumId> {
119         let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
120         match res {
121             ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it),
122             _ => None,
123         }
124     }
125
126     fn resolve_module_path(
127         &self,
128         db: &dyn DefDatabase,
129         path: &ModPath,
130         shadow: BuiltinShadowMode,
131     ) -> PerNs {
132         let (item_map, module) = match self.module_scope() {
133             Some(it) => it,
134             None => return PerNs::none(),
135         };
136         let (module_res, segment_index) = item_map.resolve_path(db, module, &path, shadow);
137         if segment_index.is_some() {
138             return PerNs::none();
139         }
140         module_res
141     }
142
143     pub fn resolve_module_path_in_items(&self, db: &dyn DefDatabase, path: &ModPath) -> PerNs {
144         self.resolve_module_path(db, path, BuiltinShadowMode::Module)
145     }
146
147     pub fn resolve_path_in_type_ns(
148         &self,
149         db: &dyn DefDatabase,
150         path: &ModPath,
151     ) -> Option<(TypeNs, Option<usize>)> {
152         let first_name = path.segments.first()?;
153         let skip_to_mod = path.kind != PathKind::Plain;
154         for scope in self.scopes.iter().rev() {
155             match scope {
156                 Scope::ExprScope(_) => continue,
157                 Scope::GenericParams { .. }
158                 | Scope::ImplDefScope(_)
159                 | Scope::LocalItemsScope(_)
160                     if skip_to_mod =>
161                 {
162                     continue
163                 }
164
165                 Scope::GenericParams { params, def } => {
166                     if let Some(local_id) = params.find_by_name(first_name) {
167                         let idx = if path.segments.len() == 1 { None } else { Some(1) };
168                         return Some((
169                             TypeNs::GenericParam(TypeParamId { local_id, parent: *def }),
170                             idx,
171                         ));
172                     }
173                 }
174                 Scope::ImplDefScope(impl_) => {
175                     if first_name == &name![Self] {
176                         let idx = if path.segments.len() == 1 { None } else { Some(1) };
177                         return Some((TypeNs::SelfType(*impl_), idx));
178                     }
179                 }
180                 Scope::AdtScope(adt) => {
181                     if first_name == &name![Self] {
182                         let idx = if path.segments.len() == 1 { None } else { Some(1) };
183                         return Some((TypeNs::AdtSelfType(*adt), idx));
184                     }
185                 }
186                 Scope::ModuleScope(m) => {
187                     let (module_def, idx) = m.crate_def_map.resolve_path(
188                         db,
189                         m.module_id,
190                         &path,
191                         BuiltinShadowMode::Other,
192                     );
193                     let res = to_type_ns(module_def)?;
194                     return Some((res, idx));
195                 }
196                 Scope::LocalItemsScope(body) => {
197                     let def = body.item_scope.get(first_name);
198                     if let Some(res) = to_type_ns(def) {
199                         return Some((res, None));
200                     }
201                 }
202             }
203         }
204         return None;
205         fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
206             let res = match per_ns.take_types()? {
207                 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
208                 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
209
210                 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
211                 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
212
213                 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
214
215                 ModuleDefId::FunctionId(_)
216                 | ModuleDefId::ConstId(_)
217                 | ModuleDefId::StaticId(_)
218                 | ModuleDefId::ModuleId(_) => return None,
219             };
220             Some(res)
221         }
222     }
223
224     pub fn resolve_path_in_type_ns_fully(
225         &self,
226         db: &dyn DefDatabase,
227         path: &ModPath,
228     ) -> Option<TypeNs> {
229         let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
230         if unresolved.is_some() {
231             return None;
232         }
233         Some(res)
234     }
235
236     pub fn resolve_visibility(
237         &self,
238         db: &dyn DefDatabase,
239         visibility: &RawVisibility,
240     ) -> Option<Visibility> {
241         match visibility {
242             RawVisibility::Module(_) => {
243                 let (item_map, module) = match self.module_scope() {
244                     Some(it) => it,
245                     None => return None,
246                 };
247                 item_map.resolve_visibility(db, module, visibility)
248             }
249             RawVisibility::Public => Some(Visibility::Public),
250         }
251     }
252
253     pub fn resolve_path_in_value_ns(
254         &self,
255         db: &dyn DefDatabase,
256         path: &ModPath,
257     ) -> Option<ResolveValueResult> {
258         let n_segments = path.segments.len();
259         let tmp = name![self];
260         let first_name = if path.is_self() { &tmp } else { &path.segments.first()? };
261         let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
262         for scope in self.scopes.iter().rev() {
263             match scope {
264                 Scope::AdtScope(_)
265                 | Scope::ExprScope(_)
266                 | Scope::GenericParams { .. }
267                 | Scope::ImplDefScope(_)
268                 | Scope::LocalItemsScope(_)
269                     if skip_to_mod =>
270                 {
271                     continue
272                 }
273
274                 Scope::ExprScope(scope) if n_segments <= 1 => {
275                     let entry = scope
276                         .expr_scopes
277                         .entries(scope.scope_id)
278                         .iter()
279                         .find(|entry| entry.name() == first_name);
280
281                     if let Some(e) = entry {
282                         return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(e.pat())));
283                     }
284                 }
285                 Scope::ExprScope(_) => continue,
286
287                 Scope::GenericParams { params, def } if n_segments > 1 => {
288                     if let Some(local_id) = params.find_by_name(first_name) {
289                         let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def });
290                         return Some(ResolveValueResult::Partial(ty, 1));
291                     }
292                 }
293                 Scope::GenericParams { .. } => continue,
294
295                 Scope::ImplDefScope(impl_) => {
296                     if first_name == &name![Self] {
297                         if n_segments > 1 {
298                             let ty = TypeNs::SelfType(*impl_);
299                             return Some(ResolveValueResult::Partial(ty, 1));
300                         } else {
301                             return Some(ResolveValueResult::ValueNs(ValueNs::ImplSelf(*impl_)));
302                         }
303                     }
304                 }
305                 Scope::AdtScope(adt) => {
306                     if n_segments == 1 {
307                         // bare `Self` doesn't work in the value namespace in a struct/enum definition
308                         continue;
309                     }
310                     if first_name == &name![Self] {
311                         let ty = TypeNs::AdtSelfType(*adt);
312                         return Some(ResolveValueResult::Partial(ty, 1));
313                     }
314                 }
315
316                 Scope::ModuleScope(m) => {
317                     let (module_def, idx) = m.crate_def_map.resolve_path(
318                         db,
319                         m.module_id,
320                         &path,
321                         BuiltinShadowMode::Other,
322                     );
323                     return match idx {
324                         None => {
325                             let value = to_value_ns(module_def)?;
326                             Some(ResolveValueResult::ValueNs(value))
327                         }
328                         Some(idx) => {
329                             let ty = match module_def.take_types()? {
330                                 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
331                                 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
332                                 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
333                                 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
334
335                                 ModuleDefId::ModuleId(_)
336                                 | ModuleDefId::FunctionId(_)
337                                 | ModuleDefId::EnumVariantId(_)
338                                 | ModuleDefId::ConstId(_)
339                                 | ModuleDefId::StaticId(_) => return None,
340                             };
341                             Some(ResolveValueResult::Partial(ty, idx))
342                         }
343                     };
344                 }
345                 Scope::LocalItemsScope(body) => {
346                     // we don't bother looking in the builtin scope here because there are no builtin values
347                     let def = to_value_ns(body.item_scope.get(first_name));
348
349                     if let Some(res) = def {
350                         return Some(ResolveValueResult::ValueNs(res));
351                     }
352                 }
353             }
354         }
355         return None;
356
357         fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
358             let res = match per_ns.take_values()? {
359                 ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
360                 ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
361                 ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
362                 ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
363                 ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
364
365                 ModuleDefId::AdtId(AdtId::EnumId(_))
366                 | ModuleDefId::AdtId(AdtId::UnionId(_))
367                 | ModuleDefId::TraitId(_)
368                 | ModuleDefId::TypeAliasId(_)
369                 | ModuleDefId::BuiltinType(_)
370                 | ModuleDefId::ModuleId(_) => return None,
371             };
372             Some(res)
373         }
374     }
375
376     pub fn resolve_path_in_value_ns_fully(
377         &self,
378         db: &dyn DefDatabase,
379         path: &ModPath,
380     ) -> Option<ValueNs> {
381         match self.resolve_path_in_value_ns(db, path)? {
382             ResolveValueResult::ValueNs(it) => Some(it),
383             ResolveValueResult::Partial(..) => None,
384         }
385     }
386
387     pub fn resolve_path_as_macro(
388         &self,
389         db: &dyn DefDatabase,
390         path: &ModPath,
391     ) -> Option<MacroDefId> {
392         // Search item scope legacy macro first
393         if let Some(def) = self.resolve_local_macro_def(path) {
394             return Some(def);
395         }
396
397         let (item_map, module) = self.module_scope()?;
398         item_map.resolve_path(db, module, &path, BuiltinShadowMode::Other).0.take_macros()
399     }
400
401     pub fn process_all_names(&self, db: &dyn DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
402         for scope in self.scopes.iter().rev() {
403             scope.process_names(db, f);
404         }
405     }
406
407     pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
408         let mut traits = FxHashSet::default();
409         for scope in &self.scopes {
410             if let Scope::ModuleScope(m) = scope {
411                 if let Some(prelude) = m.crate_def_map.prelude {
412                     let prelude_def_map = db.crate_def_map(prelude.krate);
413                     traits.extend(prelude_def_map[prelude.local_id].scope.traits());
414                 }
415                 traits.extend(m.crate_def_map[m.module_id].scope.traits());
416             }
417         }
418         traits
419     }
420
421     fn module_scope(&self) -> Option<(&CrateDefMap, LocalModuleId)> {
422         self.scopes.iter().rev().find_map(|scope| match scope {
423             Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)),
424
425             _ => None,
426         })
427     }
428
429     fn resolve_local_macro_def(&self, path: &ModPath) -> Option<MacroDefId> {
430         let name = path.as_ident()?;
431         self.scopes.iter().rev().find_map(|scope| {
432             if let Scope::LocalItemsScope(body) = scope {
433                 return body.item_scope.get_legacy_macro(name);
434             }
435             None
436         })
437     }
438
439     pub fn module(&self) -> Option<ModuleId> {
440         let (def_map, local_id) = self.module_scope()?;
441         Some(ModuleId { krate: def_map.krate, local_id })
442     }
443
444     pub fn krate(&self) -> Option<CrateId> {
445         self.module_scope().map(|t| t.0.krate)
446     }
447
448     pub fn where_predicates_in_scope<'a>(
449         &'a self,
450     ) -> impl Iterator<Item = &'a crate::generics::WherePredicate> + 'a {
451         self.scopes
452             .iter()
453             .rev()
454             .filter_map(|scope| match scope {
455                 Scope::GenericParams { params, .. } => Some(params),
456                 _ => None,
457             })
458             .flat_map(|params| params.where_predicates.iter())
459     }
460
461     pub fn generic_def(&self) -> Option<GenericDefId> {
462         self.scopes.iter().rev().find_map(|scope| match scope {
463             Scope::GenericParams { def, .. } => Some(*def),
464             _ => None,
465         })
466     }
467
468     pub fn body_owner(&self) -> Option<DefWithBodyId> {
469         self.scopes.iter().rev().find_map(|scope| match scope {
470             Scope::ExprScope(it) => Some(it.owner),
471             _ => None,
472         })
473     }
474 }
475
476 pub enum ScopeDef {
477     PerNs(PerNs),
478     ImplSelfType(ImplId),
479     AdtSelfType(AdtId),
480     GenericParam(TypeParamId),
481     Local(PatId),
482 }
483
484 impl Scope {
485     fn process_names(&self, db: &dyn DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
486         match self {
487             Scope::ModuleScope(m) => {
488                 // FIXME: should we provide `self` here?
489                 // f(
490                 //     Name::self_param(),
491                 //     PerNs::types(Resolution::Def {
492                 //         def: m.module.into(),
493                 //     }),
494                 // );
495                 m.crate_def_map[m.module_id].scope.entries().for_each(|(name, def)| {
496                     f(name.clone(), ScopeDef::PerNs(def));
497                 });
498                 m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| {
499                     f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_, Visibility::Public)));
500                 });
501                 m.crate_def_map.extern_prelude.iter().for_each(|(name, &def)| {
502                     f(name.clone(), ScopeDef::PerNs(PerNs::types(def, Visibility::Public)));
503                 });
504                 BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
505                     f(name.clone(), ScopeDef::PerNs(def));
506                 });
507                 if let Some(prelude) = m.crate_def_map.prelude {
508                     let prelude_def_map = db.crate_def_map(prelude.krate);
509                     prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| {
510                         f(name.clone(), ScopeDef::PerNs(def));
511                     });
512                 }
513             }
514             Scope::LocalItemsScope(body) => body.item_scope.entries().for_each(|(name, def)| {
515                 f(name.clone(), ScopeDef::PerNs(def));
516             }),
517             Scope::GenericParams { params, def } => {
518                 for (local_id, param) in params.types.iter() {
519                     if let Some(name) = &param.name {
520                         f(
521                             name.clone(),
522                             ScopeDef::GenericParam(TypeParamId { local_id, parent: *def }),
523                         )
524                     }
525                 }
526             }
527             Scope::ImplDefScope(i) => {
528                 f(name![Self], ScopeDef::ImplSelfType(*i));
529             }
530             Scope::AdtScope(i) => {
531                 f(name![Self], ScopeDef::AdtSelfType(*i));
532             }
533             Scope::ExprScope(scope) => {
534                 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
535                     f(e.name().clone(), ScopeDef::Local(e.pat()));
536                 });
537             }
538         }
539     }
540 }
541
542 // needs arbitrary_self_types to be a method... or maybe move to the def?
543 pub fn resolver_for_expr(db: &dyn DefDatabase, owner: DefWithBodyId, expr_id: ExprId) -> Resolver {
544     let scopes = db.expr_scopes(owner);
545     resolver_for_scope(db, owner, scopes.scope_for(expr_id))
546 }
547
548 pub fn resolver_for_scope(
549     db: &dyn DefDatabase,
550     owner: DefWithBodyId,
551     scope_id: Option<ScopeId>,
552 ) -> Resolver {
553     let mut r = owner.resolver(db);
554     r = r.push_local_items_scope(db.body(owner));
555     let scopes = db.expr_scopes(owner);
556     let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
557     for scope in scope_chain.into_iter().rev() {
558         r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
559     }
560     r
561 }
562
563 impl Resolver {
564     fn push_scope(mut self, scope: Scope) -> Resolver {
565         self.scopes.push(scope);
566         self
567     }
568
569     fn push_generic_params_scope(self, db: &dyn DefDatabase, def: GenericDefId) -> Resolver {
570         let params = db.generic_params(def);
571         self.push_scope(Scope::GenericParams { def, params })
572     }
573
574     fn push_impl_def_scope(self, impl_def: ImplId) -> Resolver {
575         self.push_scope(Scope::ImplDefScope(impl_def))
576     }
577
578     fn push_module_scope(
579         self,
580         crate_def_map: Arc<CrateDefMap>,
581         module_id: LocalModuleId,
582     ) -> Resolver {
583         self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
584     }
585
586     fn push_local_items_scope(self, body: Arc<Body>) -> Resolver {
587         self.push_scope(Scope::LocalItemsScope(body))
588     }
589
590     fn push_expr_scope(
591         self,
592         owner: DefWithBodyId,
593         expr_scopes: Arc<ExprScopes>,
594         scope_id: ScopeId,
595     ) -> Resolver {
596         self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
597     }
598 }
599
600 pub trait HasResolver: Copy {
601     /// Builds a resolver for type references inside this def.
602     fn resolver(self, db: &dyn DefDatabase) -> Resolver;
603 }
604
605 impl HasResolver for ModuleId {
606     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
607         let def_map = db.crate_def_map(self.krate);
608         Resolver::default().push_module_scope(def_map, self.local_id)
609     }
610 }
611
612 impl HasResolver for TraitId {
613     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
614         self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
615     }
616 }
617
618 impl<T: Into<AdtId> + Copy> HasResolver for T {
619     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
620         let def = self.into();
621         def.module(db)
622             .resolver(db)
623             .push_generic_params_scope(db, def.into())
624             .push_scope(Scope::AdtScope(def))
625     }
626 }
627
628 impl HasResolver for FunctionId {
629     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
630         self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
631     }
632 }
633
634 impl HasResolver for ConstId {
635     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
636         self.lookup(db).container.resolver(db)
637     }
638 }
639
640 impl HasResolver for StaticId {
641     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
642         self.lookup(db).container.resolver(db)
643     }
644 }
645
646 impl HasResolver for TypeAliasId {
647     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
648         self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
649     }
650 }
651
652 impl HasResolver for ImplId {
653     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
654         self.lookup(db)
655             .container
656             .resolver(db)
657             .push_generic_params_scope(db, self.into())
658             .push_impl_def_scope(self)
659     }
660 }
661
662 impl HasResolver for DefWithBodyId {
663     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
664         match self {
665             DefWithBodyId::ConstId(c) => c.resolver(db),
666             DefWithBodyId::FunctionId(f) => f.resolver(db),
667             DefWithBodyId::StaticId(s) => s.resolver(db),
668         }
669     }
670 }
671
672 impl HasResolver for ContainerId {
673     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
674         match self {
675             ContainerId::ModuleId(it) => it.resolver(db),
676             ContainerId::DefWithBodyId(it) => it.module(db).resolver(db),
677         }
678     }
679 }
680
681 impl HasResolver for AssocContainerId {
682     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
683         match self {
684             AssocContainerId::ContainerId(it) => it.resolver(db),
685             AssocContainerId::TraitId(it) => it.resolver(db),
686             AssocContainerId::ImplId(it) => it.resolver(db),
687         }
688     }
689 }
690
691 impl HasResolver for GenericDefId {
692     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
693         match self {
694             GenericDefId::FunctionId(inner) => inner.resolver(db),
695             GenericDefId::AdtId(adt) => adt.resolver(db),
696             GenericDefId::TraitId(inner) => inner.resolver(db),
697             GenericDefId::TypeAliasId(inner) => inner.resolver(db),
698             GenericDefId::ImplId(inner) => inner.resolver(db),
699             GenericDefId::EnumVariantId(inner) => inner.parent.resolver(db),
700             GenericDefId::ConstId(inner) => inner.resolver(db),
701         }
702     }
703 }
704
705 impl HasResolver for VariantId {
706     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
707         match self {
708             VariantId::EnumVariantId(it) => it.parent.resolver(db),
709             VariantId::StructId(it) => it.resolver(db),
710             VariantId::UnionId(it) => it.resolver(db),
711         }
712     }
713 }