hir_def/
resolver.rs

1//! Name resolution façade.
2use 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    /// The stack of scopes, where the inner-most scope is the last item.
47    ///
48    /// When using, you generally want to process the scopes in reverse order,
49    /// there's `scopes` *method* for that.
50    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    /// All the items and imported names of a module
86    BlockScope(ModuleItemMap<'db>),
87    /// Brings the generic parameters of an item into scope as well as the `Self` type alias /
88    /// generic for ADTs and impls.
89    GenericParams { def: GenericDefId, params: Arc<GenericParams> },
90    /// Local bindings
91    ExprScope(ExprScope),
92    /// Macro definition inside bodies that affects all paths after it in the same block.
93    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    // Yup, enum variants are added to the types ns, but any usage of variant as
103    // type is an error.
104    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    /// Resolve known trait from std, like `std::futures::Future`
138    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    /// Resolve known struct from std, like `std::boxed::Box`
147    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    /// Resolve known enum from std, like `std::result::Result`
156    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                // Remaining segments start from 0 because lang paths have no segments other than the remaining.
365                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 a path of the shape `u16::from_le_bytes` failed to resolve at all, then we fall back
469        // to resolving to the primitive type, to allow this to still work in the presence of
470        // `use core::u16;`.
471        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    /// Returns a set of names available in the current scope.
542    ///
543    /// Note that this is a somewhat fuzzy concept -- internally, the compiler
544    /// doesn't necessary follow a strict scoping discipline. Rather, it just
545    /// tells for each ident what it resolves to.
546    ///
547    /// A good example is something like `str::from_utf8`. From scopes point of
548    /// view, this code is erroneous -- both `str` module and `str` type occupy
549    /// the same type namespace.
550    ///
551    /// We don't try to model that super-correctly -- this functionality is
552    /// primarily exposed for completions.
553    ///
554    /// Note that in Rust one name can be bound to several items:
555    ///
556    /// ```
557    /// # #![allow(non_camel_case_types)]
558    /// macro_rules! t { () => (()) }
559    /// type t = t!();
560    /// const t: t = t!();
561    /// ```
562    ///
563    /// That's why we return a multimap.
564    ///
565    /// The shadowing is accounted for: in
566    ///
567    /// ```ignore
568    /// let it = 92;
569    /// {
570    ///     let it = 92;
571    ///     $0
572    /// }
573    /// ```
574    ///
575    /// there will be only one entry for `it` in the result.
576    ///
577    /// The result is ordered *roughly* from the innermost scope to the
578    /// outermost: when the name is introduced in two namespaces in two scopes,
579    /// we use the position of the first scope.
580    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        // FIXME: should we provide `self` here?
590        // f(
591        //     Name::self_param(),
592        //     PerNs::types(Resolution::Def {
593        //         def: m.module.into(),
594        //     }),
595        // );
596        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    /// Note: Not to be used directly within hir-def/hir-ty
626    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                // If there is a rename (`as x`), extract the renamed name, or remove the `extern crate`
637                // if it is an underscore.
638                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        // FIXME(trait_alias): Trait alias brings aliased traits in scope! Note that supertraits of
655        // aliased traits are NOT brought in scope (unless also aliased).
656        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        // Fill in the prelude traits
675        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        // Fill in module visible traits
680        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    /// Checks if we rename `renamed` (currently named `current_name`) to `new_name`, will the meaning of this reference
747    /// (that contains `current_name` path) change from `renamed` to some another variable (returned as `Some`).
748    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                                // This currently resolves to our renamed variable, now `will_be_resolved_to`
766                                // contains `Some` if the meaning will change or `None` if not.
767                                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                        // It does not resolve to our renamed variable.
780                        return None;
781                    }
782                }
783                Scope::BlockScope(m) => {
784                    if m.resolve_path_in_value_ns(db, current_name_as_path).is_some() {
785                        // It does not resolve to our renamed variable.
786                        return None;
787                    }
788                }
789            }
790        }
791        // It does not resolve to our renamed variable.
792        None
793    }
794
795    /// Checks if we rename `renamed` to `name`, will the meaning of this reference (that contains `name` path) change
796    /// from some other variable (returned as `Some`) to `renamed`.
797    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                                // This will resolve to the renamed variable before it resolves to the original variable.
816                                return Some(entry.binding());
817                            } else {
818                                // This will resolve to the original variable.
819                                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                        // Here and below, it might actually resolve to our renamed variable - in which case it'll
830                        // hide the generic parameter or some other thing (not a variable). We don't check for that
831                        // because due to naming conventions, it is rare that variable will shadow a non-variable.
832                        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    /// `expr_id` is required to be an expression id that comes after the top level expression scope in the given resolver
846    #[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                // FIXME: This adds as many module scopes as there are blocks, but resolving in each
878                // already traverses all parents, so this is O(n²). I think we could only store the
879                // innermost module scope instead?
880            }
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        // A macro is allowed to refer to variables from before its declaration.
924        // Therefore, if we got to the rib of its declaration, give up its hygiene
925        // and use its parent expansion.
926        *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        // This method resolves `path` just like import paths, so no expected macro subns is given.
965        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    /// The innermost block scope that contains items or the module scope that contains this resolver.
974    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) = &param.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(&param.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            // FIXME: This adds as many module scopes as there are blocks, but resolving in each
1080            // already traverses all parents, so this is O(n²). I think we could only store the
1081            // innermost module scope instead?
1082        }
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        // XXX: hack, account for local (and only local) shadowing.
1254        //
1255        // This should be somewhat more principled and take namespaces into
1256        // accounts, but, alas, scoping rules are a hoax. `str` type and `str`
1257        // module can be both available in the same scope.
1258        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    /// Builds a resolver for type references inside this def.
1268    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        // Same as parent's
1359        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}