Intern use and extern crate items like other items

This commit is contained in:
Lukas Wirth 2023-06-15 12:28:03 +02:00
parent 00b9d9faf4
commit 0bde3fc77e
3 changed files with 50 additions and 31 deletions

View file

@ -22,17 +22,21 @@ use crate::{
nameres::{diagnostics::DefDiagnostic, DefMap}, nameres::{diagnostics::DefDiagnostic, DefMap},
visibility::{self, Visibility}, visibility::{self, Visibility},
AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId, AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId,
EnumId, EnumLoc, ExternBlockId, ExternBlockLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, EnumId, EnumLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId,
ImplLoc, InTypeConstId, InTypeConstLoc, LocalEnumVariantId, LocalFieldId, Macro2Id, Macro2Loc, FunctionLoc, GenericDefId, ImplId, ImplLoc, ImportId, ImportLoc, InTypeConstId, InTypeConstLoc,
MacroRulesId, MacroRulesLoc, ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, LocalEnumVariantId, LocalFieldId, Macro2Id, Macro2Loc, MacroRulesId, MacroRulesLoc,
StructLoc, TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitAliasId,
UnionLoc, VariantId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId,
}; };
#[salsa::query_group(InternDatabaseStorage)] #[salsa::query_group(InternDatabaseStorage)]
pub trait InternDatabase: SourceDatabase { pub trait InternDatabase: SourceDatabase {
// region: items // region: items
#[salsa::interned] #[salsa::interned]
fn intern_import(&self, loc: ImportLoc) -> ImportId;
#[salsa::interned]
fn intern_extern_crate(&self, loc: ExternCrateLoc) -> ExternCrateId;
#[salsa::interned]
fn intern_function(&self, loc: FunctionLoc) -> FunctionId; fn intern_function(&self, loc: FunctionLoc) -> FunctionId;
#[salsa::interned] #[salsa::interned]
fn intern_struct(&self, loc: StructLoc) -> StructId; fn intern_struct(&self, loc: StructLoc) -> StructId;

View file

@ -88,8 +88,8 @@ use crate::{
builtin_type::BuiltinType, builtin_type::BuiltinType,
data::adt::VariantData, data::adt::VariantData,
item_tree::{ item_tree::{
Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, MacroDef, MacroRules, Static, Const, Enum, ExternCrate, Function, Impl, Import, ItemTreeId, ItemTreeNode, MacroDef,
Struct, Trait, TraitAlias, TypeAlias, Union, MacroRules, Static, Struct, Trait, TraitAlias, TypeAlias, Union,
}, },
}; };
@ -313,6 +313,16 @@ pub struct ImplId(salsa::InternId);
type ImplLoc = ItemLoc<Impl>; type ImplLoc = ItemLoc<Impl>;
impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct ImportId(salsa::InternId);
type ImportLoc = ItemLoc<Import>;
impl_intern!(ImportId, ImportLoc, intern_import, lookup_intern_import);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct ExternCrateId(salsa::InternId);
type ExternCrateLoc = ItemLoc<ExternCrate>;
impl_intern!(ExternCrateId, ExternCrateLoc, intern_extern_crate, lookup_intern_extern_crate);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct ExternBlockId(salsa::InternId); pub struct ExternBlockId(salsa::InternId);
type ExternBlockLoc = ItemLoc<ExternBlock>; type ExternBlockLoc = ItemLoc<ExternBlock>;

View file

@ -52,10 +52,10 @@ use crate::{
tt, tt,
visibility::{RawVisibility, Visibility}, visibility::{RawVisibility, Visibility},
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId, AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
ExternBlockLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId, LocalModuleId, ExternBlockLoc, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, ImportLoc, Intern,
Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, ModuleDefId, ItemContainerId, LocalModuleId, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId,
ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc,
TypeAliasLoc, UnionLoc, UnresolvedMacro, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro,
}; };
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100); static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
@ -156,10 +156,9 @@ struct Import {
alias: Option<ImportAlias>, alias: Option<ImportAlias>,
visibility: RawVisibility, visibility: RawVisibility,
kind: ImportKind, kind: ImportKind,
is_prelude: bool,
is_extern_crate: bool,
is_macro_use: bool,
source: ImportSource, source: ImportSource,
is_prelude: bool,
is_macro_use: bool,
} }
impl Import { impl Import {
@ -168,26 +167,23 @@ impl Import {
krate: CrateId, krate: CrateId,
tree: &ItemTree, tree: &ItemTree,
id: ItemTreeId<item_tree::Import>, id: ItemTreeId<item_tree::Import>,
) -> Vec<Self> { mut cb: impl FnMut(Self),
) {
let it = &tree[id.value]; let it = &tree[id.value];
let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into()); let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
let visibility = &tree[it.visibility]; let visibility = &tree[it.visibility];
let is_prelude = attrs.by_key("prelude_import").exists(); let is_prelude = attrs.by_key("prelude_import").exists();
let mut res = Vec::new();
it.use_tree.expand(|idx, path, kind, alias| { it.use_tree.expand(|idx, path, kind, alias| {
res.push(Self { cb(Self {
path, path,
alias, alias,
visibility: visibility.clone(), visibility: visibility.clone(),
kind, kind,
is_prelude, is_prelude,
is_extern_crate: false,
is_macro_use: false, is_macro_use: false,
source: ImportSource::Import { id, use_tree: idx }, source: ImportSource::Import { id, use_tree: idx },
}); });
}); });
res
} }
fn from_extern_crate( fn from_extern_crate(
@ -205,7 +201,6 @@ impl Import {
visibility: visibility.clone(), visibility: visibility.clone(),
kind: ImportKind::Plain, kind: ImportKind::Plain,
is_prelude: false, is_prelude: false,
is_extern_crate: true,
is_macro_use: attrs.by_key("macro_use").exists(), is_macro_use: attrs.by_key("macro_use").exists(),
source: ImportSource::ExternCrate(id), source: ImportSource::ExternCrate(id),
} }
@ -776,7 +771,7 @@ impl DefCollector<'_> {
let _p = profile::span("resolve_import") let _p = profile::span("resolve_import")
.detail(|| format!("{}", import.path.display(self.db.upcast()))); .detail(|| format!("{}", import.path.display(self.db.upcast())));
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition); tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition);
if import.is_extern_crate { if matches!(import.source, ImportSource::ExternCrate { .. }) {
let name = import let name = import
.path .path
.as_ident() .as_ident()
@ -867,7 +862,7 @@ impl DefCollector<'_> {
tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); 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 // 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 if matches!(import.source, ImportSource::ExternCrate { .. })
&& self.def_map.block.is_none() && self.def_map.block.is_none()
&& module_id == DefMap::ROOT && module_id == DefMap::ROOT
{ {
@ -1585,21 +1580,31 @@ impl ModCollector<'_, '_> {
match item { match item {
ModItem::Mod(m) => self.collect_module(m, &attrs), ModItem::Mod(m) => self.collect_module(m, &attrs),
ModItem::Import(import_id) => { ModItem::Import(import_id) => {
let imports = Import::from_use( let _import_id = ImportLoc {
container: module,
id: ItemTreeId::new(self.tree_id, import_id),
}
.intern(db);
Import::from_use(
db, db,
krate, krate,
self.item_tree, self.item_tree,
ItemTreeId::new(self.tree_id, import_id), ItemTreeId::new(self.tree_id, import_id),
); |import| {
self.def_collector.unresolved_imports.extend(imports.into_iter().map( self.def_collector.unresolved_imports.push(ImportDirective {
|import| ImportDirective {
module_id: self.module_id, module_id: self.module_id,
import, import,
status: PartialResolvedImport::Unresolved, status: PartialResolvedImport::Unresolved,
});
}, },
)); )
} }
ModItem::ExternCrate(import_id) => { ModItem::ExternCrate(import_id) => {
let _import_id = ExternCrateLoc {
container: module,
id: ItemTreeId::new(self.tree_id, import_id),
}
.intern(db);
self.def_collector.unresolved_imports.push(ImportDirective { self.def_collector.unresolved_imports.push(ImportDirective {
module_id: self.module_id, module_id: self.module_id,
import: Import::from_extern_crate( import: Import::from_extern_crate(