Skip to main content

hir_def/
resolver.rs

1//! Name resolution façade.
2use 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    /// The stack of scopes, where the inner-most scope is the last item.
46    ///
47    /// When using, you generally want to process the scopes in reverse order,
48    /// there's `scopes` *method* for that.
49    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    /// All the items and imported names of a module
85    BlockScope(ModuleItemMap<'db>),
86    /// Brings the generic parameters of an item into scope as well as the `Self` type alias /
87    /// generic for ADTs and impls.
88    GenericParams { def: GenericDefId, params: &'db GenericParams },
89    /// Local bindings
90    ExprScope(ExprScope<'db>),
91    /// Macro definition inside bodies that affects all paths after it in the same block.
92    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    // Yup, enum variants are added to the types ns, but any usage of variant as
102    // type is an error.
103    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    /// Resolve known trait from std, like `std::futures::Future`
137    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    /// Resolve known struct from std, like `std::boxed::Box`
146    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    /// Resolve known enum from std, like `std::result::Result`
159    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                // Remaining segments start from 0 because lang paths have no segments other than the remaining.
396                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 a path of the shape `u16::from_le_bytes` failed to resolve at all, then we fall back
504        // to resolving to the primitive type, to allow this to still work in the presence of
505        // `use core::u16;`.
506        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    /// Returns a set of names available in the current scope.
578    ///
579    /// Note that this is a somewhat fuzzy concept -- internally, the compiler
580    /// doesn't necessary follow a strict scoping discipline. Rather, it just
581    /// tells for each ident what it resolves to.
582    ///
583    /// A good example is something like `str::from_utf8`. From scopes point of
584    /// view, this code is erroneous -- both `str` module and `str` type occupy
585    /// the same type namespace.
586    ///
587    /// We don't try to model that super-correctly -- this functionality is
588    /// primarily exposed for completions.
589    ///
590    /// Note that in Rust one name can be bound to several items:
591    ///
592    /// ```
593    /// # #![allow(non_camel_case_types)]
594    /// macro_rules! t { () => (()) }
595    /// type t = t!();
596    /// const t: t = t!();
597    /// ```
598    ///
599    /// That's why we return a multimap.
600    ///
601    /// The shadowing is accounted for: in
602    ///
603    /// ```ignore
604    /// let it = 92;
605    /// {
606    ///     let it = 92;
607    ///     $0
608    /// }
609    /// ```
610    ///
611    /// there will be only one entry for `it` in the result.
612    ///
613    /// The result is ordered *roughly* from the innermost scope to the
614    /// outermost: when the name is introduced in two namespaces in two scopes,
615    /// we use the position of the first scope.
616    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        // FIXME: should we provide `self` here?
626        // f(
627        //     Name::self_param(),
628        //     PerNs::types(Resolution::Def {
629        //         def: m.module.into(),
630        //     }),
631        // );
632        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    /// Note: Not to be used directly within hir-def/hir-ty
662    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                // If there is a rename (`as x`), extract the renamed name, or remove the `extern crate`
673                // if it is an underscore.
674                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        // FIXME(trait_alias): Trait alias brings aliased traits in scope! Note that supertraits of
691        // aliased traits are NOT brought in scope (unless also aliased).
692        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        // Fill in the prelude traits
711        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        // Fill in module visible traits
716        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    /// Checks if we rename `renamed` (currently named `current_name`) to `new_name`, will the meaning of this reference
796    /// (that contains `current_name` path) change from `renamed` to some another variable (returned as `Some`).
797    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                                // This currently resolves to our renamed variable, now `will_be_resolved_to`
815                                // contains `Some` if the meaning will change or `None` if not.
816                                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                        // It does not resolve to our renamed variable.
829                        return None;
830                    }
831                }
832                Scope::BlockScope(m) => {
833                    if m.resolve_path_in_value_ns(db, current_name_as_path).is_some() {
834                        // It does not resolve to our renamed variable.
835                        return None;
836                    }
837                }
838            }
839        }
840        // It does not resolve to our renamed variable.
841        None
842    }
843
844    /// Checks if we rename `renamed` to `name`, will the meaning of this reference (that contains `name` path) change
845    /// from some other variable (returned as `Some`) to `renamed`.
846    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                                // This will resolve to the renamed variable before it resolves to the original variable.
865                                return Some(entry.binding());
866                            } else {
867                                // This will resolve to the original variable.
868                                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                        // Here and below, it might actually resolve to our renamed variable - in which case it'll
879                        // hide the generic parameter or some other thing (not a variable). We don't check for that
880                        // because due to naming conventions, it is rare that variable will shadow a non-variable.
881                        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    /// `expr_id` is required to be an expression id that comes after the top level expression scope in the given resolver
895    #[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                // FIXME: This adds as many module scopes as there are blocks, but resolving in each
932                // already traverses all parents, so this is O(n²). I think we could only store the
933                // innermost module scope instead?
934            }
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        // A macro is allowed to refer to variables from before its declaration.
977        // Therefore, if we got to the rib of its declaration, give up its hygiene
978        // and use its parent expansion.
979        *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        // This method resolves `path` just like import paths, so no expected macro subns is given.
1018        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    /// The innermost block scope that contains items or the module scope that contains this resolver.
1027    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) = &param.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(&param.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            // Using `DefMap::ROOT` is okay here since inside modules other than the root,
1136            // there can't directly be expressions.
1137            r = r.push_block_scope(def_map, local_def_map, def_map.root);
1138            // FIXME: This adds as many module scopes as there are blocks, but resolving in each
1139            // already traverses all parents, so this is O(n²). I think we could only store the
1140            // innermost module scope instead?
1141        }
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        // If we cannot resolve to value ns, but we can resolve to a proc macro, and this is the crate
1254        // defining this proc macro - inside this crate, we should treat the macro as a function.
1255        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        // XXX: hack, account for local (and only local) shadowing.
1325        //
1326        // This should be somewhat more principled and take namespaces into
1327        // accounts, but, alas, scoping rules are a hoax. `str` type and `str`
1328        // module can be both available in the same scope.
1329        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    /// Builds a resolver for type references inside this def.
1339    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        // Consts can have generic params on nightly. Furthermore they're a `GenericDefId`,
1396        // so not pushing a generic params scope here complicates things (e.g. `TypeOwnerId` tracking).
1397        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        // Same as parent's
1422        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}