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