about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-06-15 12:28:40 +0200
committerLukas Wirth <lukastw97@gmail.com>2023-06-19 14:15:08 +0200
commit9476fdaaa96323800b43c528e59617b14908d6a2 (patch)
tree8a0cae8972e172b44dd18f2506e4be18bb80971f
parent0bde3fc77eb01163aa632ebf029bced142655475 (diff)
downloadrust-9476fdaaa96323800b43c528e59617b14908d6a2.tar.gz
rust-9476fdaaa96323800b43c528e59617b14908d6a2.zip
HIR ExternCrateDecl
-rw-r--r--crates/hir-def/src/attr.rs2
-rw-r--r--crates/hir-def/src/data.rs32
-rw-r--r--crates/hir-def/src/db.rs7
-rw-r--r--crates/hir-def/src/dyn_map/keys.rs5
-rw-r--r--crates/hir-def/src/item_scope.rs13
-rw-r--r--crates/hir-def/src/lib.rs11
-rw-r--r--crates/hir-def/src/nameres/collector.rs5
-rw-r--r--crates/hir-def/src/resolver.rs14
-rw-r--r--crates/hir-ty/src/diagnostics/decl_check.rs1
-rw-r--r--crates/hir/src/attrs.rs1
10 files changed, 75 insertions, 16 deletions
diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs
index bab3bbc2329..09891f4452e 100644
--- a/crates/hir-def/src/attr.rs
+++ b/crates/hir-def/src/attr.rs
@@ -462,6 +462,7 @@ impl AttrsWithOwner {
                 }
             },
             AttrDefId::ExternBlockId(it) => attrs_from_item_tree_loc(db, it),
+            AttrDefId::ExternCrateId(it) => attrs_from_item_tree_loc(db, it),
         };
 
         let attrs = raw_attrs.filter(db.upcast(), def.krate(db));
@@ -546,6 +547,7 @@ impl AttrsWithOwner {
                     .map(|source| ast::AnyHasAttrs::new(source[id.local_id].clone())),
             },
             AttrDefId::ExternBlockId(id) => any_has_attrs(db, id),
+            AttrDefId::ExternCrateId(id) => any_has_attrs(db, id),
         };
 
         AttrSourceMap::new(owner.as_ref().map(|node| node as &dyn HasAttrs))
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index 40e6a430878..4a9f08dca6d 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -24,11 +24,12 @@ use crate::{
         proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind},
         DefMap, MacroSubNs,
     },
+    path::ImportAlias,
     type_ref::{TraitRef, TypeBound, TypeRef},
     visibility::RawVisibility,
-    AssocItemId, AstIdWithPath, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
-    Intern, ItemContainerId, ItemLoc, Lookup, Macro2Id, MacroRulesId, ModuleId, ProcMacroId,
-    StaticId, TraitAliasId, TraitId, TypeAliasId, TypeAliasLoc,
+    AssocItemId, AstIdWithPath, ConstId, ConstLoc, ExternCrateId, FunctionId, FunctionLoc,
+    HasModule, ImplId, Intern, ItemContainerId, ItemLoc, Lookup, Macro2Id, MacroRulesId, ModuleId,
+    ProcMacroId, StaticId, TraitAliasId, TraitId, TypeAliasId, TypeAliasLoc,
 };
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -424,6 +425,7 @@ impl MacroRulesData {
         Arc::new(MacroRulesData { name: makro.name.clone(), macro_export })
     }
 }
+
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ProcMacroData {
     pub name: Name,
@@ -461,6 +463,30 @@ impl ProcMacroData {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ExternCrateDeclData {
+    pub name: Name,
+    pub alias: Option<ImportAlias>,
+    pub visibility: RawVisibility,
+}
+
+impl ExternCrateDeclData {
+    pub(crate) fn extern_crate_decl_data_query(
+        db: &dyn DefDatabase,
+        extern_crate: ExternCrateId,
+    ) -> Arc<ExternCrateDeclData> {
+        let loc = extern_crate.lookup(db);
+        let item_tree = loc.id.item_tree(db);
+        let extern_crate = &item_tree[loc.id.value];
+
+        Arc::new(Self {
+            name: extern_crate.name.clone(),
+            visibility: item_tree[extern_crate.visibility].clone(),
+            alias: extern_crate.alias.clone(),
+        })
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ConstData {
     /// `None` for `const _: () = ();`
     pub name: Option<Name>,
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index 7c0eca1bb5b..33c3a59db22 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -12,8 +12,8 @@ use crate::{
     body::{scope::ExprScopes, Body, BodySourceMap},
     data::{
         adt::{EnumData, StructData},
-        ConstData, FunctionData, ImplData, Macro2Data, MacroRulesData, ProcMacroData, StaticData,
-        TraitAliasData, TraitData, TypeAliasData,
+        ConstData, ExternCrateDeclData, FunctionData, ImplData, Macro2Data, MacroRulesData,
+        ProcMacroData, StaticData, TraitAliasData, TraitData, TypeAliasData,
     },
     generics::GenericParams,
     import_map::ImportMap,
@@ -164,6 +164,9 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
     #[salsa::invoke(ProcMacroData::proc_macro_data_query)]
     fn proc_macro_data(&self, makro: ProcMacroId) -> Arc<ProcMacroData>;
 
+    #[salsa::invoke(ExternCrateDeclData::extern_crate_decl_data_query)]
+    fn extern_crate_decl_data(&self, extern_crate: ExternCrateId) -> Arc<ExternCrateDeclData>;
+
     // endregion:data
 
     #[salsa::invoke(Body::body_with_source_map_query)]
diff --git a/crates/hir-def/src/dyn_map/keys.rs b/crates/hir-def/src/dyn_map/keys.rs
index f30be6b64e3..4197d010608 100644
--- a/crates/hir-def/src/dyn_map/keys.rs
+++ b/crates/hir-def/src/dyn_map/keys.rs
@@ -8,8 +8,8 @@ use syntax::{ast, AstNode, AstPtr};
 
 use crate::{
     dyn_map::{DynMap, Policy},
-    ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, Macro2Id,
-    MacroRulesId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
+    ConstId, EnumId, EnumVariantId, ExternCrateId, FieldId, FunctionId, ImplId, LifetimeParamId,
+    Macro2Id, MacroRulesId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
     TypeOrConstParamId, UnionId,
 };
 
@@ -25,6 +25,7 @@ pub const TRAIT_ALIAS: Key<ast::TraitAlias, TraitAliasId> = Key::new();
 pub const STRUCT: Key<ast::Struct, StructId> = Key::new();
 pub const UNION: Key<ast::Union, UnionId> = Key::new();
 pub const ENUM: Key<ast::Enum, EnumId> = Key::new();
+pub const EXTERN_CRATE: Key<ast::ExternCrate, ExternCrateId> = Key::new();
 
 pub const VARIANT: Key<ast::Variant, EnumVariantId> = Key::new();
 pub const TUPLE_FIELD: Key<ast::TupleField, FieldId> = Key::new();
diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs
index 2001fb29a9e..2ac1bcdc079 100644
--- a/crates/hir-def/src/item_scope.rs
+++ b/crates/hir-def/src/item_scope.rs
@@ -14,8 +14,8 @@ use stdx::format_to;
 use syntax::ast;
 
 use crate::{
-    db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, ConstId, HasModule,
-    ImplId, LocalModuleId, MacroId, ModuleDefId, ModuleId, TraitId,
+    db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, ConstId,
+    ExternCrateId, HasModule, ImplId, LocalModuleId, MacroId, ModuleDefId, ModuleId, TraitId,
 };
 
 #[derive(Copy, Clone, Debug)]
@@ -50,6 +50,7 @@ pub struct ItemScope {
     unnamed_consts: Vec<ConstId>,
     /// Traits imported via `use Trait as _;`.
     unnamed_trait_imports: FxHashMap<TraitId, Visibility>,
+    extern_crate_decls: Vec<ExternCrateId>,
     /// Macros visible in current module in legacy textual scope
     ///
     /// For macros invoked by an unqualified identifier like `bar!()`, `legacy_macros` will be searched in first.
@@ -188,7 +189,11 @@ impl ItemScope {
     }
 
     pub(crate) fn define_impl(&mut self, imp: ImplId) {
-        self.impls.push(imp)
+        self.impls.push(imp);
+    }
+
+    pub(crate) fn define_extern_crate_decl(&mut self, extern_crate: ExternCrateId) {
+        self.extern_crate_decls.push(extern_crate);
     }
 
     pub(crate) fn define_unnamed_const(&mut self, konst: ConstId) {
@@ -397,6 +402,7 @@ impl ItemScope {
             legacy_macros,
             attr_macros,
             derive_macros,
+            extern_crate_decls,
         } = self;
         types.shrink_to_fit();
         values.shrink_to_fit();
@@ -409,6 +415,7 @@ impl ItemScope {
         legacy_macros.shrink_to_fit();
         attr_macros.shrink_to_fit();
         derive_macros.shrink_to_fit();
+        extern_crate_decls.shrink_to_fit();
     }
 }
 
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index 6c96af1e755..65e8c83b5d7 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -831,6 +831,7 @@ pub enum AttrDefId {
     ImplId(ImplId),
     GenericParamId(GenericParamId),
     ExternBlockId(ExternBlockId),
+    ExternCrateId(ExternCrateId),
 }
 
 impl_from!(
@@ -845,7 +846,8 @@ impl_from!(
     TypeAliasId,
     MacroId(Macro2Id, MacroRulesId, ProcMacroId),
     ImplId,
-    GenericParamId
+    GenericParamId,
+    ExternCrateId
     for AttrDefId
 );
 
@@ -937,6 +939,12 @@ impl HasModule for AdtId {
     }
 }
 
+impl HasModule for ExternCrateId {
+    fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
+        self.lookup(db).container
+    }
+}
+
 impl HasModule for VariantId {
     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
         match self {
@@ -1060,6 +1068,7 @@ impl AttrDefId {
                 .krate
             }
             AttrDefId::MacroId(it) => it.module(db).krate,
+            AttrDefId::ExternCrateId(it) => it.lookup(db).container.krate,
         }
     }
 }
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 3c0dfcf4080..d5cfe5bc706 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -1600,11 +1600,14 @@ impl ModCollector<'_, '_> {
                     )
                 }
                 ModItem::ExternCrate(import_id) => {
-                    let _import_id = ExternCrateLoc {
+                    let extern_crate_id = ExternCrateLoc {
                         container: module,
                         id: ItemTreeId::new(self.tree_id, import_id),
                     }
                     .intern(db);
+                    self.def_collector.def_map.modules[self.module_id]
+                        .scope
+                        .define_extern_crate_decl(extern_crate_id);
                     self.def_collector.unresolved_imports.push(ImportDirective {
                         module_id: self.module_id,
                         import: Import::from_extern_crate(
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 0d6f55411c1..423bd00901d 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -22,10 +22,10 @@ use crate::{
     per_ns::PerNs,
     visibility::{RawVisibility, Visibility},
     AdtId, AssocItemId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId,
-    EnumVariantId, ExternBlockId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
-    ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId,
-    ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
-    TypeOrConstParamId, TypeOwnerId, TypeParamId, VariantId,
+    EnumVariantId, ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId,
+    HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId,
+    MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId,
+    TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, VariantId,
 };
 
 #[derive(Debug, Clone)]
@@ -1018,6 +1018,12 @@ impl HasResolver for ExternBlockId {
     }
 }
 
+impl HasResolver for ExternCrateId {
+    fn resolver(self, db: &dyn DefDatabase) -> Resolver {
+        self.lookup(db).container.resolver(db)
+    }
+}
+
 impl HasResolver for TypeOwnerId {
     fn resolver(self, db: &dyn DefDatabase) -> Resolver {
         match self {
diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs
index 1233469b947..9a2df1e9001 100644
--- a/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -181,6 +181,7 @@ impl<'a> DeclValidator<'a> {
                 AttrDefId::TraitAliasId(taid) => Some(taid.lookup(self.db.upcast()).container.into()),
                 AttrDefId::ImplId(iid) => Some(iid.lookup(self.db.upcast()).container.into()),
                 AttrDefId::ExternBlockId(id) => Some(id.lookup(self.db.upcast()).container.into()),
+                AttrDefId::ExternCrateId(id) =>  Some(id.lookup(self.db.upcast()).container.into()),
                 // These warnings should not explore macro definitions at all
                 AttrDefId::MacroId(_) => None,
                 AttrDefId::AdtId(aid) => match aid {
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index b817937296d..cf8db2a5a24 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -141,6 +141,7 @@ fn resolve_doc_path(
         AttrDefId::ImplId(it) => it.resolver(db.upcast()),
         AttrDefId::ExternBlockId(it) => it.resolver(db.upcast()),
         AttrDefId::MacroId(it) => it.resolver(db.upcast()),
+        AttrDefId::ExternCrateId(it) => it.resolver(db.upcast()),
         AttrDefId::GenericParamId(it) => match it {
             GenericParamId::TypeParamId(it) => it.parent(),
             GenericParamId::ConstParamId(it) => it.parent(),