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, CrateRootModuleId, DefWithBodyId, EnumId,
20 EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId,
21 GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalModuleId, Lookup,
22 Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId,
23 TraitId, TypeAliasId, TypeOrConstParamId, 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: LocalModuleId,
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::Union(it) => TypeNs::AdtId(it.into()),
190 LangItemTarget::TypeAlias(it) => TypeNs::TypeAliasId(it),
191 LangItemTarget::Struct(it) => TypeNs::AdtId(it.into()),
192 LangItemTarget::EnumVariant(it) => TypeNs::EnumVariantId(it),
193 LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()),
194 LangItemTarget::Trait(it) => TypeNs::TraitId(it),
195 LangItemTarget::Function(_)
196 | LangItemTarget::ImplDef(_)
197 | LangItemTarget::Static(_) => 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::Function(it) => ValueNs::FunctionId(it),
338 LangItemTarget::Static(it) => ValueNs::StaticId(it),
339 LangItemTarget::Struct(it) => ValueNs::StructId(it),
340 LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
341 LangItemTarget::Union(_)
342 | LangItemTarget::ImplDef(_)
343 | LangItemTarget::TypeAlias(_)
344 | LangItemTarget::Trait(_)
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::Union(it) => TypeNs::AdtId(it.into()),
355 LangItemTarget::TypeAlias(it) => TypeNs::TypeAliasId(it),
356 LangItemTarget::Struct(it) => TypeNs::AdtId(it.into()),
357 LangItemTarget::EnumVariant(it) => TypeNs::EnumVariantId(it),
358 LangItemTarget::EnumId(it) => TypeNs::AdtId(it.into()),
359 LangItemTarget::Trait(it) => TypeNs::TraitId(it),
360 LangItemTarget::Function(_)
361 | LangItemTarget::ImplDef(_)
362 | LangItemTarget::Static(_) => 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.into())));
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.local_id].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.into()))
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.local_id].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 let (def_map, _, local_id) = self.item_scope_();
695 def_map.module_id(local_id)
696 }
697
698 pub fn item_scope(&self) -> &ItemScope {
699 let (def_map, _, local_id) = self.item_scope_();
700 &def_map[local_id].scope
701 }
702
703 pub fn krate(&self) -> Crate {
704 self.module_scope.def_map.krate()
705 }
706
707 pub fn def_map(&self) -> &DefMap {
708 self.item_scope_().0
709 }
710
711 pub fn generic_def(&self) -> Option<GenericDefId> {
712 self.scopes().find_map(|scope| match scope {
713 Scope::GenericParams { def, .. } => Some(*def),
714 _ => None,
715 })
716 }
717
718 pub fn generic_params(&self) -> Option<&GenericParams> {
719 self.scopes().find_map(|scope| match scope {
720 Scope::GenericParams { params, .. } => Some(&**params),
721 _ => None,
722 })
723 }
724
725 pub fn all_generic_params(&self) -> impl Iterator<Item = (&GenericParams, &GenericDefId)> {
726 self.scopes().filter_map(|scope| match scope {
727 Scope::GenericParams { params, def } => Some((&**params, def)),
728 _ => None,
729 })
730 }
731
732 pub fn body_owner(&self) -> Option<DefWithBodyId> {
733 self.scopes().find_map(|scope| match scope {
734 Scope::ExprScope(it) => Some(it.owner),
735 _ => None,
736 })
737 }
738
739 pub fn impl_def(&self) -> Option<ImplId> {
740 self.scopes().find_map(|scope| match scope {
741 &Scope::GenericParams { def: GenericDefId::ImplId(def), .. } => Some(def),
742 _ => None,
743 })
744 }
745
746 pub fn rename_will_conflict_with_another_variable(
749 &self,
750 db: &dyn DefDatabase,
751 current_name: &Name,
752 current_name_as_path: &ModPath,
753 mut hygiene_id: HygieneId,
754 new_name: &Symbol,
755 to_be_renamed: BindingId,
756 ) -> Option<BindingId> {
757 let mut hygiene_info = hygiene_info(db, hygiene_id);
758 let mut will_be_resolved_to = None;
759 for scope in self.scopes() {
760 match scope {
761 Scope::ExprScope(scope) => {
762 for entry in scope.expr_scopes.entries(scope.scope_id) {
763 if entry.hygiene() == hygiene_id {
764 if entry.binding() == to_be_renamed {
765 return will_be_resolved_to;
768 } else if entry.name().symbol() == new_name {
769 will_be_resolved_to = Some(entry.binding());
770 }
771 }
772 }
773 }
774 Scope::MacroDefScope(macro_id) => {
775 handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id)
776 }
777 Scope::GenericParams { params, def } => {
778 if params.find_const_by_name(current_name, *def).is_some() {
779 return None;
781 }
782 }
783 Scope::BlockScope(m) => {
784 if m.resolve_path_in_value_ns(db, current_name_as_path).is_some() {
785 return None;
787 }
788 }
789 }
790 }
791 None
793 }
794
795 pub fn rename_will_conflict_with_renamed(
798 &self,
799 db: &dyn DefDatabase,
800 name: &Name,
801 name_as_path: &ModPath,
802 mut hygiene_id: HygieneId,
803 to_be_renamed: BindingId,
804 ) -> Option<BindingId> {
805 let mut hygiene_info = hygiene_info(db, hygiene_id);
806 let mut will_resolve_to_renamed = false;
807 for scope in self.scopes() {
808 match scope {
809 Scope::ExprScope(scope) => {
810 for entry in scope.expr_scopes.entries(scope.scope_id) {
811 if entry.binding() == to_be_renamed {
812 will_resolve_to_renamed = true;
813 } else if entry.hygiene() == hygiene_id && entry.name() == name {
814 if will_resolve_to_renamed {
815 return Some(entry.binding());
817 } else {
818 return None;
820 }
821 }
822 }
823 }
824 Scope::MacroDefScope(macro_id) => {
825 handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id)
826 }
827 Scope::GenericParams { params, def } => {
828 if params.find_const_by_name(name, *def).is_some() {
829 return None;
833 }
834 }
835 Scope::BlockScope(m) => {
836 if m.resolve_path_in_value_ns(db, name_as_path).is_some() {
837 return None;
838 }
839 }
840 }
841 }
842 None
843 }
844
845 #[must_use]
847 pub fn update_to_inner_scope(
848 &mut self,
849 db: &'db dyn DefDatabase,
850 owner: DefWithBodyId,
851 expr_id: ExprId,
852 ) -> UpdateGuard {
853 #[inline(always)]
854 fn append_expr_scope<'db>(
855 db: &'db dyn DefDatabase,
856 resolver: &mut Resolver<'db>,
857 owner: DefWithBodyId,
858 expr_scopes: &Arc<ExprScopes>,
859 scope_id: ScopeId,
860 ) {
861 if let Some(macro_id) = expr_scopes.macro_def(scope_id) {
862 resolver.scopes.push(Scope::MacroDefScope(**macro_id));
863 }
864 resolver.scopes.push(Scope::ExprScope(ExprScope {
865 owner,
866 expr_scopes: expr_scopes.clone(),
867 scope_id,
868 }));
869 if let Some(block) = expr_scopes.block(scope_id) {
870 let def_map = block_def_map(db, block);
871 let local_def_map = block.lookup(db).module.only_local_def_map(db);
872 resolver.scopes.push(Scope::BlockScope(ModuleItemMap {
873 def_map,
874 local_def_map,
875 module_id: DefMap::ROOT,
876 }));
877 }
881 }
882
883 let start = self.scopes.len();
884 let innermost_scope = self.scopes().find(|scope| !matches!(scope, Scope::MacroDefScope(_)));
885 match innermost_scope {
886 Some(&Scope::ExprScope(ExprScope { scope_id, ref expr_scopes, owner })) => {
887 let expr_scopes = expr_scopes.clone();
888 let scope_chain = expr_scopes
889 .scope_chain(expr_scopes.scope_for(expr_id))
890 .take_while(|&it| it != scope_id);
891 for scope_id in scope_chain {
892 append_expr_scope(db, self, owner, &expr_scopes, scope_id);
893 }
894 }
895 _ => {
896 let expr_scopes = db.expr_scopes(owner);
897 let scope_chain = expr_scopes.scope_chain(expr_scopes.scope_for(expr_id));
898
899 for scope_id in scope_chain {
900 append_expr_scope(db, self, owner, &expr_scopes, scope_id);
901 }
902 }
903 }
904 self.scopes[start..].reverse();
905 UpdateGuard(start)
906 }
907
908 pub fn reset_to_guard(&mut self, UpdateGuard(start): UpdateGuard) {
909 self.scopes.truncate(start);
910 }
911}
912
913#[inline]
914fn handle_macro_def_scope(
915 db: &dyn DefDatabase,
916 hygiene_id: &mut HygieneId,
917 hygiene_info: &mut Option<(SyntaxContext, MacroDefId)>,
918 macro_id: &MacroDefId,
919) {
920 if let Some((parent_ctx, label_macro_id)) = hygiene_info
921 && label_macro_id == macro_id
922 {
923 *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(db));
927 *hygiene_info = parent_ctx.outer_expn(db).map(|expansion| {
928 let expansion = db.lookup_intern_macro_call(expansion.into());
929 (parent_ctx.parent(db), expansion.def)
930 });
931 }
932}
933
934#[inline]
935fn hygiene_info(
936 db: &dyn DefDatabase,
937 hygiene_id: HygieneId,
938) -> Option<(SyntaxContext, MacroDefId)> {
939 if !hygiene_id.is_root() {
940 let ctx = hygiene_id.lookup();
941 ctx.outer_expn(db).map(|expansion| {
942 let expansion = db.lookup_intern_macro_call(expansion.into());
943 (ctx.parent(db), expansion.def)
944 })
945 } else {
946 None
947 }
948}
949
950pub struct UpdateGuard(usize);
951
952impl<'db> Resolver<'db> {
953 fn scopes(&self) -> impl Iterator<Item = &Scope<'db>> {
954 self.scopes.iter().rev()
955 }
956
957 fn resolve_module_path(
958 &self,
959 db: &dyn DefDatabase,
960 path: &ModPath,
961 shadow: BuiltinShadowMode,
962 ) -> PerNs {
963 let (item_map, item_local_map, module) = self.item_scope_();
964 let (module_res, segment_index) =
966 item_map.resolve_path(item_local_map, db, module, path, shadow, None);
967 if segment_index.is_some() {
968 return PerNs::none();
969 }
970 module_res
971 }
972
973 fn item_scope_(&self) -> (&DefMap, &LocalDefMap, LocalModuleId) {
975 self.scopes()
976 .find_map(|scope| match scope {
977 Scope::BlockScope(m) => Some((m.def_map, m.local_def_map, m.module_id)),
978 _ => None,
979 })
980 .unwrap_or((
981 self.module_scope.def_map,
982 self.module_scope.local_def_map,
983 self.module_scope.module_id,
984 ))
985 }
986}
987
988#[derive(Copy, Clone, Debug, PartialEq, Eq)]
989pub enum ScopeDef {
990 ModuleDef(ModuleDefId),
991 Unknown,
992 ImplSelfType(ImplId),
993 AdtSelfType(AdtId),
994 GenericParam(GenericParamId),
995 Local(BindingId),
996 Label(LabelId),
997}
998
999impl<'db> Scope<'db> {
1000 fn process_names(&self, acc: &mut ScopeNames, db: &'db dyn DefDatabase) {
1001 match self {
1002 Scope::BlockScope(m) => {
1003 m.def_map[m.module_id].scope.entries().for_each(|(name, def)| {
1004 acc.add_per_ns(name, def);
1005 });
1006 m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, macs)| {
1007 macs.iter().for_each(|&mac| {
1008 acc.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)));
1009 })
1010 });
1011 }
1012 &Scope::GenericParams { ref params, def: parent } => {
1013 if let GenericDefId::ImplId(impl_) = parent {
1014 acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::ImplSelfType(impl_));
1015 } else if let GenericDefId::AdtId(adt) = parent {
1016 acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::AdtSelfType(adt));
1017 }
1018
1019 for (local_id, param) in params.iter_type_or_consts() {
1020 if let Some(name) = ¶m.name() {
1021 let id = TypeOrConstParamId { parent, local_id };
1022 let data = &db.generic_params(parent)[local_id];
1023 acc.add(
1024 name,
1025 ScopeDef::GenericParam(match data {
1026 TypeOrConstParamData::TypeParamData(_) => {
1027 GenericParamId::TypeParamId(TypeParamId::from_unchecked(id))
1028 }
1029 TypeOrConstParamData::ConstParamData(_) => {
1030 GenericParamId::ConstParamId(ConstParamId::from_unchecked(id))
1031 }
1032 }),
1033 );
1034 }
1035 }
1036 for (local_id, param) in params.iter_lt() {
1037 let id = LifetimeParamId { parent, local_id };
1038 acc.add(¶m.name, ScopeDef::GenericParam(id.into()))
1039 }
1040 }
1041 Scope::ExprScope(scope) => {
1042 if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) {
1043 acc.add(&name, ScopeDef::Label(label))
1044 }
1045 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
1046 acc.add_local(e.name(), e.binding());
1047 });
1048 }
1049 Scope::MacroDefScope(_) => {}
1050 }
1051 }
1052}
1053
1054pub fn resolver_for_scope(
1055 db: &dyn DefDatabase,
1056 owner: DefWithBodyId,
1057 scope_id: Option<ScopeId>,
1058) -> Resolver<'_> {
1059 let r = owner.resolver(db);
1060 let scopes = db.expr_scopes(owner);
1061 resolver_for_scope_(db, scopes, scope_id, r, owner)
1062}
1063
1064fn resolver_for_scope_<'db>(
1065 db: &'db dyn DefDatabase,
1066 scopes: Arc<ExprScopes>,
1067 scope_id: Option<ScopeId>,
1068 mut r: Resolver<'db>,
1069 owner: DefWithBodyId,
1070) -> Resolver<'db> {
1071 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
1072 r.scopes.reserve(scope_chain.len());
1073
1074 for scope in scope_chain.into_iter().rev() {
1075 if let Some(block) = scopes.block(scope) {
1076 let def_map = block_def_map(db, block);
1077 let local_def_map = block.lookup(db).module.only_local_def_map(db);
1078 r = r.push_block_scope(def_map, local_def_map);
1079 }
1083 if let Some(macro_id) = scopes.macro_def(scope) {
1084 r = r.push_scope(Scope::MacroDefScope(**macro_id));
1085 }
1086
1087 r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
1088 }
1089 r
1090}
1091
1092impl<'db> Resolver<'db> {
1093 fn push_scope(mut self, scope: Scope<'db>) -> Resolver<'db> {
1094 self.scopes.push(scope);
1095 self
1096 }
1097
1098 fn push_generic_params_scope(
1099 self,
1100 db: &'db dyn DefDatabase,
1101 def: GenericDefId,
1102 ) -> Resolver<'db> {
1103 let params = db.generic_params(def);
1104 self.push_scope(Scope::GenericParams { def, params })
1105 }
1106
1107 fn push_block_scope(
1108 self,
1109 def_map: &'db DefMap,
1110 local_def_map: &'db LocalDefMap,
1111 ) -> Resolver<'db> {
1112 self.push_scope(Scope::BlockScope(ModuleItemMap {
1113 def_map,
1114 local_def_map,
1115 module_id: DefMap::ROOT,
1116 }))
1117 }
1118
1119 fn push_expr_scope(
1120 self,
1121 owner: DefWithBodyId,
1122 expr_scopes: Arc<ExprScopes>,
1123 scope_id: ScopeId,
1124 ) -> Resolver<'db> {
1125 self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
1126 }
1127}
1128
1129impl<'db> ModuleItemMap<'db> {
1130 fn resolve_path_in_value_ns(
1131 &self,
1132 db: &'db dyn DefDatabase,
1133 path: &ModPath,
1134 ) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> {
1135 let (module_def, unresolved_idx, prefix_info) = self.def_map.resolve_path_locally(
1136 self.local_def_map,
1137 db,
1138 self.module_id,
1139 path,
1140 BuiltinShadowMode::Other,
1141 );
1142 match unresolved_idx {
1143 None => {
1144 let (value, import) = to_value_ns(module_def)?;
1145 Some((ResolveValueResult::ValueNs(value, import), prefix_info))
1146 }
1147 Some(unresolved_idx) => {
1148 let def = module_def.take_types_full()?;
1149 let ty = match def.def {
1150 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
1151 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
1152 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
1153 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
1154
1155 ModuleDefId::ModuleId(_)
1156 | ModuleDefId::FunctionId(_)
1157 | ModuleDefId::EnumVariantId(_)
1158 | ModuleDefId::ConstId(_)
1159 | ModuleDefId::MacroId(_)
1160 | ModuleDefId::StaticId(_) => return None,
1161 };
1162 Some((ResolveValueResult::Partial(ty, unresolved_idx, def.import), prefix_info))
1163 }
1164 }
1165 }
1166
1167 fn resolve_path_in_type_ns(
1168 &self,
1169 db: &dyn DefDatabase,
1170 path: &ModPath,
1171 ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)>
1172 {
1173 let (module_def, idx, prefix_info) = self.def_map.resolve_path_locally(
1174 self.local_def_map,
1175 db,
1176 self.module_id,
1177 path,
1178 BuiltinShadowMode::Other,
1179 );
1180 let (res, import) = to_type_ns(module_def)?;
1181 Some((res, idx, import, prefix_info))
1182 }
1183}
1184
1185fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportOrGlob>)> {
1186 let (def, import) = per_ns.take_values_import()?;
1187 let res = match def {
1188 ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
1189 ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
1190 ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
1191 ModuleDefId::ConstId(it) => ValueNs::ConstId(it),
1192 ModuleDefId::StaticId(it) => ValueNs::StaticId(it),
1193
1194 ModuleDefId::AdtId(AdtId::EnumId(_) | AdtId::UnionId(_))
1195 | ModuleDefId::TraitId(_)
1196 | ModuleDefId::TypeAliasId(_)
1197 | ModuleDefId::BuiltinType(_)
1198 | ModuleDefId::MacroId(_)
1199 | ModuleDefId::ModuleId(_) => return None,
1200 };
1201 Some((res, import))
1202}
1203
1204fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
1205 let def = per_ns.take_types_full()?;
1206 let res = match def.def {
1207 ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
1208 ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
1209
1210 ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it),
1211 ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it),
1212
1213 ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
1214
1215 ModuleDefId::ModuleId(it) => TypeNs::ModuleId(it),
1216
1217 ModuleDefId::FunctionId(_)
1218 | ModuleDefId::ConstId(_)
1219 | ModuleDefId::MacroId(_)
1220 | ModuleDefId::StaticId(_) => return None,
1221 };
1222 Some((res, def.import))
1223}
1224
1225#[derive(Default)]
1226struct ScopeNames {
1227 map: FxIndexMap<Name, SmallVec<[ScopeDef; 1]>>,
1228}
1229
1230impl ScopeNames {
1231 fn add(&mut self, name: &Name, def: ScopeDef) {
1232 let set = self.map.entry(name.clone()).or_default();
1233 if !set.contains(&def) {
1234 set.push(def)
1235 }
1236 }
1237 fn add_per_ns(&mut self, name: &Name, def: PerNs) {
1238 if let Some(ty) = &def.types {
1239 self.add(name, ScopeDef::ModuleDef(ty.def))
1240 }
1241 if let Some(def) = &def.values {
1242 self.add(name, ScopeDef::ModuleDef(def.def))
1243 }
1244 if let Some(mac) = &def.macros {
1245 self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac.def)))
1246 }
1247 if def.is_none() {
1248 self.add(name, ScopeDef::Unknown)
1249 }
1250 }
1251 fn add_local(&mut self, name: &Name, binding: BindingId) {
1252 let set = self.map.entry(name.clone()).or_default();
1253 if set.iter().any(|it| matches!(it, &ScopeDef::Local(_))) {
1259 cov_mark::hit!(shadowing_shows_single_completion);
1260 return;
1261 }
1262 set.push(ScopeDef::Local(binding))
1263 }
1264}
1265
1266pub trait HasResolver: Copy {
1267 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_>;
1269}
1270
1271impl HasResolver for ModuleId {
1272 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1273 let (mut def_map, local_def_map) = self.local_def_map(db);
1274 let mut module_id = self.local_id;
1275
1276 if !self.is_block_module() {
1277 return Resolver {
1278 scopes: vec![],
1279 module_scope: ModuleItemMap { def_map, local_def_map, module_id },
1280 };
1281 }
1282
1283 let mut modules: SmallVec<[_; 1]> = smallvec![];
1284 while let Some(parent) = def_map.parent() {
1285 let block_def_map = mem::replace(&mut def_map, parent.def_map(db));
1286 modules.push(block_def_map);
1287 if !parent.is_block_module() {
1288 module_id = parent.local_id;
1289 break;
1290 }
1291 }
1292 let mut resolver = Resolver {
1293 scopes: Vec::with_capacity(modules.len()),
1294 module_scope: ModuleItemMap { def_map, local_def_map, module_id },
1295 };
1296 for def_map in modules.into_iter().rev() {
1297 resolver = resolver.push_block_scope(def_map, local_def_map);
1298 }
1299 resolver
1300 }
1301}
1302
1303impl HasResolver for CrateRootModuleId {
1304 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1305 let (def_map, local_def_map) = self.local_def_map(db);
1306 Resolver {
1307 scopes: vec![],
1308 module_scope: ModuleItemMap { def_map, local_def_map, module_id: DefMap::ROOT },
1309 }
1310 }
1311}
1312
1313impl HasResolver for TraitId {
1314 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1315 lookup_resolver(db, self).push_generic_params_scope(db, self.into())
1316 }
1317}
1318
1319impl<T: Into<AdtId> + Copy> HasResolver for T {
1320 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1321 let def = self.into();
1322 def.module(db).resolver(db).push_generic_params_scope(db, def.into())
1323 }
1324}
1325
1326impl HasResolver for FunctionId {
1327 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1328 lookup_resolver(db, self).push_generic_params_scope(db, self.into())
1329 }
1330}
1331
1332impl HasResolver for ConstId {
1333 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1334 lookup_resolver(db, self)
1335 }
1336}
1337
1338impl HasResolver for StaticId {
1339 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1340 lookup_resolver(db, self)
1341 }
1342}
1343
1344impl HasResolver for TypeAliasId {
1345 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1346 lookup_resolver(db, self).push_generic_params_scope(db, self.into())
1347 }
1348}
1349
1350impl HasResolver for ImplId {
1351 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1352 self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
1353 }
1354}
1355
1356impl HasResolver for ExternBlockId {
1357 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1358 lookup_resolver(db, self)
1360 }
1361}
1362
1363impl HasResolver for ExternCrateId {
1364 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1365 lookup_resolver(db, self)
1366 }
1367}
1368
1369impl HasResolver for UseId {
1370 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1371 lookup_resolver(db, self)
1372 }
1373}
1374
1375impl HasResolver for DefWithBodyId {
1376 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1377 match self {
1378 DefWithBodyId::ConstId(c) => c.resolver(db),
1379 DefWithBodyId::FunctionId(f) => f.resolver(db),
1380 DefWithBodyId::StaticId(s) => s.resolver(db),
1381 DefWithBodyId::VariantId(v) => v.resolver(db),
1382 }
1383 }
1384}
1385
1386impl HasResolver for ItemContainerId {
1387 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1388 match self {
1389 ItemContainerId::ModuleId(it) => it.resolver(db),
1390 ItemContainerId::TraitId(it) => it.resolver(db),
1391 ItemContainerId::ImplId(it) => it.resolver(db),
1392 ItemContainerId::ExternBlockId(it) => it.resolver(db),
1393 }
1394 }
1395}
1396
1397impl HasResolver for GenericDefId {
1398 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1399 match self {
1400 GenericDefId::FunctionId(inner) => inner.resolver(db),
1401 GenericDefId::AdtId(adt) => adt.resolver(db),
1402 GenericDefId::TraitId(inner) => inner.resolver(db),
1403 GenericDefId::TypeAliasId(inner) => inner.resolver(db),
1404 GenericDefId::ImplId(inner) => inner.resolver(db),
1405 GenericDefId::ConstId(inner) => inner.resolver(db),
1406 GenericDefId::StaticId(inner) => inner.resolver(db),
1407 }
1408 }
1409}
1410
1411impl HasResolver for EnumVariantId {
1412 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1413 self.lookup(db).parent.resolver(db)
1414 }
1415}
1416
1417impl HasResolver for VariantId {
1418 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1419 match self {
1420 VariantId::EnumVariantId(it) => it.resolver(db),
1421 VariantId::StructId(it) => it.resolver(db),
1422 VariantId::UnionId(it) => it.resolver(db),
1423 }
1424 }
1425}
1426
1427impl HasResolver for MacroId {
1428 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1429 match self {
1430 MacroId::Macro2Id(it) => it.resolver(db),
1431 MacroId::MacroRulesId(it) => it.resolver(db),
1432 MacroId::ProcMacroId(it) => it.resolver(db),
1433 }
1434 }
1435}
1436
1437impl HasResolver for Macro2Id {
1438 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1439 lookup_resolver(db, self)
1440 }
1441}
1442
1443impl HasResolver for ProcMacroId {
1444 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1445 lookup_resolver(db, self)
1446 }
1447}
1448
1449impl HasResolver for MacroRulesId {
1450 fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
1451 lookup_resolver(db, self)
1452 }
1453}
1454
1455fn lookup_resolver(
1456 db: &dyn DefDatabase,
1457 lookup: impl Lookup<Database = dyn DefDatabase, Data = impl AstIdLoc<Container = impl HasResolver>>,
1458) -> Resolver<'_> {
1459 lookup.lookup(db).container().resolver(db)
1460}