1use std::{fmt, mem};
3
4use base_db::Crate;
5use hir_expand::{
6 MacroDefId,
7 mod_path::{ModPath, PathKind},
8 name::{AsName, Name},
9};
10use intern::{Symbol, sym};
11use itertools::Itertools as _;
12use rustc_hash::FxHashSet;
13use smallvec::{SmallVec, smallvec};
14use span::SyntaxContext;
15use syntax::ast::HasName;
16use triomphe::Arc;
17
18use crate::{
19 AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
20 ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, ImplId,
21 ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId,
22 ModuleId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId,
23 TypeParamId, UseId, VariantId,
24 builtin_type::BuiltinType,
25 db::DefDatabase,
26 expr_store::{
27 HygieneId,
28 path::Path,
29 scope::{ExprScopes, ScopeId},
30 },
31 hir::{
32 BindingId, ExprId, LabelId,
33 generics::{GenericParams, TypeOrConstParamData},
34 },
35 item_scope::{BUILTIN_SCOPE, BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, ItemScope},
36 lang_item::LangItemTarget,
37 nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo, block_def_map},
38 per_ns::PerNs,
39 src::HasSource,
40 type_ref::LifetimeRef,
41 visibility::{RawVisibility, Visibility},
42};
43
44#[derive(Debug, Clone)]
45pub struct Resolver<'db> {
46 scopes: Vec<Scope<'db>>,
51 module_scope: ModuleItemMap<'db>,
52}
53
54#[derive(Clone)]
55struct ModuleItemMap<'db> {
56 def_map: &'db DefMap,
57 local_def_map: &'db LocalDefMap,
58 module_id: ModuleId,
59}
60
61impl fmt::Debug for ModuleItemMap<'_> {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 f.debug_struct("ModuleItemMap").field("module_id", &self.module_id).finish()
64 }
65}
66
67#[derive(Clone)]
68struct ExprScope {
69 owner: DefWithBodyId,
70 expr_scopes: Arc<ExprScopes>,
71 scope_id: ScopeId,
72}
73
74impl fmt::Debug for ExprScope {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 f.debug_struct("ExprScope")
77 .field("owner", &self.owner)
78 .field("scope_id", &self.scope_id)
79 .finish()
80 }
81}
82
83#[derive(Debug, Clone)]
84enum Scope<'db> {
85 BlockScope(ModuleItemMap<'db>),
87 GenericParams { def: GenericDefId, params: Arc<GenericParams> },
90 ExprScope(ExprScope),
92 MacroDefScope(MacroDefId),
94}
95
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
97pub enum TypeNs {
98 SelfType(ImplId),
99 GenericParam(TypeParamId),
100 AdtId(AdtId),
101 AdtSelfType(AdtId),
102 EnumVariantId(EnumVariantId),
105 TypeAliasId(TypeAliasId),
106 BuiltinType(BuiltinType),
107 TraitId(TraitId),
108
109 ModuleId(ModuleId),
110}
111
112#[derive(Debug, Clone, PartialEq, Eq, Hash)]
113pub enum ResolveValueResult {
114 ValueNs(ValueNs, Option<ImportOrGlob>),
115 Partial(TypeNs, usize, Option<ImportOrExternCrate>),
116}
117
118#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
119pub enum ValueNs {
120 ImplSelf(ImplId),
121 LocalBinding(BindingId),
122 FunctionId(FunctionId),
123 ConstId(ConstId),
124 StaticId(StaticId),
125 StructId(StructId),
126 EnumVariantId(EnumVariantId),
127 GenericParam(ConstParamId),
128}
129
130#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
131pub enum LifetimeNs {
132 Static,
133 LifetimeParam(LifetimeParamId),
134}
135
136impl<'db> Resolver<'db> {
137 pub fn resolve_known_trait(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<TraitId> {
139 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
140 match res {
141 ModuleDefId::TraitId(it) => Some(it),
142 _ => None,
143 }
144 }
145
146 pub fn resolve_known_struct(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<StructId> {
148 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
149 match res {
150 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it),
151 _ => None,
152 }
153 }
154
155 pub fn resolve_known_enum(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<EnumId> {
157 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
158 match res {
159 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it),
160 _ => None,
161 }
162 }
163
164 pub fn resolve_module_path_in_items(&self, db: &dyn DefDatabase, path: &ModPath) -> PerNs {
165 self.resolve_module_path(db, path, BuiltinShadowMode::Module)
166 }
167
168 pub fn resolve_path_in_type_ns(
169 &self,
170 db: &dyn DefDatabase,
171 path: &Path,
172 ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
173 self.resolve_path_in_type_ns_with_prefix_info(db, path).map(
174 |(resolution, remaining_segments, import, _)| (resolution, remaining_segments, import),
175 )
176 }
177
178 pub fn resolve_path_in_type_ns_with_prefix_info(
179 &self,
180 db: &dyn DefDatabase,
181 path: &Path,
182 ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)>
183 {
184 let path = match path {
185 Path::BarePath(mod_path) => mod_path,
186 Path::Normal(it) => &it.mod_path,
187 Path::LangItem(l, seg) => {
188 let type_ns = match *l {
189 LangItemTarget::UnionId(it) => TypeNs::AdtId(it.into()),
190 LangItemTarget::TypeAliasId(it) => TypeNs::TypeAliasId(it),
191 LangItemTarget::StructId(it) => TypeNs::AdtId(it.into()),
192 LangItemTarget::EnumVariantId(it) => TypeNs::EnumVariantId(it),
193 LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()),
194 LangItemTarget::TraitId(it) => TypeNs::TraitId(it),
195 LangItemTarget::FunctionId(_)
196 | LangItemTarget::ImplId(_)
197 | LangItemTarget::StaticId(_) => return None,
198 };
199 return Some((
200 type_ns,
201 seg.as_ref().map(|_| 1),
202 None,
203 ResolvePathResultPrefixInfo::default(),
204 ));
205 }
206 };
207 let first_name = path.segments().first()?;
208 let skip_to_mod = path.kind != PathKind::Plain;
209 if skip_to_mod {
210 return self.module_scope.resolve_path_in_type_ns(db, path);
211 }
212
213 let remaining_idx = || {
214 if path.segments().len() == 1 { None } else { Some(1) }
215 };
216
217 for scope in self.scopes() {
218 match scope {
219 Scope::ExprScope(_) | Scope::MacroDefScope(_) => continue,
220 Scope::GenericParams { params, def } => {
221 if let &GenericDefId::ImplId(impl_) = def {
222 if *first_name == sym::Self_ {
223 return Some((
224 TypeNs::SelfType(impl_),
225 remaining_idx(),
226 None,
227 ResolvePathResultPrefixInfo::default(),
228 ));
229 }
230 } else if let &GenericDefId::AdtId(adt) = def
231 && *first_name == sym::Self_
232 {
233 return Some((
234 TypeNs::AdtSelfType(adt),
235 remaining_idx(),
236 None,
237 ResolvePathResultPrefixInfo::default(),
238 ));
239 }
240 if let Some(id) = params.find_type_by_name(first_name, *def) {
241 return Some((
242 TypeNs::GenericParam(id),
243 remaining_idx(),
244 None,
245 ResolvePathResultPrefixInfo::default(),
246 ));
247 }
248 }
249 Scope::BlockScope(m) => {
250 if let Some(res) = m.resolve_path_in_type_ns(db, path) {
251 let res = match res.0 {
252 TypeNs::ModuleId(_) if res.1.is_none() => {
253 if let Some(ModuleDefId::BuiltinType(builtin)) = BUILTIN_SCOPE
254 .get(first_name)
255 .and_then(|builtin| builtin.take_types())
256 {
257 (
258 TypeNs::BuiltinType(builtin),
259 remaining_idx(),
260 None,
261 ResolvePathResultPrefixInfo::default(),
262 )
263 } else {
264 res
265 }
266 }
267 _ => res,
268 };
269 return Some(res);
270 }
271 }
272 }
273 }
274 self.module_scope.resolve_path_in_type_ns(db, path)
275 }
276
277 pub fn resolve_path_in_type_ns_fully(
278 &self,
279 db: &dyn DefDatabase,
280 path: &Path,
281 ) -> Option<TypeNs> {
282 let (res, unresolved, _) = self.resolve_path_in_type_ns(db, path)?;
283 if unresolved.is_some() {
284 return None;
285 }
286 Some(res)
287 }
288
289 pub fn resolve_visibility(
290 &self,
291 db: &dyn DefDatabase,
292 visibility: &RawVisibility,
293 ) -> Option<Visibility> {
294 match visibility {
295 RawVisibility::Module(_, _) => {
296 let (item_map, item_local_map, module) = self.item_scope_();
297 item_map.resolve_visibility(
298 item_local_map,
299 db,
300 module,
301 visibility,
302 self.scopes().any(|scope| {
303 matches!(scope, Scope::GenericParams { def: GenericDefId::ImplId(_), .. })
304 }),
305 )
306 }
307 RawVisibility::PubSelf(explicitness) => {
308 Some(Visibility::Module(self.module(), *explicitness))
309 }
310 RawVisibility::PubCrate => Some(Visibility::PubCrate(self.krate())),
311 RawVisibility::Public => Some(Visibility::Public),
312 }
313 }
314
315 pub fn resolve_path_in_value_ns(
316 &self,
317 db: &dyn DefDatabase,
318 path: &Path,
319 hygiene_id: HygieneId,
320 ) -> Option<ResolveValueResult> {
321 self.resolve_path_in_value_ns_with_prefix_info(db, path, hygiene_id).map(|(it, _)| it)
322 }
323
324 pub fn resolve_path_in_value_ns_with_prefix_info(
325 &self,
326 db: &dyn DefDatabase,
327 path: &Path,
328 mut hygiene_id: HygieneId,
329 ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> {
330 let path = match path {
331 Path::BarePath(mod_path) => mod_path,
332 Path::Normal(it) => &it.mod_path,
333 Path::LangItem(l, None) => {
334 return Some((
335 ResolveValueResult::ValueNs(
336 match *l {
337 LangItemTarget::FunctionId(it) => ValueNs::FunctionId(it),
338 LangItemTarget::StaticId(it) => ValueNs::StaticId(it),
339 LangItemTarget::StructId(it) => ValueNs::StructId(it),
340 LangItemTarget::EnumVariantId(it) => ValueNs::EnumVariantId(it),
341 LangItemTarget::UnionId(_)
342 | LangItemTarget::ImplId(_)
343 | LangItemTarget::TypeAliasId(_)
344 | LangItemTarget::TraitId(_)
345 | LangItemTarget::EnumId(_) => return None,
346 },
347 None,
348 ),
349 ResolvePathResultPrefixInfo::default(),
350 ));
351 }
352 Path::LangItem(l, Some(_)) => {
353 let type_ns = match *l {
354 LangItemTarget::UnionId(it) => TypeNs::AdtId(it.into()),
355 LangItemTarget::TypeAliasId(it) => TypeNs::TypeAliasId(it),
356 LangItemTarget::StructId(it) => TypeNs::AdtId(it.into()),
357 LangItemTarget::EnumVariantId(it) => TypeNs::EnumVariantId(it),
358 LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()),
359 LangItemTarget::TraitId(it) => TypeNs::TraitId(it),
360 LangItemTarget::FunctionId(_)
361 | LangItemTarget::ImplId(_)
362 | LangItemTarget::StaticId(_) => return None,
363 };
364 return Some((
366 ResolveValueResult::Partial(type_ns, 0, None),
367 ResolvePathResultPrefixInfo::default(),
368 ));
369 }
370 };
371 let n_segments = path.segments().len();
372 let tmp = Name::new_symbol_root(sym::self_);
373 let first_name = if path.is_self() { &tmp } else { path.segments().first()? };
374 let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
375 if skip_to_mod {
376 return self.module_scope.resolve_path_in_value_ns(db, path);
377 }
378
379 if n_segments <= 1 {
380 let mut hygiene_info = hygiene_info(db, hygiene_id);
381 for scope in self.scopes() {
382 match scope {
383 Scope::ExprScope(scope) => {
384 let entry =
385 scope.expr_scopes.entries(scope.scope_id).iter().find(|entry| {
386 entry.name() == first_name && entry.hygiene() == hygiene_id
387 });
388
389 if let Some(e) = entry {
390 return Some((
391 ResolveValueResult::ValueNs(
392 ValueNs::LocalBinding(e.binding()),
393 None,
394 ),
395 ResolvePathResultPrefixInfo::default(),
396 ));
397 }
398 }
399 Scope::MacroDefScope(macro_id) => {
400 handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id)
401 }
402 Scope::GenericParams { params, def } => {
403 if let &GenericDefId::ImplId(impl_) = def
404 && *first_name == sym::Self_
405 {
406 return Some((
407 ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_), None),
408 ResolvePathResultPrefixInfo::default(),
409 ));
410 }
411 if let Some(id) = params.find_const_by_name(first_name, *def) {
412 let val = ValueNs::GenericParam(id);
413 return Some((
414 ResolveValueResult::ValueNs(val, None),
415 ResolvePathResultPrefixInfo::default(),
416 ));
417 }
418 }
419 Scope::BlockScope(m) => {
420 if let Some(def) = m.resolve_path_in_value_ns(db, path) {
421 return Some(def);
422 }
423 }
424 }
425 }
426 } else {
427 for scope in self.scopes() {
428 match scope {
429 Scope::ExprScope(_) | Scope::MacroDefScope(_) => continue,
430 Scope::GenericParams { params, def } => {
431 if let &GenericDefId::ImplId(impl_) = def {
432 if *first_name == sym::Self_ {
433 return Some((
434 ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1, None),
435 ResolvePathResultPrefixInfo::default(),
436 ));
437 }
438 } else if let &GenericDefId::AdtId(adt) = def
439 && *first_name == sym::Self_
440 {
441 let ty = TypeNs::AdtSelfType(adt);
442 return Some((
443 ResolveValueResult::Partial(ty, 1, None),
444 ResolvePathResultPrefixInfo::default(),
445 ));
446 }
447 if let Some(id) = params.find_type_by_name(first_name, *def) {
448 let ty = TypeNs::GenericParam(id);
449 return Some((
450 ResolveValueResult::Partial(ty, 1, None),
451 ResolvePathResultPrefixInfo::default(),
452 ));
453 }
454 }
455 Scope::BlockScope(m) => {
456 if let Some(def) = m.resolve_path_in_value_ns(db, path) {
457 return Some(def);
458 }
459 }
460 }
461 }
462 }
463
464 if let Some(res) = self.module_scope.resolve_path_in_value_ns(db, path) {
465 return Some(res);
466 }
467
468 if path.kind == PathKind::Plain
472 && n_segments > 1
473 && let Some(builtin) = BuiltinType::by_name(first_name)
474 {
475 return Some((
476 ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None),
477 ResolvePathResultPrefixInfo::default(),
478 ));
479 }
480
481 None
482 }
483
484 pub fn resolve_path_in_value_ns_fully(
485 &self,
486 db: &dyn DefDatabase,
487 path: &Path,
488 hygiene: HygieneId,
489 ) -> Option<ValueNs> {
490 match self.resolve_path_in_value_ns(db, path, hygiene)? {
491 ResolveValueResult::ValueNs(it, _) => Some(it),
492 ResolveValueResult::Partial(..) => None,
493 }
494 }
495
496 pub fn resolve_path_as_macro(
497 &self,
498 db: &dyn DefDatabase,
499 path: &ModPath,
500 expected_macro_kind: Option<MacroSubNs>,
501 ) -> Option<(MacroId, Option<ImportOrExternCrate>)> {
502 let (item_map, item_local_map, module) = self.item_scope_();
503 item_map
504 .resolve_path(
505 item_local_map,
506 db,
507 module,
508 path,
509 BuiltinShadowMode::Other,
510 expected_macro_kind,
511 )
512 .0
513 .take_macros_import()
514 }
515
516 pub fn resolve_path_as_macro_def(
517 &self,
518 db: &dyn DefDatabase,
519 path: &ModPath,
520 expected_macro_kind: Option<MacroSubNs>,
521 ) -> Option<MacroDefId> {
522 self.resolve_path_as_macro(db, path, expected_macro_kind).map(|(it, _)| db.macro_def(it))
523 }
524
525 pub fn resolve_lifetime(&self, lifetime: &LifetimeRef) -> Option<LifetimeNs> {
526 match lifetime {
527 LifetimeRef::Static => Some(LifetimeNs::Static),
528 LifetimeRef::Named(name) => self.scopes().find_map(|scope| match scope {
529 Scope::GenericParams { def, params } => {
530 params.find_lifetime_by_name(name, *def).map(LifetimeNs::LifetimeParam)
531 }
532 _ => None,
533 }),
534 LifetimeRef::Placeholder | LifetimeRef::Error => None,
535 LifetimeRef::Param(lifetime_param_id) => {
536 Some(LifetimeNs::LifetimeParam(*lifetime_param_id))
537 }
538 }
539 }
540
541 pub fn names_in_scope(
581 &self,
582 db: &dyn DefDatabase,
583 ) -> FxIndexMap<Name, SmallVec<[ScopeDef; 1]>> {
584 let mut res = ScopeNames::default();
585 for scope in self.scopes() {
586 scope.process_names(&mut res, db);
587 }
588 let ModuleItemMap { def_map, module_id, local_def_map } = self.module_scope;
589 def_map[module_id].scope.entries().for_each(|(name, def)| {
597 res.add_per_ns(name, def);
598 });
599
600 def_map[module_id].scope.legacy_macros().for_each(|(name, macs)| {
601 macs.iter().for_each(|&mac| {
602 res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)));
603 })
604 });
605 def_map.macro_use_prelude().iter().sorted_by_key(|&(k, _)| k.clone()).for_each(
606 |(name, &(def, _extern_crate))| {
607 res.add(name, ScopeDef::ModuleDef(def.into()));
608 },
609 );
610 local_def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| {
611 res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
612 });
613 BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
614 res.add_per_ns(name, def);
615 });
616 if let Some((prelude, _use)) = def_map.prelude() {
617 let prelude_def_map = prelude.def_map(db);
618 for (name, def) in prelude_def_map[prelude].scope.entries() {
619 res.add_per_ns(name, def)
620 }
621 }
622 res.map
623 }
624
625 pub fn extern_crate_decls_in_scope<'a>(
627 &'a self,
628 db: &'a dyn DefDatabase,
629 ) -> impl Iterator<Item = Name> + 'a {
630 self.module_scope.def_map[self.module_scope.module_id]
631 .scope
632 .extern_crate_decls()
633 .filter_map(|id| {
634 let loc = id.lookup(db);
635 let extern_crate = loc.source(db);
636 extern_crate
639 .value
640 .rename()
641 .map(|a| a.name().map(|it| it.as_name()))
642 .unwrap_or_else(|| extern_crate.value.name_ref().map(|it| it.as_name()))
643 })
644 }
645
646 pub fn extern_crates_in_scope(&self) -> impl Iterator<Item = (Name, ModuleId)> + '_ {
647 self.module_scope
648 .local_def_map
649 .extern_prelude()
650 .map(|(name, module_id)| (name.clone(), module_id.0))
651 }
652
653 pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
654 let mut traits = FxHashSet::default();
657
658 for scope in self.scopes() {
659 match scope {
660 Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()),
661 &Scope::GenericParams { def: GenericDefId::ImplId(impl_), .. } => {
662 let impl_data = db.impl_signature(impl_);
663 if let Some(target_trait) = impl_data.target_trait
664 && let Some(TypeNs::TraitId(trait_)) = self
665 .resolve_path_in_type_ns_fully(db, &impl_data.store[target_trait.path])
666 {
667 traits.insert(trait_);
668 }
669 }
670 _ => (),
671 }
672 }
673
674 if let Some((prelude, _use)) = self.module_scope.def_map.prelude() {
676 let prelude_def_map = prelude.def_map(db);
677 traits.extend(prelude_def_map[prelude].scope.traits());
678 }
679 traits.extend(self.module_scope.def_map[self.module_scope.module_id].scope.traits());
681 traits
682 }
683
684 pub fn traits_in_scope_from_block_scopes(&self) -> impl Iterator<Item = TraitId> + '_ {
685 self.scopes()
686 .filter_map(|scope| match scope {
687 Scope::BlockScope(m) => Some(m.def_map[m.module_id].scope.traits()),
688 _ => None,
689 })
690 .flatten()
691 }
692
693 pub fn module(&self) -> ModuleId {
694 self.item_scope_().2
695 }
696
697 pub fn item_scope(&self) -> &ItemScope {
698 let (def_map, _, local_id) = self.item_scope_();
699 &def_map[local_id].scope
700 }
701
702 pub fn krate(&self) -> Crate {
703 self.module_scope.def_map.krate()
704 }
705
706 pub fn def_map(&self) -> &DefMap {
707 self.item_scope_().0
708 }
709
710 #[inline]
711 pub fn top_level_def_map(&self) -> &'db DefMap {
712 self.module_scope.def_map
713 }
714
715 #[inline]
716 pub fn is_visible(&self, db: &dyn DefDatabase, visibility: Visibility) -> bool {
717 visibility.is_visible_from_def_map(
718 db,
719 self.module_scope.def_map,
720 self.module_scope.module_id,
721 )
722 }
723
724 pub fn generic_def(&self) -> Option<GenericDefId> {
725 self.scopes().find_map(|scope| match scope {
726 Scope::GenericParams { def, .. } => Some(*def),
727 _ => None,
728 })
729 }
730
731 pub fn generic_params(&self) -> Option<&GenericParams> {
732 self.scopes().find_map(|scope| match scope {
733 Scope::GenericParams { params, .. } => Some(&**params),
734 _ => None,
735 })
736 }
737
738 pub fn all_generic_params(&self) -> impl Iterator<Item = (&GenericParams, &GenericDefId)> {
739 self.scopes().filter_map(|scope| match scope {
740 Scope::GenericParams { params, def } => Some((&**params, def)),
741 _ => None,
742 })
743 }
744
745 pub fn body_owner(&self) -> Option<DefWithBodyId> {
746 self.scopes().find_map(|scope| match scope {
747 Scope::ExprScope(it) => Some(it.owner),
748 _ => None,
749 })
750 }
751
752 pub fn impl_def(&self) -> Option<ImplId> {
753 self.scopes().find_map(|scope| match scope {
754 &Scope::GenericParams { def: GenericDefId::ImplId(def), .. } => Some(def),
755 _ => None,
756 })
757 }
758
759 pub fn rename_will_conflict_with_another_variable(
762 &self,
763 db: &dyn DefDatabase,
764 current_name: &Name,
765 current_name_as_path: &ModPath,
766 mut hygiene_id: HygieneId,
767 new_name: &Symbol,
768 to_be_renamed: BindingId,
769 ) -> Option<BindingId> {
770 let mut hygiene_info = hygiene_info(db, hygiene_id);
771 let mut will_be_resolved_to = None;
772 for scope in self.scopes() {
773 match scope {
774 Scope::ExprScope(scope) => {
775 for entry in scope.expr_scopes.entries(scope.scope_id) {
776 if entry.hygiene() == hygiene_id {
777 if entry.binding() == to_be_renamed {
778 return will_be_resolved_to;
781 } else if entry.name().symbol() == new_name {
782 will_be_resolved_to = Some(entry.binding());
783 }
784 }
785 }
786 }
787 Scope::MacroDefScope(macro_id) => {
788 handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id)
789 }
790 Scope::GenericParams { params, def } => {
791 if params.find_const_by_name(current_name, *def).is_some() {
792 return None;
794 }
795 }
796 Scope::BlockScope(m) => {
797 if m.resolve_path_in_value_ns(db, current_name_as_path).is_some() {
798 return None;
800 }
801 }
802 }
803 }
804 None
806 }
807
808 pub fn rename_will_conflict_with_renamed(
811 &self,
812 db: &dyn DefDatabase,
813 name: &Name,
814 name_as_path: &ModPath,
815 mut hygiene_id: HygieneId,
816 to_be_renamed: BindingId,
817 ) -> Option<BindingId> {
818 let mut hygiene_info = hygiene_info(db, hygiene_id);
819 let mut will_resolve_to_renamed = false;
820 for scope in self.scopes() {
821 match scope {
822 Scope::ExprScope(scope) => {
823 for entry in scope.expr_scopes.entries(scope.scope_id) {
824 if entry.binding() == to_be_renamed {
825 will_resolve_to_renamed = true;
826 } else if entry.hygiene() == hygiene_id && entry.name() == name {
827 if will_resolve_to_renamed {
828 return Some(entry.binding());
830 } else {
831 return None;
833 }
834 }
835 }
836 }
837 Scope::MacroDefScope(macro_id) => {
838 handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id)
839 }
840 Scope::GenericParams { params, def } => {
841 if params.find_const_by_name(name, *def).is_some() {
842 return None;
846 }
847 }
848 Scope::BlockScope(m) => {
849 if m.resolve_path_in_value_ns(db, name_as_path).is_some() {
850 return None;
851 }
852 }
853 }
854 }
855 None
856 }
857
858 #[must_use]
860 pub fn update_to_inner_scope(
861 &mut self,
862 db: &'db dyn DefDatabase,
863 owner: DefWithBodyId,
864 expr_id: ExprId,
865 ) -> UpdateGuard {
866 #[inline(always)]
867 fn append_expr_scope<'db>(
868 db: &'db dyn DefDatabase,
869 resolver: &mut Resolver<'db>,
870 owner: DefWithBodyId,
871 expr_scopes: &Arc<ExprScopes>,
872 scope_id: ScopeId,
873 ) {
874 if let Some(macro_id) = expr_scopes.macro_def(scope_id) {
875 resolver.scopes.push(Scope::MacroDefScope(**macro_id));
876 }
877 resolver.scopes.push(Scope::ExprScope(ExprScope {
878 owner,
879 expr_scopes: expr_scopes.clone(),
880 scope_id,
881 }));
882 if let Some(block) = expr_scopes.block(scope_id) {
883 let def_map = block_def_map(db, block);
884 let local_def_map = block.lookup(db).module.only_local_def_map(db);
885 resolver.scopes.push(Scope::BlockScope(ModuleItemMap {
886 def_map,
887 local_def_map,
888 module_id: def_map.root,
889 }));
890 }
894 }
895
896 let start = self.scopes.len();
897 let innermost_scope = self.scopes().find(|scope| !matches!(scope, Scope::MacroDefScope(_)));
898 match innermost_scope {
899 Some(&Scope::ExprScope(ExprScope { scope_id, ref expr_scopes, owner })) => {
900 let expr_scopes = expr_scopes.clone();
901 let scope_chain = expr_scopes
902 .scope_chain(expr_scopes.scope_for(expr_id))
903 .take_while(|&it| it != scope_id);
904 for scope_id in scope_chain {
905 append_expr_scope(db, self, owner, &expr_scopes, scope_id);
906 }
907 }
908 _ => {
909 let expr_scopes = db.expr_scopes(owner);
910 let scope_chain = expr_scopes.scope_chain(expr_scopes.scope_for(expr_id));
911
912 for scope_id in scope_chain {
913 append_expr_scope(db, self, owner, &expr_scopes, scope_id);
914 }
915 }
916 }
917 self.scopes[start..].reverse();
918 UpdateGuard(start)
919 }
920
921 pub fn reset_to_guard(&mut self, UpdateGuard(start): UpdateGuard) {
922 self.scopes.truncate(start);
923 }
924}
925
926#[inline]
927fn handle_macro_def_scope(
928 db: &dyn DefDatabase,
929 hygiene_id: &mut HygieneId,
930 hygiene_info: &mut Option<(SyntaxContext, MacroDefId)>,
931 macro_id: &MacroDefId,
932) {
933 if let Some((parent_ctx, label_macro_id)) = hygiene_info
934 && label_macro_id == macro_id
935 {
936 *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(db));
940 *hygiene_info = parent_ctx.outer_expn(db).map(|expansion| {
941 let expansion = db.lookup_intern_macro_call(expansion.into());
942 (parent_ctx.parent(db), expansion.def)
943 });
944 }
945}
946
947#[inline]
948fn hygiene_info(
949 db: &dyn DefDatabase,
950 hygiene_id: HygieneId,
951) -> Option<(SyntaxContext, MacroDefId)> {
952 if !hygiene_id.is_root() {
953 let ctx = hygiene_id.lookup();
954 ctx.outer_expn(db).map(|expansion| {
955 let expansion = db.lookup_intern_macro_call(expansion.into());
956 (ctx.parent(db), expansion.def)
957 })
958 } else {
959 None
960 }
961}
962
963pub struct UpdateGuard(usize);
964
965impl<'db> Resolver<'db> {
966 fn scopes(&self) -> impl Iterator<Item = &Scope<'db>> {
967 self.scopes.iter().rev()
968 }
969
970 fn resolve_module_path(
971 &self,
972 db: &dyn DefDatabase,
973 path: &ModPath,
974 shadow: BuiltinShadowMode,
975 ) -> PerNs {
976 let (item_map, item_local_map, module) = self.item_scope_();
977 let (module_res, segment_index) =
979 item_map.resolve_path(item_local_map, db, module, path, shadow, None);
980 if segment_index.is_some() {
981 return PerNs::none();
982 }
983 module_res
984 }
985
986 fn item_scope_(&self) -> (&DefMap, &LocalDefMap, ModuleId) {
988 self.scopes()
989 .find_map(|scope| match scope {
990 Scope::BlockScope(m) => Some((m.def_map, m.local_def_map, m.module_id)),
991 _ => None,
992 })
993 .unwrap_or((
994 self.module_scope.def_map,
995 self.module_scope.local_def_map,
996 self.module_scope.module_id,
997 ))
998 }
999}
1000
1001#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1002pub enum ScopeDef {
1003 ModuleDef(ModuleDefId),
1004 Unknown,
1005 ImplSelfType(ImplId),
1006 AdtSelfType(AdtId),
1007 GenericParam(GenericParamId),
1008 Local(BindingId),
1009 Label(LabelId),
1010}
1011
1012impl<'db> Scope<'db> {
1013 fn process_names(&self, acc: &mut ScopeNames, db: &'db dyn DefDatabase) {
1014 match self {
1015 Scope::BlockScope(m) => {
1016 m.def_map[m.module_id].scope.entries().for_each(|(name, def)| {
1017 acc.add_per_ns(name, def);
1018 });
1019 m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, macs)| {
1020 macs.iter().for_each(|&mac| {
1021 acc.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)));
1022 })
1023 });
1024 }
1025 &Scope::GenericParams { ref params, def: parent } => {
1026 if let GenericDefId::ImplId(impl_) = parent {
1027 acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::ImplSelfType(impl_));
1028 } else if let GenericDefId::AdtId(adt) = parent {
1029 acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::AdtSelfType(adt));
1030 }
1031
1032 for (local_id, param) in params.iter_type_or_consts() {
1033 if let Some(name) = ¶m.name() {
1034 let id = TypeOrConstParamId { parent, local_id };
1035 let data = &db.generic_params(parent)[local_id];
1036 acc.add(
1037 name,
1038 ScopeDef::GenericParam(match data {
1039 TypeOrConstParamData::TypeParamData(_) => {
1040 GenericParamId::TypeParamId(TypeParamId::from_unchecked(id))
1041 }
1042 TypeOrConstParamData::ConstParamData(_) => {
1043 GenericParamId::ConstParamId(ConstParamId::from_unchecked(id))
1044 }
1045 }),
1046 );
1047 }
1048 }
1049 for (local_id, param) in params.iter_lt() {
1050 let id = LifetimeParamId { parent, local_id };
1051 acc.add(¶m.name, ScopeDef::GenericParam(id.into()))
1052 }
1053 }
1054 Scope::ExprScope(scope) => {
1055 if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) {
1056 acc.add(&name, ScopeDef::Label(label))
1057 }
1058 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
1059 acc.add_local(e.name(), e.binding());
1060 });
1061 }
1062 Scope::MacroDefScope(_) => {}
1063 }
1064 }
1065}
1066
1067pub fn resolver_for_scope(
1068 db: &dyn DefDatabase,
1069 owner: DefWithBodyId,
1070 scope_id: Option<ScopeId>,
1071) -> Resolver<'_> {
1072 let r = owner.resolver(db);
1073 let scopes = db.expr_scopes(owner);
1074 resolver_for_scope_(db, scopes, scope_id, r, owner)
1075}
1076
1077fn resolver_for_scope_<'db>(
1078 db: &'db dyn DefDatabase,
1079 scopes: Arc<ExprScopes>,
1080 scope_id: Option<ScopeId>,
1081 mut r: Resolver<'db>,
1082 owner: DefWithBodyId,
1083) -> Resolver<'db> {
1084 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
1085 r.scopes.reserve(scope_chain.len());
1086
1087 for scope in scope_chain.into_iter().rev() {
1088 if let Some(block) = scopes.block(scope) {
1089 let def_map = block_def_map(db, block);
1090 let local_def_map = block.lookup(db).module.only_local_def_map(db);
1091 r = r.push_block_scope(def_map, local_def_map, def_map.root);
1094 }
1098 if let Some(macro_id) = scopes.macro_def(scope) {
1099 r = r.push_scope(Scope::MacroDefScope(**macro_id));
1100 }
1101
1102 r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
1103 }
1104 r
1105}
1106
1107impl<'db> Resolver<'db> {
1108 fn push_scope(mut self, scope: Scope<'db>) -> Resolver<'db> {
1109 self.scopes.push(scope);
1110 self
1111 }
1112
1113 fn push_generic_params_scope(
1114 self,
1115 db: &'db dyn DefDatabase,
1116 def: GenericDefId,
1117 ) -> Resolver<'db> {
1118 let params = db.generic_params(def);
1119 self.push_scope(Scope::GenericParams { def, params })
1120 }
1121
1122 fn push_block_scope(
1123 self,
1124 def_map: &'db DefMap,
1125 local_def_map: &'db LocalDefMap,
1126 module_id: ModuleId,
1127 ) -> Resolver<'db> {
1128 self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, module_id }))
1129 }
1130
1131 fn push_expr_scope(
1132 self,
1133 owner: DefWithBodyId,
1134 expr_scopes: Arc<ExprScopes>,
1135 scope_id: ScopeId,
1136 ) -> Resolver<'db> {
1137 self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
1138 }
1139}
1140
1141impl<'db> ModuleItemMap<'db> {
1142 fn resolve_path_in_value_ns(
1143 &self,
1144 db: &'db dyn DefDatabase,
1145 path: &ModPath,
1146 ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> {
1147 let (module_def, unresolved_idx, prefix_info) = self.def_map.resolve_path_locally(
1148 self.local_def_map,
1149 db,
1150 self.module_id,
1151 path,
1152 BuiltinShadowMode::Other,
1153 );
1154 match unresolved_idx {
1155 None => {
1156 let (value, import) = to_value_ns(module_def)?;
1157 Some((ResolveValueResult::ValueNs(value, import), prefix_info))
1158 }
1159 Some(unresolved_idx) => {
1160 let def = module_def.take_types_full()?;
1161 let ty = match def.def {
1162 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
1163 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
1164 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
1165 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
1166
1167 ModuleDefId::ModuleId(_)
1168 | ModuleDefId::FunctionId(_)
1169 | ModuleDefId::EnumVariantId(_)
1170 | ModuleDefId::ConstId(_)
1171 | ModuleDefId::MacroId(_)
1172 | ModuleDefId::StaticId(_) => return None,
1173 };
1174 Some((ResolveValueResult::Partial(ty, unresolved_idx, def.import), prefix_info))
1175 }
1176 }
1177 }
1178
1179 fn resolve_path_in_type_ns(
1180 &self,
1181 db: &dyn DefDatabase,
1182 path: &ModPath,
1183 ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)>
1184 {
1185 let (module_def, idx, prefix_info) = self.def_map.resolve_path_locally(
1186 self.local_def_map,
1187 db,
1188 self.module_id,
1189 path,
1190 BuiltinShadowMode::Other,
1191 );
1192 let (res, import) = to_type_ns(module_def)?;
1193 Some((res, idx, import, prefix_info))
1194 }
1195}
1196
1197fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportOrGlob>)> {
1198 let (def, import) = per_ns.take_values_import()?;
1199 let res = match def {
1200 ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
1201 ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
1202 ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
1203 ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
1204 ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
1205
1206 ModuleDefId::AdtId(AdtId::EnumId(_) | AdtId::UnionId(_))
1207 | ModuleDefId::TraitId(_)
1208 | ModuleDefId::TypeAliasId(_)
1209 | ModuleDefId::BuiltinType(_)
1210 | ModuleDefId::MacroId(_)
1211 | ModuleDefId::ModuleId(_) => return None,
1212 };
1213 Some((res, import))
1214}
1215
1216fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
1217 let def = per_ns.take_types_full()?;
1218 let res = match def.def {
1219 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
1220 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
1221
1222 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
1223 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
1224
1225 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
1226
1227 ModuleDefId::ModuleId(it) => TypeNs::ModuleId(it),
1228
1229 ModuleDefId::FunctionId(_)
1230 | ModuleDefId::ConstId(_)
1231 | ModuleDefId::MacroId(_)
1232 | ModuleDefId::StaticId(_) => return None,
1233 };
1234 Some((res, def.import))
1235}
1236
1237#[derive(Default)]
1238struct ScopeNames {
1239 map: FxIndexMap<Name, SmallVec<[ScopeDef; 1]>>,
1240}
1241
1242impl ScopeNames {
1243 fn add(&mut self, name: &Name, def: ScopeDef) {
1244 let set = self.map.entry(name.clone()).or_default();
1245 if !set.contains(&def) {
1246 set.push(def)
1247 }
1248 }
1249 fn add_per_ns(&mut self, name: &Name, def: PerNs) {
1250 if let Some(ty) = &def.types {
1251 self.add(name, ScopeDef::ModuleDef(ty.def))
1252 }
1253 if let Some(def) = &def.values {
1254 self.add(name, ScopeDef::ModuleDef(def.def))
1255 }
1256 if let Some(mac) = &def.macros {
1257 self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac.def)))
1258 }
1259 if def.is_none() {
1260 self.add(name, ScopeDef::Unknown)
1261 }
1262 }
1263 fn add_local(&mut self, name: &Name, binding: BindingId) {
1264 let set = self.map.entry(name.clone()).or_default();
1265 if set.iter().any(|it| matches!(it, &ScopeDef::Local(_))) {
1271 cov_mark::hit!(shadowing_shows_single_completion);
1272 return;
1273 }
1274 set.push(ScopeDef::Local(binding))
1275 }
1276}
1277
1278pub trait HasResolver: Copy {
1279 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_>;
1281}
1282
1283impl HasResolver for ModuleId {
1284 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1285 let (mut def_map, local_def_map) = self.local_def_map(db);
1286 let mut module_id = self;
1287
1288 if self.block(db).is_none() {
1289 return Resolver {
1290 scopes: vec![],
1291 module_scope: ModuleItemMap { def_map, local_def_map, module_id },
1292 };
1293 }
1294
1295 let mut modules: SmallVec<[_; 1]> = smallvec![];
1296 while let Some(parent) = def_map.parent() {
1297 let block_def_map = mem::replace(&mut def_map, parent.def_map(db));
1298 let block_module_id = mem::replace(&mut module_id, parent);
1299 modules.push((block_def_map, block_module_id));
1300 if parent.block(db).is_none() {
1301 break;
1302 }
1303 }
1304 let mut resolver = Resolver {
1305 scopes: Vec::with_capacity(modules.len()),
1306 module_scope: ModuleItemMap { def_map, local_def_map, module_id },
1307 };
1308 for (def_map, module_id) in modules.into_iter().rev() {
1309 resolver = resolver.push_block_scope(def_map, local_def_map, module_id);
1310 }
1311 resolver
1312 }
1313}
1314
1315impl HasResolver for TraitId {
1316 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1317 lookup_resolver(db, self).push_generic_params_scope(db, self.into())
1318 }
1319}
1320
1321impl<T: Into<AdtId> + Copy> HasResolver for T {
1322 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1323 let def = self.into();
1324 def.module(db).resolver(db).push_generic_params_scope(db, def.into())
1325 }
1326}
1327
1328impl HasResolver for FunctionId {
1329 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1330 lookup_resolver(db, self).push_generic_params_scope(db, self.into())
1331 }
1332}
1333
1334impl HasResolver for ConstId {
1335 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1336 lookup_resolver(db, self)
1337 }
1338}
1339
1340impl HasResolver for StaticId {
1341 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1342 lookup_resolver(db, self)
1343 }
1344}
1345
1346impl HasResolver for TypeAliasId {
1347 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1348 lookup_resolver(db, self).push_generic_params_scope(db, self.into())
1349 }
1350}
1351
1352impl HasResolver for ImplId {
1353 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1354 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
1355 }
1356}
1357
1358impl HasResolver for ExternBlockId {
1359 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1360 lookup_resolver(db, self)
1362 }
1363}
1364
1365impl HasResolver for ExternCrateId {
1366 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1367 lookup_resolver(db, self)
1368 }
1369}
1370
1371impl HasResolver for UseId {
1372 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1373 lookup_resolver(db, self)
1374 }
1375}
1376
1377impl HasResolver for DefWithBodyId {
1378 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1379 match self {
1380 DefWithBodyId::ConstId(c) => c.resolver(db),
1381 DefWithBodyId::FunctionId(f) => f.resolver(db),
1382 DefWithBodyId::StaticId(s) => s.resolver(db),
1383 DefWithBodyId::VariantId(v) => v.resolver(db),
1384 }
1385 }
1386}
1387
1388impl HasResolver for ItemContainerId {
1389 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1390 match self {
1391 ItemContainerId::ModuleId(it) => it.resolver(db),
1392 ItemContainerId::TraitId(it) => it.resolver(db),
1393 ItemContainerId::ImplId(it) => it.resolver(db),
1394 ItemContainerId::ExternBlockId(it) => it.resolver(db),
1395 }
1396 }
1397}
1398
1399impl HasResolver for GenericDefId {
1400 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1401 match self {
1402 GenericDefId::FunctionId(inner) => inner.resolver(db),
1403 GenericDefId::AdtId(adt) => adt.resolver(db),
1404 GenericDefId::TraitId(inner) => inner.resolver(db),
1405 GenericDefId::TypeAliasId(inner) => inner.resolver(db),
1406 GenericDefId::ImplId(inner) => inner.resolver(db),
1407 GenericDefId::ConstId(inner) => inner.resolver(db),
1408 GenericDefId::StaticId(inner) => inner.resolver(db),
1409 }
1410 }
1411}
1412
1413impl HasResolver for EnumVariantId {
1414 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1415 self.lookup(db).parent.resolver(db)
1416 }
1417}
1418
1419impl HasResolver for VariantId {
1420 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1421 match self {
1422 VariantId::EnumVariantId(it) => it.resolver(db),
1423 VariantId::StructId(it) => it.resolver(db),
1424 VariantId::UnionId(it) => it.resolver(db),
1425 }
1426 }
1427}
1428
1429impl HasResolver for MacroId {
1430 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1431 match self {
1432 MacroId::Macro2Id(it) => it.resolver(db),
1433 MacroId::MacroRulesId(it) => it.resolver(db),
1434 MacroId::ProcMacroId(it) => it.resolver(db),
1435 }
1436 }
1437}
1438
1439impl HasResolver for Macro2Id {
1440 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1441 lookup_resolver(db, self)
1442 }
1443}
1444
1445impl HasResolver for ProcMacroId {
1446 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1447 lookup_resolver(db, self)
1448 }
1449}
1450
1451impl HasResolver for MacroRulesId {
1452 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1453 lookup_resolver(db, self)
1454 }
1455}
1456
1457fn lookup_resolver(
1458 db: &dyn DefDatabase,
1459 lookup: impl Lookup<Database = dyn DefDatabase, Data = impl AstIdLoc<Container = impl HasResolver>>,
1460) -> Resolver<'_> {
1461 lookup.lookup(db).container().resolver(db)
1462}