about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-02 17:38:26 +0000
committerbors <bors@rust-lang.org>2022-09-02 17:38:26 +0000
commitafa374e58e0bce33b666ee83baa24f16cb486a75 (patch)
treeff0717071073a1c6aa74a78f5812de7b66e85a74
parentf27f98d4bb1a5f83ffd41f9e5e81c5595cd6ebbf (diff)
parent894aa0ed0d181668ca33e4c5d2e08b4a49ae20d7 (diff)
downloadrust-afa374e58e0bce33b666ee83baa24f16cb486a75.tar.gz
rust-afa374e58e0bce33b666ee83baa24f16cb486a75.zip
Auto merge of #13175 - Veykril:resolver, r=Veykril
Clarify the state of (extern) preludes for block def maps
-rw-r--r--crates/hir-def/src/nameres.rs4
-rw-r--r--crates/hir-def/src/nameres/collector.rs13
-rw-r--r--crates/hir-def/src/resolver.rs103
3 files changed, 60 insertions, 60 deletions
diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs
index fc8444394cf..2e392f741bf 100644
--- a/crates/hir-def/src/nameres.rs
+++ b/crates/hir-def/src/nameres.rs
@@ -98,7 +98,11 @@ pub struct DefMap {
     /// The prelude module for this crate. This either comes from an import
     /// marked with the `prelude_import` attribute, or (in the normal case) from
     /// a dependency (`std` or `core`).
+    /// The prelude is empty for non-block DefMaps (unless `#[prelude_import]` was used,
+    /// but that attribute is nightly and when used in a block, it affects resolution globally
+    /// so we aren't handling this correctly anyways).
     prelude: Option<ModuleId>,
+    /// The extern prelude is only populated for non-block DefMaps
     extern_prelude: FxHashMap<Name, ModuleId>,
 
     /// Side table for resolving derive helpers.
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index ee27aa2554a..495bbe4579f 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -512,10 +512,9 @@ impl DefCollector<'_> {
             Edition::Edition2021 => name![rust_2021],
         };
 
-        let path_kind = if self.def_map.edition == Edition::Edition2015 {
-            PathKind::Plain
-        } else {
-            PathKind::Abs
+        let path_kind = match self.def_map.edition {
+            Edition::Edition2015 => PathKind::Plain,
+            _ => PathKind::Abs,
         };
         let path =
             ModPath::from_segments(path_kind, [krate.clone(), name![prelude], edition].into_iter());
@@ -535,7 +534,6 @@ impl DefCollector<'_> {
             match per_ns.types {
                 Some((ModuleDefId::ModuleId(m), _)) => {
                     self.def_map.prelude = Some(m);
-                    return;
                 }
                 types => {
                     tracing::debug!(
@@ -850,7 +848,10 @@ impl DefCollector<'_> {
                 tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
 
                 // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
-                if import.is_extern_crate && module_id == self.def_map.root {
+                if import.is_extern_crate
+                    && self.def_map.block.is_none()
+                    && module_id == self.def_map.root
+                {
                     if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
                     {
                         self.def_map.extern_prelude.insert(name.clone(), def);
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 769aa9dcb0c..8aa5973cac5 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -368,34 +368,43 @@ impl Resolver {
         for scope in self.scopes() {
             scope.process_names(&mut res, db);
         }
-        process_module_scope_names(&mut res, db, &self.module_scope);
+        let ModuleItemMap { ref def_map, module_id } = self.module_scope;
+        // FIXME: should we provide `self` here?
+        // f(
+        //     Name::self_param(),
+        //     PerNs::types(Resolution::Def {
+        //         def: m.module.into(),
+        //     }),
+        // );
+        def_map[module_id].scope.entries().for_each(|(name, def)| {
+            res.add_per_ns(name, def);
+        });
+        def_map[module_id].scope.legacy_macros().for_each(|(name, macs)| {
+            macs.iter().for_each(|&mac| {
+                res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac))));
+            })
+        });
+        def_map.extern_prelude().for_each(|(name, &def)| {
+            res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
+        });
+        BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
+            res.add_per_ns(name, def);
+        });
+        if let Some(prelude) = def_map.prelude() {
+            let prelude_def_map = prelude.def_map(db);
+            for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
+                res.add_per_ns(name, def)
+            }
+        }
         res.map
     }
 
     pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
         let mut traits = FxHashSet::default();
 
-        let collect_module_traits = |traits: &mut FxHashSet<_>, m: &ModuleItemMap| {
-            if let Some(prelude) = m.def_map.prelude() {
-                let prelude_def_map = prelude.def_map(db);
-                traits.extend(prelude_def_map[prelude.local_id].scope.traits());
-            }
-            traits.extend(m.def_map[m.module_id].scope.traits());
-
-            // Add all traits that are in scope because of the containing DefMaps
-            m.def_map.with_ancestor_maps(db, m.module_id, &mut |def_map, module| {
-                if let Some(prelude) = def_map.prelude() {
-                    let prelude_def_map = prelude.def_map(db);
-                    traits.extend(prelude_def_map[prelude.local_id].scope.traits());
-                }
-                traits.extend(def_map[module].scope.traits());
-                None::<()>
-            });
-        };
-
         for scope in self.scopes() {
             match scope {
-                Scope::BlockScope(m) => collect_module_traits(&mut traits, m),
+                Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()),
                 &Scope::ImplDefScope(impl_) => {
                     if let Some(target_trait) = &db.impl_data(impl_).target_trait {
                         if let Some(TypeNs::TraitId(trait_)) =
@@ -409,7 +418,13 @@ impl Resolver {
             }
         }
 
-        collect_module_traits(&mut traits, &self.module_scope);
+        // Fill in the prelude traits
+        if let Some(prelude) = self.module_scope.def_map.prelude() {
+            let prelude_def_map = prelude.def_map(db);
+            traits.extend(prelude_def_map[prelude.local_id].scope.traits());
+        }
+        // Fill in module visible traits
+        traits.extend(self.module_scope.def_map[self.module_scope.module_id].scope.traits());
         traits
     }
 
@@ -493,42 +508,22 @@ pub enum ScopeDef {
     Label(LabelId),
 }
 
-fn process_module_scope_names(acc: &mut ScopeNames, db: &dyn DefDatabase, m: &ModuleItemMap) {
-    // FIXME: should we provide `self` here?
-    // f(
-    //     Name::self_param(),
-    //     PerNs::types(Resolution::Def {
-    //         def: m.module.into(),
-    //     }),
-    // );
-    m.def_map[m.module_id].scope.entries().for_each(|(name, def)| {
-        acc.add_per_ns(name, def);
-    });
-    m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, macs)| {
-        macs.iter().for_each(|&mac| {
-            acc.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac))));
-        })
-    });
-    m.def_map.extern_prelude().for_each(|(name, &def)| {
-        acc.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
-    });
-    if m.def_map.block_id().is_none() {
-        BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
-            acc.add_per_ns(name, def);
-        });
-    }
-    if let Some(prelude) = m.def_map.prelude() {
-        let prelude_def_map = prelude.def_map(db);
-        for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
-            acc.add_per_ns(name, def)
-        }
-    }
-}
-
 impl Scope {
     fn process_names(&self, acc: &mut ScopeNames, db: &dyn DefDatabase) {
         match self {
-            Scope::BlockScope(m) => process_module_scope_names(acc, db, m),
+            Scope::BlockScope(m) => {
+                m.def_map[m.module_id].scope.entries().for_each(|(name, def)| {
+                    acc.add_per_ns(name, def);
+                });
+                m.def_map[m.module_id].scope.legacy_macros().for_each(|(name, macs)| {
+                    macs.iter().for_each(|&mac| {
+                        acc.add(
+                            name,
+                            ScopeDef::ModuleDef(ModuleDefId::MacroId(MacroId::from(mac))),
+                        );
+                    })
+                });
+            }
             Scope::GenericParams { params, def: parent } => {
                 let parent = *parent;
                 for (local_id, param) in params.type_or_consts.iter() {