mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
Auto merge of #15472 - Veykril:import-ide-support, r=Veykril
internal: Record import origins in ItemScope and PerNS This records the import items definitions come from in the module scope (as well as what an import resolves to in an ItemScope). It does ignore glob imports as thats a lot more work for little to no gain, glob imports act as if the importing items are "inlined" into the scope which suffices for almost all use cases I believe (to my knowledge, attributes on them have little effect). There is still a lot of work needed to make this available to the IDE layer, but this lays out the ground work for havin IDE layer support. cc https://github.com/rust-lang/rust-analyzer/issues/14079
This commit is contained in:
@@ -38,9 +38,9 @@ fn Struct() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
block scope
|
||||
CrateStruct: t
|
||||
PlainStruct: t v
|
||||
SelfStruct: t
|
||||
CrateStruct: ti
|
||||
PlainStruct: ti vi
|
||||
SelfStruct: ti
|
||||
Struct: v
|
||||
SuperStruct: _
|
||||
|
||||
@@ -66,7 +66,7 @@ fn name() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
block scope
|
||||
imported: t v
|
||||
imported: ti vi
|
||||
name: v
|
||||
|
||||
crate
|
||||
@@ -92,9 +92,9 @@ fn inner2() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
block scope
|
||||
inner1: t
|
||||
inner1: ti
|
||||
inner2: v
|
||||
outer: v
|
||||
outer: vi
|
||||
|
||||
block scope
|
||||
inner: v
|
||||
@@ -121,7 +121,7 @@ struct Struct {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
block scope
|
||||
Struct: t
|
||||
Struct: ti
|
||||
|
||||
crate
|
||||
Struct: t
|
||||
@@ -153,7 +153,7 @@ fn inner() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
block scope
|
||||
ResolveMe: t
|
||||
ResolveMe: ti
|
||||
|
||||
block scope
|
||||
m2: t
|
||||
@@ -214,7 +214,7 @@ fn h() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
block scope
|
||||
ResolveMe: t
|
||||
ResolveMe: ti
|
||||
|
||||
block scope
|
||||
h: v
|
||||
@@ -292,7 +292,7 @@ struct $name {}
|
||||
nested: v
|
||||
|
||||
crate
|
||||
cov_mark: t
|
||||
cov_mark: ti
|
||||
f: v
|
||||
"#]],
|
||||
);
|
||||
|
||||
@@ -1293,4 +1293,22 @@ pub enum Option { 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 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 {
|
||||
name: name.clone(),
|
||||
container: module,
|
||||
@@ -121,15 +124,17 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> FxIndexMap<ItemIn
|
||||
};
|
||||
|
||||
match depth_map.entry(item) {
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(depth);
|
||||
}
|
||||
Entry::Vacant(entry) => _ = entry.insert((depth, is_doc_hidden)),
|
||||
Entry::Occupied(mut entry) => {
|
||||
if depth < *entry.get() {
|
||||
entry.insert(depth);
|
||||
} else {
|
||||
let &(occ_depth, occ_is_doc_hidden) = entry.get();
|
||||
// Prefer the one that is not doc(hidden),
|
||||
// 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;
|
||||
}
|
||||
entry.insert((depth, is_doc_hidden));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
use base_db::CrateId;
|
||||
use hir_expand::{attrs::AttrId, db::ExpandDatabase, name::Name, AstId, MacroCallId};
|
||||
use itertools::Itertools;
|
||||
use la_arena::Idx;
|
||||
use once_cell::sync::Lazy;
|
||||
use profile::Count;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
@@ -19,12 +20,6 @@
|
||||
UseId,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) enum ImportType {
|
||||
Glob,
|
||||
Named,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct PerNsGlobImports {
|
||||
types: FxHashSet<(LocalModuleId, Name)>,
|
||||
@@ -32,15 +27,49 @@ pub struct PerNsGlobImports {
|
||||
macros: FxHashSet<(LocalModuleId, Name)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum ImportOrExternCrate {
|
||||
Import(ImportId),
|
||||
ExternCrate(ExternCrateId),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub(crate) enum ImportType {
|
||||
Import(ImportId),
|
||||
Glob(UseId),
|
||||
ExternCrate(ExternCrateId),
|
||||
}
|
||||
|
||||
impl ImportOrExternCrate {
|
||||
pub fn into_import(self) -> Option<ImportId> {
|
||||
match self {
|
||||
ImportOrExternCrate::Import(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)]
|
||||
pub struct ItemScope {
|
||||
_c: Count<Self>,
|
||||
|
||||
/// Defs visible in this scope. This includes `declarations`, but also
|
||||
/// imports.
|
||||
types: FxHashMap<Name, (ModuleDefId, Visibility)>,
|
||||
values: FxHashMap<Name, (ModuleDefId, Visibility)>,
|
||||
macros: FxHashMap<Name, (MacroId, Visibility)>,
|
||||
types: FxHashMap<Name, (ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
|
||||
values: FxHashMap<Name, (ModuleDefId, Visibility, Option<ImportId>)>,
|
||||
macros: FxHashMap<Name, (MacroId, Visibility, Option<ImportId>)>,
|
||||
unresolved: FxHashSet<Name>,
|
||||
|
||||
/// The defs declared in this scope. Each def has a single scope where it is
|
||||
@@ -50,7 +79,14 @@ pub struct ItemScope {
|
||||
impls: Vec<ImplId>,
|
||||
unnamed_consts: Vec<ConstId>,
|
||||
/// 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<ImportOrExternCrate, ImportOrDef>,
|
||||
use_imports_values: FxHashMap<ImportId, ImportOrDef>,
|
||||
use_imports_macros: FxHashMap<ImportId, ImportOrDef>,
|
||||
|
||||
use_decls: Vec<UseId>,
|
||||
extern_crate_decls: Vec<ExternCrateId>,
|
||||
/// Macros visible in current module in legacy textual scope
|
||||
///
|
||||
@@ -82,7 +118,7 @@ struct DeriveMacroInvocation {
|
||||
pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
|
||||
BuiltinType::ALL
|
||||
.iter()
|
||||
.map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public)))
|
||||
.map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public, None)))
|
||||
.collect()
|
||||
});
|
||||
|
||||
@@ -121,8 +157,7 @@ pub fn extern_crate_decls(
|
||||
}
|
||||
|
||||
pub fn use_decls(&self) -> impl Iterator<Item = UseId> + ExactSizeIterator + '_ {
|
||||
// FIXME: to be implemented
|
||||
std::iter::empty()
|
||||
self.use_decls.iter().copied()
|
||||
}
|
||||
|
||||
pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
|
||||
@@ -132,13 +167,13 @@ pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
|
||||
pub fn values(
|
||||
&self,
|
||||
) -> 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,
|
||||
) -> 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> + '_ {
|
||||
@@ -165,33 +200,55 @@ pub(crate) fn get(&self, name: &Name) -> PerNs {
|
||||
}
|
||||
|
||||
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.
|
||||
pub(crate) fn name_of(&self, item: ItemInNs) -> Option<(&Name, Visibility)> {
|
||||
let (def, mut iter) = match item {
|
||||
ItemInNs::Macros(def) => {
|
||||
return self.macros.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)))
|
||||
match item {
|
||||
ItemInNs::Macros(def) => self
|
||||
.macros
|
||||
.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))),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn traits(&self) -> impl Iterator<Item = TraitId> + '_ {
|
||||
self.types
|
||||
.values()
|
||||
.filter_map(|&(def, _)| match def {
|
||||
.filter_map(|&(def, _, _)| match def {
|
||||
ModuleDefId::TraitId(t) => Some(t),
|
||||
_ => None,
|
||||
})
|
||||
.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, i))| {
|
||||
(
|
||||
None,
|
||||
PerNs::types(
|
||||
ModuleDefId::TraitId(*tr),
|
||||
*vis,
|
||||
i.map(ImportOrExternCrate::Import),
|
||||
),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemScope {
|
||||
pub(crate) fn declare(&mut self, def: ModuleDefId) {
|
||||
self.declarations.push(def)
|
||||
}
|
||||
@@ -277,12 +334,14 @@ impl Iterator<Item = (AttrId, MacroCallId, &[Option<MacroCallId>])>,
|
||||
})
|
||||
}
|
||||
|
||||
// FIXME: This is only used in collection, we should move the relevant parts of it out of ItemScope
|
||||
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) {
|
||||
self.unnamed_trait_imports.insert(tr, vis);
|
||||
// FIXME: import
|
||||
self.unnamed_trait_imports.insert(tr, (vis, None));
|
||||
}
|
||||
|
||||
pub(crate) fn push_res_with_import(
|
||||
@@ -290,51 +349,187 @@ pub(crate) fn push_res_with_import(
|
||||
glob_imports: &mut PerNsGlobImports,
|
||||
lookup: (LocalModuleId, Name),
|
||||
def: PerNs,
|
||||
def_import_type: ImportType,
|
||||
import: Option<ImportType>,
|
||||
) -> bool {
|
||||
let mut changed = false;
|
||||
|
||||
macro_rules! check_changed {
|
||||
(
|
||||
$changed:ident,
|
||||
( $this:ident / $def:ident ) . $field:ident,
|
||||
$glob_imports:ident [ $lookup:ident ],
|
||||
$def_import_type:ident
|
||||
) => {{
|
||||
if let Some(fld) = $def.$field {
|
||||
let existing = $this.$field.entry($lookup.1.clone());
|
||||
match existing {
|
||||
Entry::Vacant(entry) => {
|
||||
match $def_import_type {
|
||||
ImportType::Glob => {
|
||||
$glob_imports.$field.insert($lookup.clone());
|
||||
}
|
||||
ImportType::Named => {
|
||||
$glob_imports.$field.remove(&$lookup);
|
||||
}
|
||||
}
|
||||
// FIXME: Document and simplify this
|
||||
|
||||
entry.insert(fld);
|
||||
$changed = true;
|
||||
if let Some(mut fld) = def.types {
|
||||
let existing = self.types.entry(lookup.1.clone());
|
||||
match existing {
|
||||
Entry::Vacant(entry) => {
|
||||
match import {
|
||||
Some(ImportType::Glob(_)) => {
|
||||
glob_imports.types.insert(lookup.clone());
|
||||
}
|
||||
Entry::Occupied(mut entry)
|
||||
if matches!($def_import_type, ImportType::Named) =>
|
||||
{
|
||||
if $glob_imports.$field.remove(&$lookup) {
|
||||
cov_mark::hit!(import_shadowed);
|
||||
entry.insert(fld);
|
||||
$changed = true;
|
||||
_ => _ = glob_imports.types.remove(&lookup),
|
||||
}
|
||||
let import = match import {
|
||||
Some(ImportType::ExternCrate(extern_crate)) => {
|
||||
Some(ImportOrExternCrate::ExternCrate(extern_crate))
|
||||
}
|
||||
Some(ImportType::Import(import)) => {
|
||||
Some(ImportOrExternCrate::Import(import))
|
||||
}
|
||||
None | Some(ImportType::Glob(_)) => None,
|
||||
};
|
||||
let prev = std::mem::replace(&mut fld.2, import);
|
||||
if let Some(ImportOrExternCrate::Import(import)) = import {
|
||||
self.use_imports_values.insert(
|
||||
import,
|
||||
match prev {
|
||||
Some(ImportOrExternCrate::Import(import)) => {
|
||||
ImportOrDef::Import(import)
|
||||
}
|
||||
Some(ImportOrExternCrate::ExternCrate(import)) => {
|
||||
ImportOrDef::ExternCrate(import)
|
||||
}
|
||||
None => ImportOrDef::Def(fld.0),
|
||||
},
|
||||
);
|
||||
}
|
||||
entry.insert(fld);
|
||||
changed = true;
|
||||
}
|
||||
Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
|
||||
if glob_imports.types.remove(&lookup) {
|
||||
let import = match import {
|
||||
Some(ImportType::ExternCrate(extern_crate)) => {
|
||||
Some(ImportOrExternCrate::ExternCrate(extern_crate))
|
||||
}
|
||||
Some(ImportType::Import(import)) => {
|
||||
Some(ImportOrExternCrate::Import(import))
|
||||
}
|
||||
None | Some(ImportType::Glob(_)) => None,
|
||||
};
|
||||
let prev = std::mem::replace(&mut fld.2, import);
|
||||
if let Some(ImportOrExternCrate::Import(import)) = import {
|
||||
self.use_imports_values.insert(
|
||||
import,
|
||||
match prev {
|
||||
Some(ImportOrExternCrate::Import(import)) => {
|
||||
ImportOrDef::Import(import)
|
||||
}
|
||||
Some(ImportOrExternCrate::ExternCrate(import)) => {
|
||||
ImportOrDef::ExternCrate(import)
|
||||
}
|
||||
None => ImportOrDef::Def(fld.0),
|
||||
},
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
cov_mark::hit!(import_shadowed);
|
||||
entry.insert(fld);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}};
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
check_changed!(changed, (self / def).types, glob_imports[lookup], def_import_type);
|
||||
check_changed!(changed, (self / def).values, glob_imports[lookup], def_import_type);
|
||||
check_changed!(changed, (self / def).macros, glob_imports[lookup], def_import_type);
|
||||
if let Some(mut fld) = def.values {
|
||||
let existing = self.values.entry(lookup.1.clone());
|
||||
match existing {
|
||||
Entry::Vacant(entry) => {
|
||||
match import {
|
||||
Some(ImportType::Glob(_)) => {
|
||||
glob_imports.values.insert(lookup.clone());
|
||||
}
|
||||
_ => _ = glob_imports.values.remove(&lookup),
|
||||
}
|
||||
let import = match import {
|
||||
Some(ImportType::Import(import)) => Some(import),
|
||||
_ => None,
|
||||
};
|
||||
let prev = std::mem::replace(&mut fld.2, import);
|
||||
if let Some(import) = import {
|
||||
self.use_imports_values.insert(
|
||||
import,
|
||||
match prev {
|
||||
Some(import) => ImportOrDef::Import(import),
|
||||
None => ImportOrDef::Def(fld.0),
|
||||
},
|
||||
);
|
||||
}
|
||||
entry.insert(fld);
|
||||
changed = true;
|
||||
}
|
||||
Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
|
||||
if glob_imports.values.remove(&lookup) {
|
||||
cov_mark::hit!(import_shadowed);
|
||||
let import = match import {
|
||||
Some(ImportType::Import(import)) => Some(import),
|
||||
_ => None,
|
||||
};
|
||||
let prev = std::mem::replace(&mut fld.2, import);
|
||||
if let Some(import) = import {
|
||||
self.use_imports_values.insert(
|
||||
import,
|
||||
match prev {
|
||||
Some(import) => ImportOrDef::Import(import),
|
||||
None => ImportOrDef::Def(fld.0),
|
||||
},
|
||||
);
|
||||
}
|
||||
entry.insert(fld);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut fld) = def.macros {
|
||||
let existing = self.macros.entry(lookup.1.clone());
|
||||
match existing {
|
||||
Entry::Vacant(entry) => {
|
||||
match import {
|
||||
Some(ImportType::Glob(_)) => {
|
||||
glob_imports.macros.insert(lookup.clone());
|
||||
}
|
||||
_ => _ = glob_imports.macros.remove(&lookup),
|
||||
}
|
||||
let import = match import {
|
||||
Some(ImportType::Import(import)) => Some(import),
|
||||
_ => None,
|
||||
};
|
||||
let prev = std::mem::replace(&mut fld.2, import);
|
||||
if let Some(import) = import {
|
||||
self.use_imports_macros.insert(
|
||||
import,
|
||||
match prev {
|
||||
Some(import) => ImportOrDef::Import(import),
|
||||
None => ImportOrDef::Def(fld.0.into()),
|
||||
},
|
||||
);
|
||||
}
|
||||
entry.insert(fld);
|
||||
changed = true;
|
||||
}
|
||||
Entry::Occupied(mut entry) if !matches!(import, Some(ImportType::Glob(..))) => {
|
||||
if glob_imports.macros.remove(&lookup) {
|
||||
cov_mark::hit!(import_shadowed);
|
||||
let import = match import {
|
||||
Some(ImportType::Import(import)) => Some(import),
|
||||
_ => None,
|
||||
};
|
||||
let prev = std::mem::replace(&mut fld.2, import);
|
||||
if let Some(import) = import {
|
||||
self.use_imports_macros.insert(
|
||||
import,
|
||||
match prev {
|
||||
Some(import) => ImportOrDef::Import(import),
|
||||
None => ImportOrDef::Def(fld.0.into()),
|
||||
},
|
||||
);
|
||||
}
|
||||
entry.insert(fld);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if def.is_none() && self.unresolved.insert(lookup.1) {
|
||||
changed = true;
|
||||
@@ -343,27 +538,18 @@ macro_rules! check_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`.
|
||||
pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) {
|
||||
self.types
|
||||
.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)
|
||||
.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 (mac, vis) in self.macros.values_mut() {
|
||||
if let MacroId::ProcMacroId(_) = mac {
|
||||
// FIXME: Technically this is insufficient since reexports of proc macros are also
|
||||
// forbidden. Practically nobody does that.
|
||||
for (mac, vis, import) in self.macros.values_mut() {
|
||||
if matches!(mac, MacroId::ProcMacroId(_) if import.is_none()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -382,14 +568,25 @@ pub(crate) fn dump(&self, db: &dyn ExpandDatabase, buf: &mut String) {
|
||||
name.map_or("_".to_string(), |name| name.display(db).to_string())
|
||||
);
|
||||
|
||||
if def.types.is_some() {
|
||||
if let Some((.., i)) = def.types {
|
||||
buf.push_str(" t");
|
||||
match i {
|
||||
Some(ImportOrExternCrate::Import(_)) => buf.push('i'),
|
||||
Some(ImportOrExternCrate::ExternCrate(_)) => buf.push('e'),
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
if def.values.is_some() {
|
||||
if let Some((.., i)) = def.values {
|
||||
buf.push_str(" v");
|
||||
if i.is_some() {
|
||||
buf.push('i');
|
||||
}
|
||||
}
|
||||
if def.macros.is_some() {
|
||||
if let Some((.., i)) = def.macros {
|
||||
buf.push_str(" m");
|
||||
if i.is_some() {
|
||||
buf.push('i');
|
||||
}
|
||||
}
|
||||
if def.is_none() {
|
||||
buf.push_str(" _");
|
||||
@@ -415,10 +612,17 @@ pub(crate) fn shrink_to_fit(&mut self) {
|
||||
attr_macros,
|
||||
derive_macros,
|
||||
extern_crate_decls,
|
||||
use_decls,
|
||||
use_imports_values,
|
||||
use_imports_types,
|
||||
use_imports_macros,
|
||||
} = self;
|
||||
types.shrink_to_fit();
|
||||
values.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();
|
||||
declarations.shrink_to_fit();
|
||||
impls.shrink_to_fit();
|
||||
@@ -428,32 +632,44 @@ pub(crate) fn shrink_to_fit(&mut self) {
|
||||
attr_macros.shrink_to_fit();
|
||||
derive_macros.shrink_to_fit();
|
||||
extern_crate_decls.shrink_to_fit();
|
||||
use_decls.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
impl PerNs {
|
||||
pub(crate) fn from_def(def: ModuleDefId, v: Visibility, has_constructor: bool) -> PerNs {
|
||||
pub(crate) fn from_def(
|
||||
def: ModuleDefId,
|
||||
v: Visibility,
|
||||
has_constructor: bool,
|
||||
import: Option<ImportOrExternCrate>,
|
||||
) -> PerNs {
|
||||
match def {
|
||||
ModuleDefId::ModuleId(_) => PerNs::types(def, v),
|
||||
ModuleDefId::FunctionId(_) => PerNs::values(def, v),
|
||||
ModuleDefId::ModuleId(_) => PerNs::types(def, v, import),
|
||||
ModuleDefId::FunctionId(_) => {
|
||||
PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
|
||||
}
|
||||
ModuleDefId::AdtId(adt) => match adt {
|
||||
AdtId::UnionId(_) => PerNs::types(def, v),
|
||||
AdtId::EnumId(_) => PerNs::types(def, v),
|
||||
AdtId::UnionId(_) => PerNs::types(def, v, import),
|
||||
AdtId::EnumId(_) => PerNs::types(def, v, import),
|
||||
AdtId::StructId(_) => {
|
||||
if has_constructor {
|
||||
PerNs::both(def, def, v)
|
||||
PerNs::both(def, def, v, import)
|
||||
} else {
|
||||
PerNs::types(def, v)
|
||||
PerNs::types(def, v, import)
|
||||
}
|
||||
}
|
||||
},
|
||||
ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v),
|
||||
ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),
|
||||
ModuleDefId::TraitId(_) => PerNs::types(def, v),
|
||||
ModuleDefId::TraitAliasId(_) => PerNs::types(def, v),
|
||||
ModuleDefId::TypeAliasId(_) => PerNs::types(def, v),
|
||||
ModuleDefId::BuiltinType(_) => PerNs::types(def, v),
|
||||
ModuleDefId::MacroId(mac) => PerNs::macros(mac, v),
|
||||
ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v, import),
|
||||
ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => {
|
||||
PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
|
||||
}
|
||||
ModuleDefId::TraitId(_) => PerNs::types(def, v, import),
|
||||
ModuleDefId::TraitAliasId(_) => PerNs::types(def, v, import),
|
||||
ModuleDefId::TypeAliasId(_) => PerNs::types(def, v, import),
|
||||
ModuleDefId::BuiltinType(_) => PerNs::types(def, v, import),
|
||||
ModuleDefId::MacroId(mac) => {
|
||||
PerNs::macros(mac, v, import.and_then(ImportOrExternCrate::into_import))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,6 +865,7 @@ pub enum AttrDefId {
|
||||
ConstId,
|
||||
FunctionId,
|
||||
TraitId,
|
||||
TraitAliasId,
|
||||
TypeAliasId,
|
||||
MacroId(Macro2Id, MacroRulesId, ProcMacroId),
|
||||
ImplId,
|
||||
@@ -873,6 +874,26 @@ pub enum 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 {
|
||||
fn from(acid: ItemContainerId) -> Self {
|
||||
match acid {
|
||||
|
||||
@@ -131,7 +131,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
|
||||
.as_call_id_with_errors(&db, krate, |path| {
|
||||
resolver
|
||||
.resolve_path_as_macro(&db, &path, Some(MacroSubNs::Bang))
|
||||
.map(|it| macro_id_to_def_id(&db, it))
|
||||
.map(|(it, _)| macro_id_to_def_id(&db, it))
|
||||
})
|
||||
.unwrap();
|
||||
let macro_call_id = res.value.unwrap();
|
||||
|
||||
@@ -108,6 +108,7 @@ pub struct DefMap {
|
||||
prelude: Option<(ModuleId, Option<UseId>)>,
|
||||
/// `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.
|
||||
/// ExternCrateId being None implies it being imported from the general prelude import.
|
||||
macro_use_prelude: FxHashMap<Name, (MacroId, Option<ExternCrateId>)>,
|
||||
|
||||
/// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
attr_macro_as_call_id,
|
||||
db::DefDatabase,
|
||||
derive_macro_as_call_id,
|
||||
item_scope::{ImportType, PerNsGlobImports},
|
||||
item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
|
||||
item_tree::{
|
||||
self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode,
|
||||
MacroCall, MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId,
|
||||
@@ -146,7 +146,7 @@ fn namespaces(self) -> PerNs {
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
enum ImportSource {
|
||||
Use { use_tree: Idx<ast::UseTree>, id: UseId, is_prelude: bool },
|
||||
Use { use_tree: Idx<ast::UseTree>, id: UseId, is_prelude: bool, kind: ImportKind },
|
||||
ExternCrate { id: ExternCrateId },
|
||||
}
|
||||
|
||||
@@ -155,7 +155,6 @@ struct Import {
|
||||
path: ModPath,
|
||||
alias: Option<ImportAlias>,
|
||||
visibility: RawVisibility,
|
||||
kind: ImportKind,
|
||||
source: ImportSource,
|
||||
}
|
||||
|
||||
@@ -174,8 +173,7 @@ fn from_use(
|
||||
path,
|
||||
alias,
|
||||
visibility: visibility.clone(),
|
||||
kind,
|
||||
source: ImportSource::Use { use_tree: idx, id, is_prelude },
|
||||
source: ImportSource::Use { use_tree: idx, id, is_prelude, kind },
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -191,7 +189,6 @@ fn from_extern_crate(
|
||||
path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
|
||||
alias: it.alias.clone(),
|
||||
visibility: visibility.clone(),
|
||||
kind: ImportKind::Plain,
|
||||
source: ImportSource::ExternCrate { id },
|
||||
}
|
||||
}
|
||||
@@ -225,7 +222,7 @@ struct DefCollector<'a> {
|
||||
db: &'a dyn DefDatabase,
|
||||
def_map: DefMap,
|
||||
deps: FxHashMap<Name, Dependency>,
|
||||
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
|
||||
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, UseId)>>,
|
||||
unresolved_imports: Vec<ImportDirective>,
|
||||
indeterminate_imports: Vec<ImportDirective>,
|
||||
unresolved_macros: Vec<MacroDirective>,
|
||||
@@ -546,8 +543,12 @@ fn inject_prelude(&mut self) {
|
||||
self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
|
||||
|
||||
match per_ns.types {
|
||||
Some((ModuleDefId::ModuleId(m), _)) => {
|
||||
self.def_map.prelude = Some((m, None));
|
||||
Some((ModuleDefId::ModuleId(m), _, import)) => {
|
||||
// FIXME: This should specifically look for a glob import somehow and record that here
|
||||
self.def_map.prelude = Some((
|
||||
m,
|
||||
import.and_then(ImportOrExternCrate::into_import).map(|it| it.import),
|
||||
));
|
||||
}
|
||||
types => {
|
||||
tracing::debug!(
|
||||
@@ -647,9 +648,9 @@ fn define_macro_rules(
|
||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||
self.update(
|
||||
module_id,
|
||||
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
|
||||
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
|
||||
Visibility::Public,
|
||||
ImportType::Named,
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -683,9 +684,9 @@ fn define_macro_def(
|
||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||
self.update(
|
||||
module_id,
|
||||
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
|
||||
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
|
||||
vis,
|
||||
ImportType::Named,
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -698,9 +699,9 @@ fn define_proc_macro(&mut self, name: Name, macro_: ProcMacroId) {
|
||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||
self.update(
|
||||
module_id,
|
||||
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
|
||||
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
|
||||
Visibility::Public,
|
||||
ImportType::Named,
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -714,23 +715,25 @@ fn import_macros_from_extern_crate(
|
||||
&mut self,
|
||||
krate: CrateId,
|
||||
names: Option<Vec<Name>>,
|
||||
|
||||
extern_crate: Option<ExternCrateId>,
|
||||
) {
|
||||
let def_map = self.db.crate_def_map(krate);
|
||||
// `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!`
|
||||
// macros.
|
||||
let root_scope = &def_map[DefMap::ROOT].scope;
|
||||
if let Some(names) = names {
|
||||
for name in names {
|
||||
// FIXME: Report diagnostic on 404.
|
||||
if let Some(def) = root_scope.get(&name).take_macros() {
|
||||
self.def_map.macro_use_prelude.insert(name, (def, extern_crate));
|
||||
match names {
|
||||
Some(names) => {
|
||||
for name in names {
|
||||
// FIXME: Report diagnostic on 404.
|
||||
if let Some(def) = root_scope.get(&name).take_macros() {
|
||||
self.def_map.macro_use_prelude.insert(name, (def, extern_crate));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (name, def) in root_scope.macros() {
|
||||
self.def_map.macro_use_prelude.insert(name.clone(), (def, extern_crate));
|
||||
None => {
|
||||
for (name, def) in root_scope.macros() {
|
||||
self.def_map.macro_use_prelude.insert(name.clone(), (def, extern_crate));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -780,6 +783,7 @@ fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialRe
|
||||
Some(res) => PartialResolvedImport::Resolved(PerNs::types(
|
||||
res.into(),
|
||||
Visibility::Public,
|
||||
None,
|
||||
)),
|
||||
None => PartialResolvedImport::Unresolved,
|
||||
}
|
||||
@@ -837,8 +841,9 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
||||
.resolve_visibility(self.db, module_id, &directive.import.visibility, false)
|
||||
.unwrap_or(Visibility::Public);
|
||||
|
||||
match import.kind {
|
||||
ImportKind::Plain | ImportKind::TypeOnly => {
|
||||
match import.source {
|
||||
ImportSource::ExternCrate { .. }
|
||||
| ImportSource::Use { kind: ImportKind::Plain | ImportKind::TypeOnly, .. } => {
|
||||
let name = match &import.alias {
|
||||
Some(ImportAlias::Alias(name)) => Some(name),
|
||||
Some(ImportAlias::Underscore) => None,
|
||||
@@ -851,32 +856,36 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
||||
},
|
||||
};
|
||||
|
||||
if import.kind == ImportKind::TypeOnly {
|
||||
def.values = None;
|
||||
def.macros = None;
|
||||
}
|
||||
|
||||
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 let ImportSource::ExternCrate { id, .. } = import.source {
|
||||
if self.def_map.block.is_none() && module_id == DefMap::ROOT {
|
||||
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) =
|
||||
(def.take_types(), name)
|
||||
{
|
||||
if let Ok(def) = def.try_into() {
|
||||
Arc::get_mut(&mut self.def_map.data)
|
||||
.unwrap()
|
||||
.extern_prelude
|
||||
.insert(name.clone(), (def, Some(id)));
|
||||
let imp = match import.source {
|
||||
// extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
|
||||
ImportSource::ExternCrate { id, .. } => {
|
||||
if self.def_map.block.is_none() && module_id == DefMap::ROOT {
|
||||
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) =
|
||||
(def.take_types(), name)
|
||||
{
|
||||
if let Ok(def) = def.try_into() {
|
||||
Arc::get_mut(&mut self.def_map.data)
|
||||
.unwrap()
|
||||
.extern_prelude
|
||||
.insert(name.clone(), (def, Some(id)));
|
||||
}
|
||||
}
|
||||
}
|
||||
ImportType::ExternCrate(id)
|
||||
}
|
||||
}
|
||||
ImportSource::Use { kind, id, use_tree, .. } => {
|
||||
if kind == ImportKind::TypeOnly {
|
||||
def.values = None;
|
||||
def.macros = None;
|
||||
}
|
||||
ImportType::Import(ImportId { import: id, idx: use_tree })
|
||||
}
|
||||
};
|
||||
tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
|
||||
|
||||
self.update(module_id, &[(name.cloned(), def)], vis, ImportType::Named);
|
||||
self.update(module_id, &[(name.cloned(), def)], vis, Some(imp));
|
||||
}
|
||||
ImportKind::Glob => {
|
||||
ImportSource::Use { kind: ImportKind::Glob, id, .. } => {
|
||||
tracing::debug!("glob import: {:?}", import);
|
||||
match def.take_types() {
|
||||
Some(ModuleDefId::ModuleId(m)) => {
|
||||
@@ -901,7 +910,7 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
||||
.filter(|(_, res)| !res.is_none())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.update(module_id, &items, vis, ImportType::Glob);
|
||||
self.update(module_id, &items, vis, Some(ImportType::Glob(id)));
|
||||
} else {
|
||||
// glob import from same crate => we do an initial
|
||||
// import, and then need to propagate any further
|
||||
@@ -933,11 +942,11 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
||||
.filter(|(_, res)| !res.is_none())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.update(module_id, &items, vis, ImportType::Glob);
|
||||
self.update(module_id, &items, vis, Some(ImportType::Glob(id)));
|
||||
// record the glob import in case we add further items
|
||||
let glob = self.glob_imports.entry(m.local_id).or_default();
|
||||
if !glob.iter().any(|(mid, _)| *mid == module_id) {
|
||||
glob.push((module_id, vis));
|
||||
if !glob.iter().any(|(mid, _, _)| *mid == module_id) {
|
||||
glob.push((module_id, vis, id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -959,11 +968,11 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
||||
.map(|(local_id, variant_data)| {
|
||||
let name = variant_data.name.clone();
|
||||
let variant = EnumVariantId { parent: e, local_id };
|
||||
let res = PerNs::both(variant.into(), variant.into(), vis);
|
||||
let res = PerNs::both(variant.into(), variant.into(), vis, None);
|
||||
(Some(name), res)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
self.update(module_id, &resolutions, vis, ImportType::Glob);
|
||||
self.update(module_id, &resolutions, vis, Some(ImportType::Glob(id)));
|
||||
}
|
||||
Some(d) => {
|
||||
tracing::debug!("glob import {:?} from non-module/enum {:?}", import, d);
|
||||
@@ -983,10 +992,10 @@ fn update(
|
||||
resolutions: &[(Option<Name>, PerNs)],
|
||||
// Visibility this import will have
|
||||
vis: Visibility,
|
||||
import_type: ImportType,
|
||||
import: Option<ImportType>,
|
||||
) {
|
||||
self.db.unwind_if_cancelled();
|
||||
self.update_recursive(module_id, resolutions, vis, import_type, 0)
|
||||
self.update_recursive(module_id, resolutions, vis, import, 0)
|
||||
}
|
||||
|
||||
fn update_recursive(
|
||||
@@ -997,7 +1006,7 @@ fn update_recursive(
|
||||
// All resolutions are imported with this visibility; the visibilities in
|
||||
// the `PerNs` values are ignored and overwritten
|
||||
vis: Visibility,
|
||||
import_type: ImportType,
|
||||
import: Option<ImportType>,
|
||||
depth: usize,
|
||||
) {
|
||||
if GLOB_RECURSION_LIMIT.check(depth).is_err() {
|
||||
@@ -1014,7 +1023,7 @@ fn update_recursive(
|
||||
&mut self.from_glob_import,
|
||||
(module_id, name.clone()),
|
||||
res.with_visibility(vis),
|
||||
import_type,
|
||||
import,
|
||||
);
|
||||
}
|
||||
None => {
|
||||
@@ -1059,7 +1068,7 @@ fn update_recursive(
|
||||
.get(&module_id)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter(|(glob_importing_module, _)| {
|
||||
.filter(|(glob_importing_module, _, _)| {
|
||||
// we know all resolutions have the same visibility (`vis`), so we
|
||||
// just need to check that once
|
||||
vis.is_visible_from_def_map(self.db, &self.def_map, *glob_importing_module)
|
||||
@@ -1067,12 +1076,12 @@ fn update_recursive(
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for (glob_importing_module, glob_import_vis) in glob_imports {
|
||||
for (glob_importing_module, glob_import_vis, use_) in glob_imports {
|
||||
self.update_recursive(
|
||||
glob_importing_module,
|
||||
resolutions,
|
||||
glob_import_vis,
|
||||
ImportType::Glob,
|
||||
Some(ImportType::Glob(use_)),
|
||||
depth + 1,
|
||||
);
|
||||
}
|
||||
@@ -1475,7 +1484,9 @@ fn finish(mut self) -> DefMap {
|
||||
}
|
||||
|
||||
for directive in &self.unresolved_imports {
|
||||
if let ImportSource::Use { use_tree, id, is_prelude: _ } = directive.import.source {
|
||||
if let ImportSource::Use { use_tree, id, is_prelude: _, kind: _ } =
|
||||
directive.import.source
|
||||
{
|
||||
if matches!(
|
||||
(directive.import.path.segments().first(), &directive.import.path.kind),
|
||||
(Some(krate), PathKind::Plain | PathKind::Abs) if diagnosed_extern_crates.contains(krate)
|
||||
@@ -1537,9 +1548,9 @@ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
|
||||
def_collector.def_map.modules[module_id].scope.declare(id);
|
||||
def_collector.update(
|
||||
module_id,
|
||||
&[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
|
||||
&[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor, None))],
|
||||
vis,
|
||||
ImportType::Named,
|
||||
None,
|
||||
)
|
||||
};
|
||||
let resolve_vis = |def_map: &DefMap, visibility| {
|
||||
@@ -1967,9 +1978,9 @@ fn push_child_module(
|
||||
def_map.modules[self.module_id].scope.declare(def);
|
||||
self.def_collector.update(
|
||||
self.module_id,
|
||||
&[(Some(name), PerNs::from_def(def, vis, false))],
|
||||
&[(Some(name), PerNs::from_def(def, vis, false, None))],
|
||||
vis,
|
||||
ImportType::Named,
|
||||
None,
|
||||
);
|
||||
res
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
data::adt::VariantData,
|
||||
db::DefDatabase,
|
||||
item_scope::BUILTIN_SCOPE,
|
||||
item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
|
||||
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
|
||||
path::{ModPath, PathKind},
|
||||
per_ns::PerNs,
|
||||
@@ -65,7 +66,7 @@ pub(super) fn filter_macro(
|
||||
db: &dyn DefDatabase,
|
||||
expected: Option<MacroSubNs>,
|
||||
) -> Self {
|
||||
self.macros = self.macros.filter(|&(id, _)| {
|
||||
self.macros = self.macros.filter(|&(id, _, _)| {
|
||||
let this = MacroSubNs::from_id(db, id);
|
||||
sub_namespace_match(Some(this), expected)
|
||||
});
|
||||
@@ -196,15 +197,15 @@ pub(super) fn resolve_path_fp_with_macro_single(
|
||||
PathKind::DollarCrate(krate) => {
|
||||
if krate == self.krate {
|
||||
cov_mark::hit!(macro_dollar_crate_self);
|
||||
PerNs::types(self.crate_root().into(), Visibility::Public)
|
||||
PerNs::types(self.crate_root().into(), Visibility::Public, None)
|
||||
} else {
|
||||
let def_map = db.crate_def_map(krate);
|
||||
let module = def_map.module_id(Self::ROOT);
|
||||
cov_mark::hit!(macro_dollar_crate_other);
|
||||
PerNs::types(module.into(), Visibility::Public)
|
||||
PerNs::types(module.into(), Visibility::Public, None)
|
||||
}
|
||||
}
|
||||
PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public),
|
||||
PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public, None),
|
||||
// plain import or absolute path in 2015: crate-relative with
|
||||
// fallback to extern prelude (with the simplification in
|
||||
// rust-lang/rust#57745)
|
||||
@@ -291,7 +292,7 @@ pub(super) fn resolve_path_fp_with_macro_single(
|
||||
);
|
||||
}
|
||||
|
||||
PerNs::types(module.into(), Visibility::Public)
|
||||
PerNs::types(module.into(), Visibility::Public, None)
|
||||
}
|
||||
PathKind::Abs => {
|
||||
// 2018-style absolute path -- only extern prelude
|
||||
@@ -299,9 +300,13 @@ pub(super) fn resolve_path_fp_with_macro_single(
|
||||
Some((_, segment)) => segment,
|
||||
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
|
||||
};
|
||||
if let Some(&(def, _extern_crate)) = self.data.extern_prelude.get(segment) {
|
||||
if let Some(&(def, extern_crate)) = self.data.extern_prelude.get(segment) {
|
||||
tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def);
|
||||
PerNs::types(def.into(), Visibility::Public)
|
||||
PerNs::types(
|
||||
def.into(),
|
||||
Visibility::Public,
|
||||
extern_crate.map(ImportOrExternCrate::ExternCrate),
|
||||
)
|
||||
} else {
|
||||
return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
|
||||
}
|
||||
@@ -309,7 +314,7 @@ pub(super) fn resolve_path_fp_with_macro_single(
|
||||
};
|
||||
|
||||
for (i, segment) in segments {
|
||||
let (curr, vis) = match curr_per_ns.take_types_vis() {
|
||||
let (curr, vis, imp) = match curr_per_ns.take_types_full() {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
// we still have path segments left, but the path so far
|
||||
@@ -364,18 +369,20 @@ pub(super) fn resolve_path_fp_with_macro_single(
|
||||
Some(local_id) => {
|
||||
let variant = EnumVariantId { parent: e, local_id };
|
||||
match &*enum_data.variants[local_id].variant_data {
|
||||
crate::data::adt::VariantData::Record(_) => {
|
||||
PerNs::types(variant.into(), Visibility::Public)
|
||||
}
|
||||
crate::data::adt::VariantData::Tuple(_)
|
||||
| crate::data::adt::VariantData::Unit => {
|
||||
PerNs::both(variant.into(), variant.into(), Visibility::Public)
|
||||
VariantData::Record(_) => {
|
||||
PerNs::types(variant.into(), Visibility::Public, None)
|
||||
}
|
||||
VariantData::Tuple(_) | VariantData::Unit => PerNs::both(
|
||||
variant.into(),
|
||||
variant.into(),
|
||||
Visibility::Public,
|
||||
None,
|
||||
),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return ResolvePathResult::with(
|
||||
PerNs::types(e.into(), vis),
|
||||
PerNs::types(e.into(), vis, imp),
|
||||
ReachedFixedPoint::Yes,
|
||||
Some(i),
|
||||
Some(self.krate),
|
||||
@@ -393,7 +400,7 @@ pub(super) fn resolve_path_fp_with_macro_single(
|
||||
);
|
||||
|
||||
return ResolvePathResult::with(
|
||||
PerNs::types(s, vis),
|
||||
PerNs::types(s, vis, imp),
|
||||
ReachedFixedPoint::Yes,
|
||||
Some(i),
|
||||
Some(self.krate),
|
||||
@@ -430,7 +437,7 @@ fn resolve_name_in_module(
|
||||
.filter(|&id| {
|
||||
sub_namespace_match(Some(MacroSubNs::from_id(db, id)), expected_macro_subns)
|
||||
})
|
||||
.map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
|
||||
.map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public, None));
|
||||
let from_scope = self[module].scope.get(name).filter_macro(db, expected_macro_subns);
|
||||
let from_builtin = match self.block {
|
||||
Some(_) => {
|
||||
@@ -449,16 +456,26 @@ fn resolve_name_in_module(
|
||||
|
||||
let extern_prelude = || {
|
||||
if self.block.is_some() {
|
||||
// Don't resolve extern prelude in block `DefMap`s.
|
||||
// Don't resolve extern prelude in block `DefMap`s, defer it to the crate def map so
|
||||
// that blocks can properly shadow them
|
||||
return PerNs::none();
|
||||
}
|
||||
self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
|
||||
PerNs::types(it.into(), Visibility::Public)
|
||||
self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {
|
||||
PerNs::types(
|
||||
it.into(),
|
||||
Visibility::Public,
|
||||
extern_crate.map(ImportOrExternCrate::ExternCrate),
|
||||
)
|
||||
})
|
||||
};
|
||||
let macro_use_prelude = || {
|
||||
self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
|
||||
PerNs::macros(it.into(), Visibility::Public)
|
||||
PerNs::macros(
|
||||
it.into(),
|
||||
Visibility::Public,
|
||||
// FIXME?
|
||||
None, // extern_crate.map(ImportOrExternCrate::ExternCrate),
|
||||
)
|
||||
})
|
||||
};
|
||||
let prelude = || self.resolve_in_prelude(db, name);
|
||||
@@ -487,13 +504,16 @@ fn resolve_name_in_crate_root_or_extern_prelude(
|
||||
// Don't resolve extern prelude in block `DefMap`s.
|
||||
return PerNs::none();
|
||||
}
|
||||
self.data
|
||||
.extern_prelude
|
||||
.get(name)
|
||||
.copied()
|
||||
.map_or(PerNs::none(), |(it, _extern_crate)| {
|
||||
PerNs::types(it.into(), Visibility::Public)
|
||||
})
|
||||
self.data.extern_prelude.get(name).copied().map_or(
|
||||
PerNs::none(),
|
||||
|(it, extern_crate)| {
|
||||
PerNs::types(
|
||||
it.into(),
|
||||
Visibility::Public,
|
||||
extern_crate.map(ImportOrExternCrate::ExternCrate),
|
||||
)
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
from_crate_root.or_else(from_extern_prelude)
|
||||
|
||||
@@ -168,7 +168,7 @@ fn use_as() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Foo: t v
|
||||
Foo: ti vi
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
@@ -194,8 +194,8 @@ fn use_trees() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Baz: t v
|
||||
Quux: t
|
||||
Baz: ti vi
|
||||
Quux: ti
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
@@ -225,11 +225,11 @@ fn re_exports() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
bar: t
|
||||
|
||||
crate::foo::bar
|
||||
@@ -274,7 +274,7 @@ enum E { V }
|
||||
expect![[r#"
|
||||
crate
|
||||
E: t
|
||||
V: t v
|
||||
V: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -307,7 +307,7 @@ fn edition_2015_imports() {
|
||||
|
||||
crate::foo
|
||||
Bar: _
|
||||
FromLib: t v
|
||||
FromLib: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -328,7 +328,7 @@ fn item_map_using_self() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Baz: t
|
||||
Baz: ti
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
@@ -352,7 +352,7 @@ fn item_map_across_crates() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -375,13 +375,13 @@ fn extern_crate_rename() {
|
||||
expect![[r#"
|
||||
crate
|
||||
alloc: t
|
||||
alloc_crate: t
|
||||
alloc_crate: te
|
||||
sync: t
|
||||
|
||||
crate::alloc
|
||||
|
||||
crate::sync
|
||||
Arc: t v
|
||||
Arc: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -404,13 +404,13 @@ fn extern_crate_rename_2015_edition() {
|
||||
expect![[r#"
|
||||
crate
|
||||
alloc: t
|
||||
alloc_crate: t
|
||||
alloc_crate: te
|
||||
sync: t
|
||||
|
||||
crate::alloc
|
||||
|
||||
crate::sync
|
||||
Arc: t v
|
||||
Arc: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -426,7 +426,7 @@ fn macro_use_extern_crate_self() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
bla: t
|
||||
bla: te
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -447,7 +447,7 @@ fn reexport_across_crates() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -465,7 +465,7 @@ fn foo() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Bar: ti vi
|
||||
foo: v
|
||||
"#]],
|
||||
);
|
||||
@@ -492,9 +492,9 @@ pub mod rust_2018 {
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Rust: t v
|
||||
"#]],
|
||||
crate
|
||||
Rust: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -516,9 +516,9 @@ pub mod rust_2018 {
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Rust2018: t v
|
||||
"#]],
|
||||
crate
|
||||
Rust2018: ti vi
|
||||
"#]],
|
||||
);
|
||||
check(
|
||||
r#"
|
||||
@@ -533,9 +533,9 @@ pub mod rust_2021 {
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Rust2021: t v
|
||||
"#]],
|
||||
crate
|
||||
Rust2021: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -563,8 +563,8 @@ pub mod rust_2018 {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Foo: t v
|
||||
Bar: ti vi
|
||||
Foo: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -590,7 +590,7 @@ pub mod rust_2018 {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Bar: ti vi
|
||||
Baz: _
|
||||
Foo: _
|
||||
"#]],
|
||||
@@ -619,8 +619,8 @@ pub mod rust_2018 {
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: _
|
||||
Baz: t v
|
||||
Foo: t v
|
||||
Baz: ti vi
|
||||
Foo: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -643,7 +643,7 @@ mod b {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
T: t v
|
||||
T: ti vi
|
||||
a: t
|
||||
b: t
|
||||
|
||||
@@ -816,8 +816,8 @@ fn bar() {}
|
||||
expect![[r#"
|
||||
crate
|
||||
bar: v
|
||||
baz: v
|
||||
foo: t
|
||||
baz: vi
|
||||
foo: ti
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -836,7 +836,7 @@ mod m {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
S: t
|
||||
S: ti
|
||||
m: t
|
||||
|
||||
crate::m
|
||||
@@ -860,8 +860,8 @@ mod settings {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Settings: t v
|
||||
settings: v
|
||||
Settings: ti vi
|
||||
settings: vi
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
@@ -890,8 +890,8 @@ fn non_prelude_deps() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Struct: t v
|
||||
dep: t
|
||||
Struct: ti vi
|
||||
dep: te
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -917,13 +917,13 @@ mod some_submodule {
|
||||
crate
|
||||
other_module: t
|
||||
some_module: t
|
||||
unknown_func: v
|
||||
unknown_func: vi
|
||||
|
||||
crate::other_module
|
||||
some_submodule: t
|
||||
|
||||
crate::other_module::some_submodule
|
||||
unknown_func: v
|
||||
unknown_func: vi
|
||||
|
||||
crate::some_module
|
||||
unknown_func: v
|
||||
|
||||
@@ -24,7 +24,7 @@ fn glob_1() {
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
Foo: t v
|
||||
bar: t
|
||||
|
||||
@@ -237,9 +237,9 @@ fn glob_shadowed_def() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Bar: ti vi
|
||||
bar: t
|
||||
baz: t
|
||||
baz: ti
|
||||
foo: t
|
||||
|
||||
crate::bar
|
||||
@@ -276,9 +276,9 @@ fn glob_shadowed_def_reversed() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Bar: ti vi
|
||||
bar: t
|
||||
baz: t
|
||||
baz: ti
|
||||
foo: t
|
||||
|
||||
crate::bar
|
||||
@@ -323,7 +323,7 @@ mod d {
|
||||
X: t v
|
||||
|
||||
crate::b
|
||||
foo: t
|
||||
foo: ti
|
||||
|
||||
crate::c
|
||||
foo: t
|
||||
@@ -332,8 +332,8 @@ mod d {
|
||||
Y: t v
|
||||
|
||||
crate::d
|
||||
Y: t v
|
||||
foo: t
|
||||
Y: ti vi
|
||||
foo: ti
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -355,7 +355,7 @@ pub struct Event {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Event: t
|
||||
Event: ti
|
||||
event: t
|
||||
|
||||
crate::event
|
||||
|
||||
@@ -212,7 +212,7 @@ impl Tr for () {}
|
||||
}
|
||||
|
||||
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::AdtId(adt) => match adt {
|
||||
AdtId::StructId(it) => _ = db.struct_data(it),
|
||||
|
||||
@@ -203,8 +203,8 @@ macro_rules! bar {
|
||||
expect![[r#"
|
||||
crate
|
||||
Foo: t
|
||||
bar: m
|
||||
foo: m
|
||||
bar: mi
|
||||
foo: mi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -251,7 +251,7 @@ macro_rules! structs_priv {
|
||||
Bar: t v
|
||||
Foo: t v
|
||||
bar: t
|
||||
foo: t
|
||||
foo: te
|
||||
|
||||
crate::bar
|
||||
Baz: t v
|
||||
@@ -318,9 +318,9 @@ fn macro_use_filter() {
|
||||
OkBaz1: t v
|
||||
OkBaz2: t v
|
||||
OkBaz3: t v
|
||||
all: t
|
||||
empty: t
|
||||
multiple: t
|
||||
all: te
|
||||
empty: te
|
||||
multiple: te
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -551,8 +551,8 @@ fn baz() {}
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
bar: t m
|
||||
baz: t v m
|
||||
bar: ti mi
|
||||
baz: ti v mi
|
||||
foo: t m
|
||||
"#]],
|
||||
);
|
||||
@@ -583,7 +583,7 @@ macro_rules! foo {
|
||||
crate
|
||||
Alias: t v
|
||||
Direct: t v
|
||||
foo: t
|
||||
foo: te
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -628,9 +628,9 @@ macro_rules! bar {
|
||||
m: t
|
||||
|
||||
crate::m
|
||||
alias1: m
|
||||
alias2: m
|
||||
alias3: m
|
||||
alias1: mi
|
||||
alias2: mi
|
||||
alias3: mi
|
||||
not_found: _
|
||||
"#]],
|
||||
);
|
||||
@@ -682,11 +682,11 @@ macro_rules! not_current2 {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Baz: t v
|
||||
Bar: ti vi
|
||||
Baz: ti vi
|
||||
Foo: t v
|
||||
FooSelf: t v
|
||||
foo: t
|
||||
FooSelf: ti vi
|
||||
foo: te
|
||||
m: t
|
||||
|
||||
crate::m
|
||||
@@ -725,7 +725,7 @@ macro_rules! foo {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
bar: t v
|
||||
bar: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -1340,7 +1340,7 @@ macro_rules! bar {
|
||||
crate
|
||||
Ok: t v
|
||||
bar: m
|
||||
dep: t
|
||||
dep: te
|
||||
foo: m
|
||||
ok: v
|
||||
"#]],
|
||||
@@ -1370,13 +1370,13 @@ macro_rules! foo {
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
a: t
|
||||
lib: t
|
||||
crate
|
||||
a: t
|
||||
lib: te
|
||||
|
||||
crate::a
|
||||
Ok: t v
|
||||
"#]],
|
||||
crate::a
|
||||
Ok: t v
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1427,8 +1427,8 @@ fn ok() {}
|
||||
expect![[r#"
|
||||
crate
|
||||
Ok: t v
|
||||
bar: m
|
||||
foo: m
|
||||
bar: mi
|
||||
foo: mi
|
||||
ok: v
|
||||
"#]],
|
||||
);
|
||||
|
||||
@@ -80,18 +80,18 @@ fn nested_module_resolution_2() {
|
||||
prelude: t
|
||||
|
||||
crate::iter
|
||||
Iterator: t
|
||||
Iterator: ti
|
||||
traits: t
|
||||
|
||||
crate::iter::traits
|
||||
Iterator: t
|
||||
Iterator: ti
|
||||
iterator: t
|
||||
|
||||
crate::iter::traits::iterator
|
||||
Iterator: t
|
||||
|
||||
crate::prelude
|
||||
Iterator: t
|
||||
Iterator: ti
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -109,7 +109,7 @@ fn module_resolution_works_for_non_standard_filenames() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Bar: ti vi
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
@@ -139,7 +139,7 @@ fn module_resolution_works_for_raw_modules() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Bar: ti vi
|
||||
r#async: t
|
||||
|
||||
crate::r#async
|
||||
@@ -176,8 +176,8 @@ mod r#async {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Foo: t v
|
||||
Bar: ti vi
|
||||
Foo: ti vi
|
||||
r#async: t
|
||||
|
||||
crate::r#async
|
||||
@@ -207,7 +207,7 @@ fn module_resolution_decl_path() {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Bar: t v
|
||||
Bar: ti vi
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
@@ -236,7 +236,7 @@ fn module_resolution_module_with_path_in_mod_rs() {
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
bar: t
|
||||
|
||||
crate::foo::bar
|
||||
@@ -265,7 +265,7 @@ fn module_resolution_module_with_path_non_crate_root() {
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
bar: t
|
||||
|
||||
crate::foo::bar
|
||||
@@ -292,7 +292,7 @@ fn module_resolution_module_decl_path_super() {
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -626,7 +626,7 @@ mod foo {
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
@@ -660,7 +660,7 @@ mod bar {
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
bar: t
|
||||
|
||||
crate::foo::bar
|
||||
@@ -694,7 +694,7 @@ mod bar {
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
bar: t
|
||||
|
||||
crate::foo::bar
|
||||
@@ -728,7 +728,7 @@ mod bar {
|
||||
foo: t
|
||||
|
||||
crate::foo
|
||||
Baz: t v
|
||||
Baz: ti vi
|
||||
bar: t
|
||||
|
||||
crate::foo::bar
|
||||
@@ -868,7 +868,7 @@ pub mod hash { pub trait Hash {} }
|
||||
"#,
|
||||
expect![[r#"
|
||||
crate
|
||||
Hash: t
|
||||
Hash: ti
|
||||
core: t
|
||||
|
||||
crate::core
|
||||
|
||||
@@ -14,10 +14,10 @@ fn primitive_reexport() {
|
||||
expect![[r#"
|
||||
crate
|
||||
foo: t
|
||||
int: t
|
||||
int: ti
|
||||
|
||||
crate::foo
|
||||
int: t
|
||||
int: ti
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,13 +3,17 @@
|
||||
//!
|
||||
//! `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)]
|
||||
pub struct PerNs {
|
||||
pub types: Option<(ModuleDefId, Visibility)>,
|
||||
pub values: Option<(ModuleDefId, Visibility)>,
|
||||
pub macros: Option<(MacroId, Visibility)>,
|
||||
pub types: Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
|
||||
pub values: Option<(ModuleDefId, Visibility, Option<ImportId>)>,
|
||||
pub macros: Option<(MacroId, Visibility, Option<ImportId>)>,
|
||||
}
|
||||
|
||||
impl Default for PerNs {
|
||||
@@ -23,20 +27,29 @@ pub fn none() -> PerNs {
|
||||
PerNs { types: None, values: None, macros: None }
|
||||
}
|
||||
|
||||
pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
|
||||
PerNs { types: None, values: Some((t, v)), macros: None }
|
||||
pub fn values(t: ModuleDefId, v: Visibility, i: Option<ImportId>) -> PerNs {
|
||||
PerNs { types: None, values: Some((t, v, i)), macros: None }
|
||||
}
|
||||
|
||||
pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
|
||||
PerNs { types: Some((t, v)), values: None, macros: None }
|
||||
pub fn types(t: ModuleDefId, v: Visibility, i: Option<ImportOrExternCrate>) -> PerNs {
|
||||
PerNs { types: Some((t, v, i)), values: None, macros: None }
|
||||
}
|
||||
|
||||
pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
|
||||
PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
|
||||
pub fn both(
|
||||
types: ModuleDefId,
|
||||
values: ModuleDefId,
|
||||
v: Visibility,
|
||||
i: Option<ImportOrExternCrate>,
|
||||
) -> PerNs {
|
||||
PerNs {
|
||||
types: Some((types, v, i)),
|
||||
values: Some((values, v, i.and_then(ImportOrExternCrate::into_import))),
|
||||
macros: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn macros(macro_: MacroId, v: Visibility) -> PerNs {
|
||||
PerNs { types: None, values: None, macros: Some((macro_, v)) }
|
||||
pub fn macros(macro_: MacroId, v: Visibility, i: Option<ImportId>) -> PerNs {
|
||||
PerNs { types: None, values: None, macros: Some((macro_, v, i)) }
|
||||
}
|
||||
|
||||
pub fn is_none(&self) -> bool {
|
||||
@@ -51,7 +64,7 @@ pub fn take_types(self) -> Option<ModuleDefId> {
|
||||
self.types.map(|it| it.0)
|
||||
}
|
||||
|
||||
pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> {
|
||||
pub fn take_types_full(self) -> Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)> {
|
||||
self.types
|
||||
}
|
||||
|
||||
@@ -59,24 +72,32 @@ pub fn take_values(self) -> Option<ModuleDefId> {
|
||||
self.values.map(|it| it.0)
|
||||
}
|
||||
|
||||
pub fn take_values_import(self) -> Option<(ModuleDefId, Option<ImportId>)> {
|
||||
self.values.map(|it| (it.0, it.2))
|
||||
}
|
||||
|
||||
pub fn take_macros(self) -> Option<MacroId> {
|
||||
self.macros.map(|it| it.0)
|
||||
}
|
||||
|
||||
pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportId>)> {
|
||||
self.macros.map(|it| (it.0, it.2))
|
||||
}
|
||||
|
||||
pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
|
||||
let _p = profile::span("PerNs::filter_visibility");
|
||||
PerNs {
|
||||
types: self.types.filter(|(_, v)| f(*v)),
|
||||
values: self.values.filter(|(_, v)| f(*v)),
|
||||
macros: self.macros.filter(|(_, v)| f(*v)),
|
||||
types: self.types.filter(|&(_, v, _)| f(v)),
|
||||
values: self.values.filter(|&(_, v, _)| f(v)),
|
||||
macros: self.macros.filter(|&(_, v, _)| f(v)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_visibility(self, vis: Visibility) -> PerNs {
|
||||
PerNs {
|
||||
types: self.types.map(|(it, _)| (it, vis)),
|
||||
values: self.values.map(|(it, _)| (it, vis)),
|
||||
macros: self.macros.map(|(it, _)| (it, vis)),
|
||||
types: self.types.map(|(it, _, c)| (it, vis, c)),
|
||||
values: self.values.map(|(it, _, c)| (it, vis, c)),
|
||||
macros: self.macros.map(|(it, _, import)| (it, vis, import)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
db::DefDatabase,
|
||||
generics::{GenericParams, TypeOrConstParamData},
|
||||
hir::{BindingId, ExprId, LabelId},
|
||||
item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
|
||||
item_scope::{BuiltinShadowMode, ImportId, ImportOrExternCrate, BUILTIN_SCOPE},
|
||||
lang_item::LangItemTarget,
|
||||
nameres::{DefMap, MacroSubNs},
|
||||
path::{ModPath, Path, PathKind},
|
||||
@@ -100,8 +100,8 @@ pub enum TypeNs {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum ResolveValueResult {
|
||||
ValueNs(ValueNs),
|
||||
Partial(TypeNs, usize),
|
||||
ValueNs(ValueNs, Option<ImportId>),
|
||||
Partial(TypeNs, usize, Option<ImportOrExternCrate>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
@@ -152,7 +152,7 @@ pub fn resolve_path_in_type_ns(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
path: &Path,
|
||||
) -> Option<(TypeNs, Option<usize>)> {
|
||||
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
|
||||
let path = match path {
|
||||
Path::Normal { mod_path, .. } => mod_path,
|
||||
Path::LangItem(l) => {
|
||||
@@ -169,6 +169,7 @@ pub fn resolve_path_in_type_ns(
|
||||
| LangItemTarget::Static(_) => return None,
|
||||
},
|
||||
None,
|
||||
None,
|
||||
))
|
||||
}
|
||||
};
|
||||
@@ -185,17 +186,17 @@ pub fn resolve_path_in_type_ns(
|
||||
Scope::ExprScope(_) => continue,
|
||||
Scope::GenericParams { params, def } => {
|
||||
if let Some(id) = params.find_type_by_name(first_name, *def) {
|
||||
return Some((TypeNs::GenericParam(id), remaining_idx()));
|
||||
return Some((TypeNs::GenericParam(id), remaining_idx(), None));
|
||||
}
|
||||
}
|
||||
&Scope::ImplDefScope(impl_) => {
|
||||
if first_name == &name![Self] {
|
||||
return Some((TypeNs::SelfType(impl_), remaining_idx()));
|
||||
return Some((TypeNs::SelfType(impl_), remaining_idx(), None));
|
||||
}
|
||||
}
|
||||
&Scope::AdtScope(adt) => {
|
||||
if first_name == &name![Self] {
|
||||
return Some((TypeNs::AdtSelfType(adt), remaining_idx()));
|
||||
return Some((TypeNs::AdtSelfType(adt), remaining_idx(), None));
|
||||
}
|
||||
}
|
||||
Scope::BlockScope(m) => {
|
||||
@@ -208,12 +209,24 @@ pub fn resolve_path_in_type_ns(
|
||||
self.module_scope.resolve_path_in_type_ns(db, path)
|
||||
}
|
||||
|
||||
pub fn resolve_path_in_type_ns_fully_with_imports(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
path: &Path,
|
||||
) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
|
||||
let (res, unresolved, imp) = self.resolve_path_in_type_ns(db, path)?;
|
||||
if unresolved.is_some() {
|
||||
return None;
|
||||
}
|
||||
Some((res, imp))
|
||||
}
|
||||
|
||||
pub fn resolve_path_in_type_ns_fully(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
path: &Path,
|
||||
) -> Option<TypeNs> {
|
||||
let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
|
||||
let (res, unresolved, _) = self.resolve_path_in_type_ns(db, path)?;
|
||||
if unresolved.is_some() {
|
||||
return None;
|
||||
}
|
||||
@@ -235,7 +248,6 @@ pub fn resolve_visibility(
|
||||
RawVisibility::Public => Some(Visibility::Public),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_path_in_value_ns(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
@@ -244,17 +256,20 @@ pub fn resolve_path_in_value_ns(
|
||||
let path = match path {
|
||||
Path::Normal { mod_path, .. } => mod_path,
|
||||
Path::LangItem(l) => {
|
||||
return Some(ResolveValueResult::ValueNs(match *l {
|
||||
LangItemTarget::Function(it) => ValueNs::FunctionId(it),
|
||||
LangItemTarget::Static(it) => ValueNs::StaticId(it),
|
||||
LangItemTarget::Struct(it) => ValueNs::StructId(it),
|
||||
LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
|
||||
LangItemTarget::Union(_)
|
||||
| LangItemTarget::ImplDef(_)
|
||||
| LangItemTarget::TypeAlias(_)
|
||||
| LangItemTarget::Trait(_)
|
||||
| LangItemTarget::EnumId(_) => return None,
|
||||
}))
|
||||
return Some(ResolveValueResult::ValueNs(
|
||||
match *l {
|
||||
LangItemTarget::Function(it) => ValueNs::FunctionId(it),
|
||||
LangItemTarget::Static(it) => ValueNs::StaticId(it),
|
||||
LangItemTarget::Struct(it) => ValueNs::StructId(it),
|
||||
LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
|
||||
LangItemTarget::Union(_)
|
||||
| LangItemTarget::ImplDef(_)
|
||||
| LangItemTarget::TypeAlias(_)
|
||||
| LangItemTarget::Trait(_)
|
||||
| LangItemTarget::EnumId(_) => return None,
|
||||
},
|
||||
None,
|
||||
))
|
||||
}
|
||||
};
|
||||
let n_segments = path.segments().len();
|
||||
@@ -276,20 +291,24 @@ pub fn resolve_path_in_value_ns(
|
||||
.find(|entry| entry.name() == first_name);
|
||||
|
||||
if let Some(e) = entry {
|
||||
return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(
|
||||
e.binding(),
|
||||
)));
|
||||
return Some(ResolveValueResult::ValueNs(
|
||||
ValueNs::LocalBinding(e.binding()),
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
Scope::GenericParams { params, def } => {
|
||||
if let Some(id) = params.find_const_by_name(first_name, *def) {
|
||||
let val = ValueNs::GenericParam(id);
|
||||
return Some(ResolveValueResult::ValueNs(val));
|
||||
return Some(ResolveValueResult::ValueNs(val, None));
|
||||
}
|
||||
}
|
||||
&Scope::ImplDefScope(impl_) => {
|
||||
if first_name == &name![Self] {
|
||||
return Some(ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_)));
|
||||
return Some(ResolveValueResult::ValueNs(
|
||||
ValueNs::ImplSelf(impl_),
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
// bare `Self` doesn't work in the value namespace in a struct/enum definition
|
||||
@@ -308,18 +327,22 @@ pub fn resolve_path_in_value_ns(
|
||||
Scope::GenericParams { params, def } => {
|
||||
if let Some(id) = params.find_type_by_name(first_name, *def) {
|
||||
let ty = TypeNs::GenericParam(id);
|
||||
return Some(ResolveValueResult::Partial(ty, 1));
|
||||
return Some(ResolveValueResult::Partial(ty, 1, None));
|
||||
}
|
||||
}
|
||||
&Scope::ImplDefScope(impl_) => {
|
||||
if first_name == &name![Self] {
|
||||
return Some(ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1));
|
||||
return Some(ResolveValueResult::Partial(
|
||||
TypeNs::SelfType(impl_),
|
||||
1,
|
||||
None,
|
||||
));
|
||||
}
|
||||
}
|
||||
Scope::AdtScope(adt) => {
|
||||
if first_name == &name![Self] {
|
||||
let ty = TypeNs::AdtSelfType(*adt);
|
||||
return Some(ResolveValueResult::Partial(ty, 1));
|
||||
return Some(ResolveValueResult::Partial(ty, 1, None));
|
||||
}
|
||||
}
|
||||
Scope::BlockScope(m) => {
|
||||
@@ -340,7 +363,7 @@ pub fn resolve_path_in_value_ns(
|
||||
// `use core::u16;`.
|
||||
if path.kind == PathKind::Plain && n_segments > 1 {
|
||||
if let Some(builtin) = BuiltinType::by_name(first_name) {
|
||||
return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1));
|
||||
return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +376,7 @@ pub fn resolve_path_in_value_ns_fully(
|
||||
path: &Path,
|
||||
) -> Option<ValueNs> {
|
||||
match self.resolve_path_in_value_ns(db, path)? {
|
||||
ResolveValueResult::ValueNs(it) => Some(it),
|
||||
ResolveValueResult::ValueNs(it, _) => Some(it),
|
||||
ResolveValueResult::Partial(..) => None,
|
||||
}
|
||||
}
|
||||
@@ -363,12 +386,12 @@ pub fn resolve_path_as_macro(
|
||||
db: &dyn DefDatabase,
|
||||
path: &ModPath,
|
||||
expected_macro_kind: Option<MacroSubNs>,
|
||||
) -> Option<MacroId> {
|
||||
) -> Option<(MacroId, Option<ImportId>)> {
|
||||
let (item_map, module) = self.item_scope();
|
||||
item_map
|
||||
.resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind)
|
||||
.0
|
||||
.take_macros()
|
||||
.take_macros_import()
|
||||
}
|
||||
|
||||
/// Returns a set of names available in the current scope.
|
||||
@@ -776,11 +799,12 @@ fn resolve_path_in_value_ns(
|
||||
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
|
||||
match idx {
|
||||
None => {
|
||||
let value = to_value_ns(module_def)?;
|
||||
Some(ResolveValueResult::ValueNs(value))
|
||||
let (value, import) = to_value_ns(module_def)?;
|
||||
Some(ResolveValueResult::ValueNs(value, import))
|
||||
}
|
||||
Some(idx) => {
|
||||
let ty = match module_def.take_types()? {
|
||||
let (def, _, import) = module_def.take_types_full()?;
|
||||
let ty = match def {
|
||||
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
|
||||
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
|
||||
ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
|
||||
@@ -794,7 +818,7 @@ fn resolve_path_in_value_ns(
|
||||
| ModuleDefId::MacroId(_)
|
||||
| ModuleDefId::StaticId(_) => return None,
|
||||
};
|
||||
Some(ResolveValueResult::Partial(ty, idx))
|
||||
Some(ResolveValueResult::Partial(ty, idx, import))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -803,16 +827,17 @@ fn resolve_path_in_type_ns(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
path: &ModPath,
|
||||
) -> Option<(TypeNs, Option<usize>)> {
|
||||
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
|
||||
let (module_def, idx) =
|
||||
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
|
||||
let res = to_type_ns(module_def)?;
|
||||
Some((res, idx))
|
||||
let (res, import) = to_type_ns(module_def)?;
|
||||
Some((res, idx, import))
|
||||
}
|
||||
}
|
||||
|
||||
fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
|
||||
let res = match per_ns.take_values()? {
|
||||
fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportId>)> {
|
||||
let (def, import) = per_ns.take_values_import()?;
|
||||
let res = match def {
|
||||
ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
|
||||
ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
|
||||
ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
|
||||
@@ -827,11 +852,12 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
|
||||
| ModuleDefId::MacroId(_)
|
||||
| ModuleDefId::ModuleId(_) => return None,
|
||||
};
|
||||
Some(res)
|
||||
Some((res, import))
|
||||
}
|
||||
|
||||
fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
|
||||
let res = match per_ns.take_types()? {
|
||||
fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
|
||||
let (def, _, import) = per_ns.take_types_full()?;
|
||||
let res = match def {
|
||||
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
|
||||
ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
|
||||
|
||||
@@ -847,7 +873,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
|
||||
| ModuleDefId::StaticId(_)
|
||||
| ModuleDefId::ModuleId(_) => return None,
|
||||
};
|
||||
Some(res)
|
||||
Some((res, import))
|
||||
}
|
||||
|
||||
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<rustc_hash::FxHasher>>;
|
||||
@@ -864,13 +890,13 @@ fn add(&mut self, name: &Name, def: ScopeDef) {
|
||||
}
|
||||
}
|
||||
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))
|
||||
}
|
||||
if let &Some((def, _)) = &def.values {
|
||||
if let &Some((def, _, _)) = &def.values {
|
||||
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)))
|
||||
}
|
||||
if def.is_none() {
|
||||
|
||||
@@ -75,7 +75,7 @@ fn walk_unsafe(
|
||||
Expr::Path(path) => {
|
||||
let resolver = resolver_for_expr(db.upcast(), def, current);
|
||||
let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path);
|
||||
if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial {
|
||||
if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
|
||||
if db.static_data(id).mutable {
|
||||
unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
|
||||
}
|
||||
|
||||
@@ -1017,7 +1017,7 @@ fn resolve_variant(&mut self, path: Option<&Path>, value_ns: bool) -> (Ty, Optio
|
||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||
let (resolution, unresolved) = if value_ns {
|
||||
match self.resolver.resolve_path_in_value_ns(self.db.upcast(), path) {
|
||||
Some(ResolveValueResult::ValueNs(value)) => match value {
|
||||
Some(ResolveValueResult::ValueNs(value, _)) => match value {
|
||||
ValueNs::EnumVariantId(var) => {
|
||||
let substs = ctx.substs_from_path(path, var.into(), true);
|
||||
let ty = self.db.ty(var.parent.into());
|
||||
@@ -1033,12 +1033,14 @@ fn resolve_variant(&mut self, path: Option<&Path>, value_ns: bool) -> (Ty, Optio
|
||||
ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
|
||||
_ => return (self.err_ty(), None),
|
||||
},
|
||||
Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
|
||||
Some(ResolveValueResult::Partial(typens, unresolved, _)) => {
|
||||
(typens, Some(unresolved))
|
||||
}
|
||||
None => return (self.err_ty(), None),
|
||||
}
|
||||
} else {
|
||||
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
|
||||
Some(it) => it,
|
||||
Some((it, idx, _)) => (it, idx),
|
||||
None => return (self.err_ty(), None),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -322,7 +322,7 @@ fn place_of_expr_without_adjust(&mut self, tgt_expr: ExprId) -> Option<HirPlace>
|
||||
Expr::Path(p) => {
|
||||
let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
|
||||
if let Some(r) = resolver.resolve_path_in_value_ns(self.db.upcast(), p) {
|
||||
if let ResolveValueResult::ValueNs(v) = r {
|
||||
if let ResolveValueResult::ValueNs(v, _) = r {
|
||||
if let ValueNs::LocalBinding(b) = v {
|
||||
return Some(HirPlace { local: b, projections: vec![] });
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ fn resolve_value_path(&mut self, path: &Path, id: ExprOrPatId) -> Option<ValuePa
|
||||
self.resolver.resolve_path_in_value_ns(self.db.upcast(), path)?;
|
||||
|
||||
match value_or_partial {
|
||||
ResolveValueResult::ValueNs(it) => (it, None),
|
||||
ResolveValueResult::Partial(def, remaining_index) => self
|
||||
ResolveValueResult::ValueNs(it, _) => (it, None),
|
||||
ResolveValueResult::Partial(def, remaining_index, _) => self
|
||||
.resolve_assoc_item(def, path, remaining_index, id)
|
||||
.map(|(it, substs)| (it, Some(substs)))?,
|
||||
}
|
||||
|
||||
@@ -393,11 +393,9 @@ pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
|
||||
let ty = {
|
||||
let macro_call = macro_call.to_node(self.db.upcast());
|
||||
let resolver = |path| {
|
||||
self.resolver.resolve_path_as_macro(
|
||||
self.db.upcast(),
|
||||
&path,
|
||||
Some(MacroSubNs::Bang),
|
||||
)
|
||||
self.resolver
|
||||
.resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
|
||||
.map(|(it, _)| it)
|
||||
};
|
||||
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call, resolver)
|
||||
{
|
||||
@@ -449,7 +447,7 @@ fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId>
|
||||
return None;
|
||||
}
|
||||
let resolution = match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
|
||||
Some((it, None)) => it,
|
||||
Some((it, None, _)) => it,
|
||||
_ => return None,
|
||||
};
|
||||
match resolution {
|
||||
@@ -629,7 +627,7 @@ pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
|
||||
return self.lower_ty_relative_path(ty, res, path.segments());
|
||||
}
|
||||
|
||||
let (resolution, remaining_index) =
|
||||
let (resolution, remaining_index, _) =
|
||||
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
|
||||
Some(it) => it,
|
||||
None => return (TyKind::Error.intern(Interner), None),
|
||||
|
||||
@@ -1352,14 +1352,14 @@ fn lower_literal_or_const_to_operand(
|
||||
.resolve_path_in_value_ns(self.db.upcast(), c)
|
||||
.ok_or_else(unresolved_name)?;
|
||||
match pr {
|
||||
ResolveValueResult::ValueNs(v) => {
|
||||
ResolveValueResult::ValueNs(v, _) => {
|
||||
if let ValueNs::ConstId(c) = v {
|
||||
self.lower_const_to_operand(Substitution::empty(Interner), c.into(), ty)
|
||||
} else {
|
||||
not_supported!("bad path in range pattern");
|
||||
}
|
||||
}
|
||||
ResolveValueResult::Partial(_, _) => {
|
||||
ResolveValueResult::Partial(_, _, _) => {
|
||||
not_supported!("associated constants in range pattern")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ fn pattern_match_inner(
|
||||
break 'b (c, x.1);
|
||||
}
|
||||
}
|
||||
if let ResolveValueResult::ValueNs(v) = pr {
|
||||
if let ResolveValueResult::ValueNs(v, _) = pr {
|
||||
if let ValueNs::ConstId(c) = v {
|
||||
break 'b (c, Substitution::empty(Interner));
|
||||
}
|
||||
|
||||
@@ -623,7 +623,7 @@ fn speculative_expand(
|
||||
let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
|
||||
resolver
|
||||
.resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
|
||||
.map(|it| macro_id_to_def_id(self.db.upcast(), it))
|
||||
.map(|(it, _)| macro_id_to_def_id(self.db.upcast(), it))
|
||||
})?;
|
||||
hir_expand::db::expand_speculative(
|
||||
self.db.upcast(),
|
||||
|
||||
@@ -487,7 +487,7 @@ pub(crate) fn resolve_macro_call(
|
||||
let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
|
||||
self.resolver
|
||||
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Bang))
|
||||
.map(|it| it.into())
|
||||
.map(|(it, _)| it.into())
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_bind_pat_to_const(
|
||||
@@ -760,7 +760,7 @@ pub(crate) fn expand(
|
||||
let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
|
||||
self.resolver
|
||||
.resolve_path_as_macro(db.upcast(), &path, Some(MacroSubNs::Bang))
|
||||
.map(|it| macro_id_to_def_id(db.upcast(), it))
|
||||
.map(|(it, _)| macro_id_to_def_id(db.upcast(), it))
|
||||
})?;
|
||||
Some(macro_call_id.as_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
|
||||
}
|
||||
@@ -966,6 +966,7 @@ pub(crate) fn resolve_hir_path_as_attr_macro(
|
||||
) -> Option<Macro> {
|
||||
resolver
|
||||
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Attr))
|
||||
.map(|(it, _)| it)
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
@@ -983,7 +984,7 @@ fn resolve_hir_path_(
|
||||
res.map(|ty_ns| (ty_ns, path.segments().first()))
|
||||
}
|
||||
None => {
|
||||
let (ty, remaining_idx) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
|
||||
let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
|
||||
match remaining_idx {
|
||||
Some(remaining_idx) => {
|
||||
if remaining_idx + 1 == path.segments().len() {
|
||||
@@ -1067,7 +1068,7 @@ fn resolve_hir_path_(
|
||||
let macros = || {
|
||||
resolver
|
||||
.resolve_path_as_macro(db.upcast(), path.mod_path()?, None)
|
||||
.map(|def| PathResolution::Def(ModuleDef::Macro(def.into())))
|
||||
.map(|(def, _)| PathResolution::Def(ModuleDef::Macro(def.into())))
|
||||
};
|
||||
|
||||
if prefer_value_ns { values().or_else(types) } else { types().or_else(values) }
|
||||
|
||||
@@ -94,18 +94,21 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
|
||||
impl Upcast<dyn ExpandDatabase> for RootDatabase {
|
||||
#[inline]
|
||||
fn upcast(&self) -> &(dyn ExpandDatabase + 'static) {
|
||||
&*self
|
||||
}
|
||||
}
|
||||
|
||||
impl Upcast<dyn DefDatabase> for RootDatabase {
|
||||
#[inline]
|
||||
fn upcast(&self) -> &(dyn DefDatabase + 'static) {
|
||||
&*self
|
||||
}
|
||||
}
|
||||
|
||||
impl Upcast<dyn HirDatabase> for RootDatabase {
|
||||
#[inline]
|
||||
fn upcast(&self) -> &(dyn HirDatabase + 'static) {
|
||||
&*self
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user