mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
Intern use and extern crate items like other items
This commit is contained in:
parent
00b9d9faf4
commit
0bde3fc77e
3 changed files with 50 additions and 31 deletions
|
@ -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;
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue