mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-31 23:38:45 +00:00
Prepare ItemScope for IDE import resolution
This commit is contained in:
parent
1b678231d7
commit
af8048266c
11 changed files with 174 additions and 67 deletions
|
@ -1293,4 +1293,22 @@ pub mod prelude {
|
||||||
"None",
|
"None",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn different_crate_renamed_through_dep() {
|
||||||
|
check_found_path(
|
||||||
|
r#"
|
||||||
|
//- /main.rs crate:main deps:intermediate
|
||||||
|
$0
|
||||||
|
//- /intermediate.rs crate:intermediate deps:std
|
||||||
|
pub extern crate std as std_renamed;
|
||||||
|
//- /std.rs crate:std
|
||||||
|
pub struct S;
|
||||||
|
"#,
|
||||||
|
"intermediate::std_renamed::S",
|
||||||
|
"intermediate::std_renamed::S",
|
||||||
|
"intermediate::std_renamed::S",
|
||||||
|
"intermediate::std_renamed::S",
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,9 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> FxIndexMap<ItemIn
|
||||||
|
|
||||||
for (name, per_ns) in visible_items {
|
for (name, per_ns) in visible_items {
|
||||||
for item in per_ns.iter_items() {
|
for item in per_ns.iter_items() {
|
||||||
|
// FIXME: Not yet used, but will be once we handle doc(hidden) import sources
|
||||||
|
let is_doc_hidden = false;
|
||||||
|
|
||||||
let import_info = ImportInfo {
|
let import_info = ImportInfo {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
container: module,
|
container: module,
|
||||||
|
@ -121,15 +124,17 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> FxIndexMap<ItemIn
|
||||||
};
|
};
|
||||||
|
|
||||||
match depth_map.entry(item) {
|
match depth_map.entry(item) {
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => _ = entry.insert((depth, is_doc_hidden)),
|
||||||
entry.insert(depth);
|
|
||||||
}
|
|
||||||
Entry::Occupied(mut entry) => {
|
Entry::Occupied(mut entry) => {
|
||||||
if depth < *entry.get() {
|
let &(occ_depth, occ_is_doc_hidden) = entry.get();
|
||||||
entry.insert(depth);
|
// Prefer the one that is not doc(hidden),
|
||||||
} else {
|
// Otherwise, if both have the same doc(hidden)-ness and the new path is shorter, prefer that one.
|
||||||
|
let overwrite_entry = occ_is_doc_hidden && !is_doc_hidden
|
||||||
|
|| occ_is_doc_hidden == is_doc_hidden && depth < occ_depth;
|
||||||
|
if !overwrite_entry {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
entry.insert((depth, is_doc_hidden));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::collections::hash_map::Entry;
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId};
|
use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use la_arena::Idx;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use profile::Count;
|
use profile::Count;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
@ -32,15 +33,50 @@ pub struct PerNsGlobImports {
|
||||||
macros: FxHashSet<(LocalModuleId, Name)>,
|
macros: FxHashSet<(LocalModuleId, Name)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ImportOrExternCrate {
|
||||||
|
Import(ImportId),
|
||||||
|
Glob(UseId),
|
||||||
|
ExternCrate(ExternCrateId),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImportOrExternCrate {
|
||||||
|
pub fn into_import(self) -> Option<ImportId> {
|
||||||
|
match self {
|
||||||
|
ImportOrExternCrate::Import(it) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_glob(self) -> Option<UseId> {
|
||||||
|
match self {
|
||||||
|
ImportOrExternCrate::Glob(it) => Some(it),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum ImportOrDef {
|
||||||
|
Import(ImportId),
|
||||||
|
ExternCrate(ExternCrateId),
|
||||||
|
Def(ModuleDefId),
|
||||||
|
}
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct ImportId {
|
||||||
|
pub import: UseId,
|
||||||
|
pub idx: Idx<ast::UseTree>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, Eq)]
|
#[derive(Debug, Default, PartialEq, Eq)]
|
||||||
pub struct ItemScope {
|
pub struct ItemScope {
|
||||||
_c: Count<Self>,
|
_c: Count<Self>,
|
||||||
|
|
||||||
/// Defs visible in this scope. This includes `declarations`, but also
|
/// Defs visible in this scope. This includes `declarations`, but also
|
||||||
/// imports.
|
/// imports.
|
||||||
types: FxHashMap<Name, (ModuleDefId, Visibility)>,
|
types: FxHashMap<Name, (ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
|
||||||
values: FxHashMap<Name, (ModuleDefId, Visibility)>,
|
values: FxHashMap<Name, (ModuleDefId, Visibility, Option<ImportId>)>,
|
||||||
macros: FxHashMap<Name, (MacroId, Visibility)>,
|
macros: FxHashMap<Name, (MacroId, Visibility, Option<ImportId>)>,
|
||||||
unresolved: FxHashSet<Name>,
|
unresolved: FxHashSet<Name>,
|
||||||
|
|
||||||
/// The defs declared in this scope. Each def has a single scope where it is
|
/// The defs declared in this scope. Each def has a single scope where it is
|
||||||
|
@ -50,7 +86,14 @@ pub struct ItemScope {
|
||||||
impls: Vec<ImplId>,
|
impls: Vec<ImplId>,
|
||||||
unnamed_consts: Vec<ConstId>,
|
unnamed_consts: Vec<ConstId>,
|
||||||
/// Traits imported via `use Trait as _;`.
|
/// Traits imported via `use Trait as _;`.
|
||||||
unnamed_trait_imports: FxHashMap<TraitId, Visibility>,
|
unnamed_trait_imports: FxHashMap<TraitId, (Visibility, Option<ImportId>)>,
|
||||||
|
|
||||||
|
// the resolutions of the imports of this scope
|
||||||
|
use_imports_types: FxHashMap<UseId, ImportOrDef>,
|
||||||
|
use_imports_values: FxHashMap<UseId, ImportOrDef>,
|
||||||
|
use_imports_macros: FxHashMap<UseId, ImportOrDef>,
|
||||||
|
|
||||||
|
use_decls: Vec<UseId>,
|
||||||
extern_crate_decls: Vec<ExternCrateId>,
|
extern_crate_decls: Vec<ExternCrateId>,
|
||||||
/// Macros visible in current module in legacy textual scope
|
/// Macros visible in current module in legacy textual scope
|
||||||
///
|
///
|
||||||
|
@ -121,8 +164,7 @@ impl ItemScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_decls(&self) -> impl Iterator<Item = UseId> + ExactSizeIterator + '_ {
|
pub fn use_decls(&self) -> impl Iterator<Item = UseId> + ExactSizeIterator + '_ {
|
||||||
// FIXME: to be implemented
|
self.use_decls.iter().copied()
|
||||||
std::iter::empty()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
|
pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
|
||||||
|
@ -132,13 +174,13 @@ impl ItemScope {
|
||||||
pub fn values(
|
pub fn values(
|
||||||
&self,
|
&self,
|
||||||
) -> impl Iterator<Item = (ModuleDefId, Visibility)> + ExactSizeIterator + '_ {
|
) -> impl Iterator<Item = (ModuleDefId, Visibility)> + ExactSizeIterator + '_ {
|
||||||
self.values.values().copied()
|
self.values.values().copied().map(|(a, b, _)| (a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn types(
|
pub(crate) fn types(
|
||||||
&self,
|
&self,
|
||||||
) -> impl Iterator<Item = (ModuleDefId, Visibility)> + ExactSizeIterator + '_ {
|
) -> impl Iterator<Item = (ModuleDefId, Visibility)> + ExactSizeIterator + '_ {
|
||||||
self.types.values().copied()
|
self.types.values().copied().map(|(def, vis, _)| (def, vis))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unnamed_consts(&self) -> impl Iterator<Item = ConstId> + '_ {
|
pub fn unnamed_consts(&self) -> impl Iterator<Item = ConstId> + '_ {
|
||||||
|
@ -165,33 +207,48 @@ impl ItemScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn type_(&self, name: &Name) -> Option<(ModuleDefId, Visibility)> {
|
pub(crate) fn type_(&self, name: &Name) -> Option<(ModuleDefId, Visibility)> {
|
||||||
self.types.get(name).copied()
|
self.types.get(name).copied().map(|(a, b, _)| (a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// XXX: this is O(N) rather than O(1), try to not introduce new usages.
|
/// XXX: this is O(N) rather than O(1), try to not introduce new usages.
|
||||||
pub(crate) fn name_of(&self, item: ItemInNs) -> Option<(&Name, Visibility)> {
|
pub(crate) fn name_of(&self, item: ItemInNs) -> Option<(&Name, Visibility)> {
|
||||||
let (def, mut iter) = match item {
|
match item {
|
||||||
ItemInNs::Macros(def) => {
|
ItemInNs::Macros(def) => self
|
||||||
return self.macros.iter().find_map(|(name, &(other_def, vis))| {
|
.macros
|
||||||
(other_def == def).then_some((name, vis))
|
.iter()
|
||||||
});
|
.find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
|
||||||
|
ItemInNs::Types(def) => self
|
||||||
|
.types
|
||||||
|
.iter()
|
||||||
|
.find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
|
||||||
|
|
||||||
|
ItemInNs::Values(def) => self
|
||||||
|
.values
|
||||||
|
.iter()
|
||||||
|
.find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
|
||||||
}
|
}
|
||||||
ItemInNs::Types(def) => (def, self.types.iter()),
|
|
||||||
ItemInNs::Values(def) => (def, self.values.iter()),
|
|
||||||
};
|
|
||||||
iter.find_map(|(name, &(other_def, vis))| (other_def == def).then_some((name, vis)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ {
|
pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ {
|
||||||
self.types
|
self.types
|
||||||
.values()
|
.values()
|
||||||
.filter_map(|&(def, _)| match def {
|
.filter_map(|&(def, _, _)| match def {
|
||||||
ModuleDefId::TraitId(t) => Some(t),
|
ModuleDefId::TraitId(t) => Some(t),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.chain(self.unnamed_trait_imports.keys().copied())
|
.chain(self.unnamed_trait_imports.keys().copied())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ {
|
||||||
|
self.entries().map(|(name, res)| (Some(name.clone()), res)).chain(
|
||||||
|
self.unnamed_trait_imports
|
||||||
|
.iter()
|
||||||
|
.map(|(tr, (vis, _))| (None, PerNs::types(ModuleDefId::TraitId(*tr), *vis))),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ItemScope {
|
||||||
pub(crate) fn declare(&mut self, def: ModuleDefId) {
|
pub(crate) fn declare(&mut self, def: ModuleDefId) {
|
||||||
self.declarations.push(def)
|
self.declarations.push(def)
|
||||||
}
|
}
|
||||||
|
@ -278,11 +335,11 @@ impl ItemScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option<Visibility> {
|
pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option<Visibility> {
|
||||||
self.unnamed_trait_imports.get(&tr).copied()
|
self.unnamed_trait_imports.get(&tr).copied().map(|(a, _)| a)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) {
|
pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) {
|
||||||
self.unnamed_trait_imports.insert(tr, vis);
|
self.unnamed_trait_imports.insert(tr, (vis, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn push_res_with_import(
|
pub(crate) fn push_res_with_import(
|
||||||
|
@ -343,27 +400,18 @@ impl ItemScope {
|
||||||
changed
|
changed
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ {
|
|
||||||
self.entries().map(|(name, res)| (Some(name.clone()), res)).chain(
|
|
||||||
self.unnamed_trait_imports
|
|
||||||
.iter()
|
|
||||||
.map(|(tr, vis)| (None, PerNs::types(ModuleDefId::TraitId(*tr), *vis))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Marks everything that is not a procedural macro as private to `this_module`.
|
/// Marks everything that is not a procedural macro as private to `this_module`.
|
||||||
pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) {
|
pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) {
|
||||||
self.types
|
self.types
|
||||||
.values_mut()
|
.values_mut()
|
||||||
.chain(self.values.values_mut())
|
.map(|(def, vis, _)| (def, vis))
|
||||||
|
.chain(self.values.values_mut().map(|(def, vis, _)| (def, vis)))
|
||||||
.map(|(_, v)| v)
|
.map(|(_, v)| v)
|
||||||
.chain(self.unnamed_trait_imports.values_mut())
|
.chain(self.unnamed_trait_imports.values_mut().map(|(vis, _)| vis))
|
||||||
.for_each(|vis| *vis = Visibility::Module(this_module));
|
.for_each(|vis| *vis = Visibility::Module(this_module));
|
||||||
|
|
||||||
for (mac, vis) in self.macros.values_mut() {
|
for (mac, vis, import) in self.macros.values_mut() {
|
||||||
if let MacroId::ProcMacroId(_) = mac {
|
if matches!(mac, MacroId::ProcMacroId(_) if import.is_none()) {
|
||||||
// FIXME: Technically this is insufficient since reexports of proc macros are also
|
|
||||||
// forbidden. Practically nobody does that.
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,10 +463,17 @@ impl ItemScope {
|
||||||
attr_macros,
|
attr_macros,
|
||||||
derive_macros,
|
derive_macros,
|
||||||
extern_crate_decls,
|
extern_crate_decls,
|
||||||
|
use_decls,
|
||||||
|
use_imports_values,
|
||||||
|
use_imports_types,
|
||||||
|
use_imports_macros,
|
||||||
} = self;
|
} = self;
|
||||||
types.shrink_to_fit();
|
types.shrink_to_fit();
|
||||||
values.shrink_to_fit();
|
values.shrink_to_fit();
|
||||||
macros.shrink_to_fit();
|
macros.shrink_to_fit();
|
||||||
|
use_imports_types.shrink_to_fit();
|
||||||
|
use_imports_values.shrink_to_fit();
|
||||||
|
use_imports_macros.shrink_to_fit();
|
||||||
unresolved.shrink_to_fit();
|
unresolved.shrink_to_fit();
|
||||||
declarations.shrink_to_fit();
|
declarations.shrink_to_fit();
|
||||||
impls.shrink_to_fit();
|
impls.shrink_to_fit();
|
||||||
|
@ -428,6 +483,7 @@ impl ItemScope {
|
||||||
attr_macros.shrink_to_fit();
|
attr_macros.shrink_to_fit();
|
||||||
derive_macros.shrink_to_fit();
|
derive_macros.shrink_to_fit();
|
||||||
extern_crate_decls.shrink_to_fit();
|
extern_crate_decls.shrink_to_fit();
|
||||||
|
use_decls.shrink_to_fit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -865,6 +865,7 @@ impl_from!(
|
||||||
ConstId,
|
ConstId,
|
||||||
FunctionId,
|
FunctionId,
|
||||||
TraitId,
|
TraitId,
|
||||||
|
TraitAliasId,
|
||||||
TypeAliasId,
|
TypeAliasId,
|
||||||
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
||||||
ImplId,
|
ImplId,
|
||||||
|
@ -873,6 +874,26 @@ impl_from!(
|
||||||
for AttrDefId
|
for AttrDefId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl TryFrom<ModuleDefId> for AttrDefId {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(value: ModuleDefId) -> Result<Self, Self::Error> {
|
||||||
|
match value {
|
||||||
|
ModuleDefId::ModuleId(it) => Ok(it.into()),
|
||||||
|
ModuleDefId::FunctionId(it) => Ok(it.into()),
|
||||||
|
ModuleDefId::AdtId(it) => Ok(it.into()),
|
||||||
|
ModuleDefId::EnumVariantId(it) => Ok(it.into()),
|
||||||
|
ModuleDefId::ConstId(it) => Ok(it.into()),
|
||||||
|
ModuleDefId::StaticId(it) => Ok(it.into()),
|
||||||
|
ModuleDefId::TraitId(it) => Ok(it.into()),
|
||||||
|
ModuleDefId::TypeAliasId(it) => Ok(it.into()),
|
||||||
|
ModuleDefId::TraitAliasId(id) => Ok(id.into()),
|
||||||
|
ModuleDefId::MacroId(id) => Ok(id.into()),
|
||||||
|
ModuleDefId::BuiltinType(_) => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<ItemContainerId> for AttrDefId {
|
impl From<ItemContainerId> for AttrDefId {
|
||||||
fn from(acid: ItemContainerId) -> Self {
|
fn from(acid: ItemContainerId) -> Self {
|
||||||
match acid {
|
match acid {
|
||||||
|
|
|
@ -108,6 +108,7 @@ pub struct DefMap {
|
||||||
prelude: Option<(ModuleId, Option<UseId>)>,
|
prelude: Option<(ModuleId, Option<UseId>)>,
|
||||||
/// `macro_use` prelude that contains macros from `#[macro_use]`'d external crates. Note that
|
/// `macro_use` prelude that contains macros from `#[macro_use]`'d external crates. Note that
|
||||||
/// this contains all kinds of macro, not just `macro_rules!` macro.
|
/// this contains all kinds of macro, not just `macro_rules!` macro.
|
||||||
|
/// ExternCrateId being None implies it being imported from the general prelude import.
|
||||||
macro_use_prelude: FxHashMap<Name, (MacroId, Option<ExternCrateId>)>,
|
macro_use_prelude: FxHashMap<Name, (MacroId, Option<ExternCrateId>)>,
|
||||||
|
|
||||||
/// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
|
/// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
|
||||||
|
|
|
@ -33,7 +33,7 @@ use crate::{
|
||||||
attr_macro_as_call_id,
|
attr_macro_as_call_id,
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
derive_macro_as_call_id,
|
derive_macro_as_call_id,
|
||||||
item_scope::{ImportType, PerNsGlobImports},
|
item_scope::{ImportOrExternCrate, ImportType, PerNsGlobImports},
|
||||||
item_tree::{
|
item_tree::{
|
||||||
self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
|
self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
|
||||||
MacroCall, MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId,
|
MacroCall, MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId,
|
||||||
|
@ -546,8 +546,8 @@ impl DefCollector<'_> {
|
||||||
self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
|
self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
|
||||||
|
|
||||||
match per_ns.types {
|
match per_ns.types {
|
||||||
Some((ModuleDefId::ModuleId(m), _)) => {
|
Some((ModuleDefId::ModuleId(m), _, import)) => {
|
||||||
self.def_map.prelude = Some((m, None));
|
self.def_map.prelude = Some((m, import.and_then(ImportOrExternCrate::into_glob)));
|
||||||
}
|
}
|
||||||
types => {
|
types => {
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
|
@ -714,7 +714,6 @@ impl DefCollector<'_> {
|
||||||
&mut self,
|
&mut self,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
names: Option<Vec<Name>>,
|
names: Option<Vec<Name>>,
|
||||||
|
|
||||||
extern_crate: Option<ExternCrateId>,
|
extern_crate: Option<ExternCrateId>,
|
||||||
) {
|
) {
|
||||||
let def_map = self.db.crate_def_map(krate);
|
let def_map = self.db.crate_def_map(krate);
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl PerNs {
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
expected: Option<MacroSubNs>,
|
expected: Option<MacroSubNs>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.macros = self.macros.filter(|&(id, _)| {
|
self.macros = self.macros.filter(|&(id, _, _)| {
|
||||||
let this = MacroSubNs::from_id(db, id);
|
let this = MacroSubNs::from_id(db, id);
|
||||||
sub_namespace_match(Some(this), expected)
|
sub_namespace_match(Some(this), expected)
|
||||||
});
|
});
|
||||||
|
|
|
@ -212,7 +212,7 @@ pub type Ty = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, res) in module_data.scope.resolutions() {
|
for (_, res) in module_data.scope.resolutions() {
|
||||||
match res.values.or(res.types).unwrap().0 {
|
match res.values.map(|(a, _, _)| a).or(res.types.map(|(a, _, _)| a)).unwrap() {
|
||||||
ModuleDefId::FunctionId(f) => _ = db.function_data(f),
|
ModuleDefId::FunctionId(f) => _ = db.function_data(f),
|
||||||
ModuleDefId::AdtId(adt) => match adt {
|
ModuleDefId::AdtId(adt) => match adt {
|
||||||
AdtId::StructId(it) => _ = db.struct_data(it),
|
AdtId::StructId(it) => _ = db.struct_data(it),
|
||||||
|
|
|
@ -3,13 +3,17 @@
|
||||||
//!
|
//!
|
||||||
//! `PerNs` (per namespace) captures this.
|
//! `PerNs` (per namespace) captures this.
|
||||||
|
|
||||||
use crate::{item_scope::ItemInNs, visibility::Visibility, MacroId, ModuleDefId};
|
use crate::{
|
||||||
|
item_scope::{ImportId, ImportOrExternCrate, ItemInNs},
|
||||||
|
visibility::Visibility,
|
||||||
|
MacroId, ModuleDefId,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct PerNs {
|
pub struct PerNs {
|
||||||
pub types: Option<(ModuleDefId, Visibility)>,
|
pub types: Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
|
||||||
pub values: Option<(ModuleDefId, Visibility)>,
|
pub values: Option<(ModuleDefId, Visibility, Option<ImportId>)>,
|
||||||
pub macros: Option<(MacroId, Visibility)>,
|
pub macros: Option<(MacroId, Visibility, Option<ImportId>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PerNs {
|
impl Default for PerNs {
|
||||||
|
@ -24,19 +28,19 @@ impl PerNs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
|
pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
|
||||||
PerNs { types: None, values: Some((t, v)), macros: None }
|
PerNs { types: None, values: Some((t, v, None)), macros: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
|
pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
|
||||||
PerNs { types: Some((t, v)), values: None, macros: None }
|
PerNs { types: Some((t, v, None)), values: None, macros: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
|
pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
|
||||||
PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
|
PerNs { types: Some((types, v, None)), values: Some((values, v, None)), macros: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn macros(macro_: MacroId, v: Visibility) -> PerNs {
|
pub fn macros(macro_: MacroId, v: Visibility) -> PerNs {
|
||||||
PerNs { types: None, values: None, macros: Some((macro_, v)) }
|
PerNs { types: None, values: None, macros: Some((macro_, v, None)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_none(&self) -> bool {
|
pub fn is_none(&self) -> bool {
|
||||||
|
@ -52,7 +56,7 @@ impl PerNs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> {
|
pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> {
|
||||||
self.types
|
self.types.map(|(a, b, _)| (a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_values(self) -> Option<ModuleDefId> {
|
pub fn take_values(self) -> Option<ModuleDefId> {
|
||||||
|
@ -66,17 +70,17 @@ impl PerNs {
|
||||||
pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
|
pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
|
||||||
let _p = profile::span("PerNs::filter_visibility");
|
let _p = profile::span("PerNs::filter_visibility");
|
||||||
PerNs {
|
PerNs {
|
||||||
types: self.types.filter(|(_, v)| f(*v)),
|
types: self.types.filter(|&(_, v, _)| f(v)),
|
||||||
values: self.values.filter(|(_, v)| f(*v)),
|
values: self.values.filter(|&(_, v, _)| f(v)),
|
||||||
macros: self.macros.filter(|(_, v)| f(*v)),
|
macros: self.macros.filter(|&(_, v, _)| f(v)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_visibility(self, vis: Visibility) -> PerNs {
|
pub fn with_visibility(self, vis: Visibility) -> PerNs {
|
||||||
PerNs {
|
PerNs {
|
||||||
types: self.types.map(|(it, _)| (it, vis)),
|
types: self.types.map(|(it, _, c)| (it, vis, c)),
|
||||||
values: self.values.map(|(it, _)| (it, vis)),
|
values: self.values.map(|(it, _, c)| (it, vis, c)),
|
||||||
macros: self.macros.map(|(it, _)| (it, vis)),
|
macros: self.macros.map(|(it, _, import)| (it, vis, import)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -864,13 +864,13 @@ impl ScopeNames {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn add_per_ns(&mut self, name: &Name, def: PerNs) {
|
fn add_per_ns(&mut self, name: &Name, def: PerNs) {
|
||||||
if let &Some((ty, _)) = &def.types {
|
if let &Some((ty, _, _)) = &def.types {
|
||||||
self.add(name, ScopeDef::ModuleDef(ty))
|
self.add(name, ScopeDef::ModuleDef(ty))
|
||||||
}
|
}
|
||||||
if let &Some((def, _)) = &def.values {
|
if let &Some((def, _, _)) = &def.values {
|
||||||
self.add(name, ScopeDef::ModuleDef(def))
|
self.add(name, ScopeDef::ModuleDef(def))
|
||||||
}
|
}
|
||||||
if let &Some((mac, _)) = &def.macros {
|
if let &Some((mac, _, _)) = &def.macros {
|
||||||
self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)))
|
self.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)))
|
||||||
}
|
}
|
||||||
if def.is_none() {
|
if def.is_none() {
|
||||||
|
|
|
@ -94,18 +94,21 @@ impl fmt::Debug for RootDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Upcast<dyn ExpandDatabase> for RootDatabase {
|
impl Upcast<dyn ExpandDatabase> for RootDatabase {
|
||||||
|
#[inline]
|
||||||
fn upcast(&self) -> &(dyn ExpandDatabase + 'static) {
|
fn upcast(&self) -> &(dyn ExpandDatabase + 'static) {
|
||||||
&*self
|
&*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Upcast<dyn DefDatabase> for RootDatabase {
|
impl Upcast<dyn DefDatabase> for RootDatabase {
|
||||||
|
#[inline]
|
||||||
fn upcast(&self) -> &(dyn DefDatabase + 'static) {
|
fn upcast(&self) -> &(dyn DefDatabase + 'static) {
|
||||||
&*self
|
&*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Upcast<dyn HirDatabase> for RootDatabase {
|
impl Upcast<dyn HirDatabase> for RootDatabase {
|
||||||
|
#[inline]
|
||||||
fn upcast(&self) -> &(dyn HirDatabase + 'static) {
|
fn upcast(&self) -> &(dyn HirDatabase + 'static) {
|
||||||
&*self
|
&*self
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue