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:
commit
49716e681a
27 changed files with 732 additions and 389 deletions
|
@ -38,9 +38,9 @@ fn outer() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
block scope
|
block scope
|
||||||
CrateStruct: t
|
CrateStruct: ti
|
||||||
PlainStruct: t v
|
PlainStruct: ti vi
|
||||||
SelfStruct: t
|
SelfStruct: ti
|
||||||
Struct: v
|
Struct: v
|
||||||
SuperStruct: _
|
SuperStruct: _
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ fn outer() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
block scope
|
block scope
|
||||||
imported: t v
|
imported: ti vi
|
||||||
name: v
|
name: v
|
||||||
|
|
||||||
crate
|
crate
|
||||||
|
@ -92,9 +92,9 @@ fn outer() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
block scope
|
block scope
|
||||||
inner1: t
|
inner1: ti
|
||||||
inner2: v
|
inner2: v
|
||||||
outer: v
|
outer: vi
|
||||||
|
|
||||||
block scope
|
block scope
|
||||||
inner: v
|
inner: v
|
||||||
|
@ -121,7 +121,7 @@ struct Struct {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
block scope
|
block scope
|
||||||
Struct: t
|
Struct: ti
|
||||||
|
|
||||||
crate
|
crate
|
||||||
Struct: t
|
Struct: t
|
||||||
|
@ -153,7 +153,7 @@ fn outer() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
block scope
|
block scope
|
||||||
ResolveMe: t
|
ResolveMe: ti
|
||||||
|
|
||||||
block scope
|
block scope
|
||||||
m2: t
|
m2: t
|
||||||
|
@ -214,7 +214,7 @@ fn f() {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
block scope
|
block scope
|
||||||
ResolveMe: t
|
ResolveMe: ti
|
||||||
|
|
||||||
block scope
|
block scope
|
||||||
h: v
|
h: v
|
||||||
|
@ -292,7 +292,7 @@ pub mod cov_mark {
|
||||||
nested: v
|
nested: v
|
||||||
|
|
||||||
crate
|
crate
|
||||||
cov_mark: t
|
cov_mark: ti
|
||||||
f: v
|
f: v
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
|
@ -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};
|
||||||
|
@ -19,12 +20,6 @@ use crate::{
|
||||||
UseId,
|
UseId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub(crate) enum ImportType {
|
|
||||||
Glob,
|
|
||||||
Named,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct PerNsGlobImports {
|
pub struct PerNsGlobImports {
|
||||||
types: FxHashSet<(LocalModuleId, Name)>,
|
types: FxHashSet<(LocalModuleId, Name)>,
|
||||||
|
@ -32,15 +27,49 @@ pub struct PerNsGlobImports {
|
||||||
macros: FxHashSet<(LocalModuleId, Name)>,
|
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)]
|
#[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 +79,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<ImportOrExternCrate, ImportOrDef>,
|
||||||
|
use_imports_values: FxHashMap<ImportId, ImportOrDef>,
|
||||||
|
use_imports_macros: FxHashMap<ImportId, 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
|
||||||
///
|
///
|
||||||
|
@ -82,7 +118,7 @@ struct DeriveMacroInvocation {
|
||||||
pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
|
pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
|
||||||
BuiltinType::ALL
|
BuiltinType::ALL
|
||||||
.iter()
|
.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()
|
.collect()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -121,8 +157,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 +167,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 +200,55 @@ 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
|
||||||
ItemInNs::Types(def) => (def, self.types.iter()),
|
.types
|
||||||
ItemInNs::Values(def) => (def, self.values.iter()),
|
.iter()
|
||||||
};
|
.find_map(|(name, &(other_def, vis, _))| (other_def == def).then_some((name, vis))),
|
||||||
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> + '_ {
|
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, i))| {
|
||||||
|
(
|
||||||
|
None,
|
||||||
|
PerNs::types(
|
||||||
|
ModuleDefId::TraitId(*tr),
|
||||||
|
*vis,
|
||||||
|
i.map(ImportOrExternCrate::Import),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
@ -277,12 +334,14 @@ impl ItemScope {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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> {
|
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);
|
// FIXME: import
|
||||||
|
self.unnamed_trait_imports.insert(tr, (vis, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn push_res_with_import(
|
pub(crate) fn push_res_with_import(
|
||||||
|
@ -290,51 +349,187 @@ impl ItemScope {
|
||||||
glob_imports: &mut PerNsGlobImports,
|
glob_imports: &mut PerNsGlobImports,
|
||||||
lookup: (LocalModuleId, Name),
|
lookup: (LocalModuleId, Name),
|
||||||
def: PerNs,
|
def: PerNs,
|
||||||
def_import_type: ImportType,
|
import: Option<ImportType>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
|
|
||||||
macro_rules! check_changed {
|
// FIXME: Document and simplify this
|
||||||
(
|
|
||||||
$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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entry.insert(fld);
|
if let Some(mut fld) = def.types {
|
||||||
$changed = true;
|
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)
|
_ => _ = glob_imports.types.remove(&lookup),
|
||||||
if matches!($def_import_type, ImportType::Named) =>
|
}
|
||||||
{
|
let import = match import {
|
||||||
if $glob_imports.$field.remove(&$lookup) {
|
Some(ImportType::ExternCrate(extern_crate)) => {
|
||||||
cov_mark::hit!(import_shadowed);
|
Some(ImportOrExternCrate::ExternCrate(extern_crate))
|
||||||
entry.insert(fld);
|
}
|
||||||
$changed = true;
|
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);
|
if let Some(mut fld) = def.values {
|
||||||
check_changed!(changed, (self / def).values, glob_imports[lookup], def_import_type);
|
let existing = self.values.entry(lookup.1.clone());
|
||||||
check_changed!(changed, (self / def).macros, glob_imports[lookup], def_import_type);
|
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) {
|
if def.is_none() && self.unresolved.insert(lookup.1) {
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -343,27 +538,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,14 +568,25 @@ impl ItemScope {
|
||||||
name.map_or("_".to_string(), |name| name.display(db).to_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");
|
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");
|
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");
|
buf.push_str(" m");
|
||||||
|
if i.is_some() {
|
||||||
|
buf.push('i');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if def.is_none() {
|
if def.is_none() {
|
||||||
buf.push_str(" _");
|
buf.push_str(" _");
|
||||||
|
@ -415,10 +612,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,32 +632,44 @@ 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PerNs {
|
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 {
|
match def {
|
||||||
ModuleDefId::ModuleId(_) => PerNs::types(def, v),
|
ModuleDefId::ModuleId(_) => PerNs::types(def, v, import),
|
||||||
ModuleDefId::FunctionId(_) => PerNs::values(def, v),
|
ModuleDefId::FunctionId(_) => {
|
||||||
|
PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
|
||||||
|
}
|
||||||
ModuleDefId::AdtId(adt) => match adt {
|
ModuleDefId::AdtId(adt) => match adt {
|
||||||
AdtId::UnionId(_) => PerNs::types(def, v),
|
AdtId::UnionId(_) => PerNs::types(def, v, import),
|
||||||
AdtId::EnumId(_) => PerNs::types(def, v),
|
AdtId::EnumId(_) => PerNs::types(def, v, import),
|
||||||
AdtId::StructId(_) => {
|
AdtId::StructId(_) => {
|
||||||
if has_constructor {
|
if has_constructor {
|
||||||
PerNs::both(def, def, v)
|
PerNs::both(def, def, v, import)
|
||||||
} else {
|
} else {
|
||||||
PerNs::types(def, v)
|
PerNs::types(def, v, import)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v),
|
ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v, import),
|
||||||
ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),
|
ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => {
|
||||||
ModuleDefId::TraitId(_) => PerNs::types(def, v),
|
PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
|
||||||
ModuleDefId::TraitAliasId(_) => PerNs::types(def, v),
|
}
|
||||||
ModuleDefId::TypeAliasId(_) => PerNs::types(def, v),
|
ModuleDefId::TraitId(_) => PerNs::types(def, v, import),
|
||||||
ModuleDefId::BuiltinType(_) => PerNs::types(def, v),
|
ModuleDefId::TraitAliasId(_) => PerNs::types(def, v, import),
|
||||||
ModuleDefId::MacroId(mac) => PerNs::macros(mac, v),
|
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 @@ 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 {
|
||||||
|
|
|
@ -131,7 +131,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
|
||||||
.as_call_id_with_errors(&db, krate, |path| {
|
.as_call_id_with_errors(&db, krate, |path| {
|
||||||
resolver
|
resolver
|
||||||
.resolve_path_as_macro(&db, &path, Some(MacroSubNs::Bang))
|
.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();
|
.unwrap();
|
||||||
let macro_call_id = res.value.unwrap();
|
let macro_call_id = res.value.unwrap();
|
||||||
|
|
|
@ -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::{ImportId, 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,
|
||||||
|
@ -146,7 +146,7 @@ impl PartialResolvedImport {
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
enum ImportSource {
|
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 },
|
ExternCrate { id: ExternCrateId },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,6 @@ struct Import {
|
||||||
path: ModPath,
|
path: ModPath,
|
||||||
alias: Option<ImportAlias>,
|
alias: Option<ImportAlias>,
|
||||||
visibility: RawVisibility,
|
visibility: RawVisibility,
|
||||||
kind: ImportKind,
|
|
||||||
source: ImportSource,
|
source: ImportSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +173,7 @@ impl Import {
|
||||||
path,
|
path,
|
||||||
alias,
|
alias,
|
||||||
visibility: visibility.clone(),
|
visibility: visibility.clone(),
|
||||||
kind,
|
source: ImportSource::Use { use_tree: idx, id, is_prelude, kind },
|
||||||
source: ImportSource::Use { use_tree: idx, id, is_prelude },
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -191,7 +189,6 @@ impl Import {
|
||||||
path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
|
path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
|
||||||
alias: it.alias.clone(),
|
alias: it.alias.clone(),
|
||||||
visibility: visibility.clone(),
|
visibility: visibility.clone(),
|
||||||
kind: ImportKind::Plain,
|
|
||||||
source: ImportSource::ExternCrate { id },
|
source: ImportSource::ExternCrate { id },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +222,7 @@ struct DefCollector<'a> {
|
||||||
db: &'a dyn DefDatabase,
|
db: &'a dyn DefDatabase,
|
||||||
def_map: DefMap,
|
def_map: DefMap,
|
||||||
deps: FxHashMap<Name, Dependency>,
|
deps: FxHashMap<Name, Dependency>,
|
||||||
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
|
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, UseId)>>,
|
||||||
unresolved_imports: Vec<ImportDirective>,
|
unresolved_imports: Vec<ImportDirective>,
|
||||||
indeterminate_imports: Vec<ImportDirective>,
|
indeterminate_imports: Vec<ImportDirective>,
|
||||||
unresolved_macros: Vec<MacroDirective>,
|
unresolved_macros: Vec<MacroDirective>,
|
||||||
|
@ -546,8 +543,12 @@ 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));
|
// 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 => {
|
types => {
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
|
@ -647,9 +648,9 @@ impl DefCollector<'_> {
|
||||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||||
self.update(
|
self.update(
|
||||||
module_id,
|
module_id,
|
||||||
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
|
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
|
||||||
Visibility::Public,
|
Visibility::Public,
|
||||||
ImportType::Named,
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -683,9 +684,9 @@ impl DefCollector<'_> {
|
||||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||||
self.update(
|
self.update(
|
||||||
module_id,
|
module_id,
|
||||||
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
|
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
|
||||||
vis,
|
vis,
|
||||||
ImportType::Named,
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,9 +699,9 @@ impl DefCollector<'_> {
|
||||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||||
self.update(
|
self.update(
|
||||||
module_id,
|
module_id,
|
||||||
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
|
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
|
||||||
Visibility::Public,
|
Visibility::Public,
|
||||||
ImportType::Named,
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,23 +715,25 @@ 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);
|
||||||
// `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!`
|
// `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!`
|
||||||
// macros.
|
// macros.
|
||||||
let root_scope = &def_map[DefMap::ROOT].scope;
|
let root_scope = &def_map[DefMap::ROOT].scope;
|
||||||
if let Some(names) = names {
|
match names {
|
||||||
for name in names {
|
Some(names) => {
|
||||||
// FIXME: Report diagnostic on 404.
|
for name in names {
|
||||||
if let Some(def) = root_scope.get(&name).take_macros() {
|
// FIXME: Report diagnostic on 404.
|
||||||
self.def_map.macro_use_prelude.insert(name, (def, extern_crate));
|
if let Some(def) = root_scope.get(&name).take_macros() {
|
||||||
|
self.def_map.macro_use_prelude.insert(name, (def, extern_crate));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
None => {
|
||||||
for (name, def) in root_scope.macros() {
|
for (name, def) in root_scope.macros() {
|
||||||
self.def_map.macro_use_prelude.insert(name.clone(), (def, extern_crate));
|
self.def_map.macro_use_prelude.insert(name.clone(), (def, extern_crate));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,6 +783,7 @@ impl DefCollector<'_> {
|
||||||
Some(res) => PartialResolvedImport::Resolved(PerNs::types(
|
Some(res) => PartialResolvedImport::Resolved(PerNs::types(
|
||||||
res.into(),
|
res.into(),
|
||||||
Visibility::Public,
|
Visibility::Public,
|
||||||
|
None,
|
||||||
)),
|
)),
|
||||||
None => PartialResolvedImport::Unresolved,
|
None => PartialResolvedImport::Unresolved,
|
||||||
}
|
}
|
||||||
|
@ -837,8 +841,9 @@ impl DefCollector<'_> {
|
||||||
.resolve_visibility(self.db, module_id, &directive.import.visibility, false)
|
.resolve_visibility(self.db, module_id, &directive.import.visibility, false)
|
||||||
.unwrap_or(Visibility::Public);
|
.unwrap_or(Visibility::Public);
|
||||||
|
|
||||||
match import.kind {
|
match import.source {
|
||||||
ImportKind::Plain | ImportKind::TypeOnly => {
|
ImportSource::ExternCrate { .. }
|
||||||
|
| ImportSource::Use { kind: ImportKind::Plain | ImportKind::TypeOnly, .. } => {
|
||||||
let name = match &import.alias {
|
let name = match &import.alias {
|
||||||
Some(ImportAlias::Alias(name)) => Some(name),
|
Some(ImportAlias::Alias(name)) => Some(name),
|
||||||
Some(ImportAlias::Underscore) => None,
|
Some(ImportAlias::Underscore) => None,
|
||||||
|
@ -851,32 +856,36 @@ impl DefCollector<'_> {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if import.kind == ImportKind::TypeOnly {
|
let imp = match import.source {
|
||||||
def.values = None;
|
// extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
|
||||||
def.macros = None;
|
ImportSource::ExternCrate { id, .. } => {
|
||||||
}
|
if self.def_map.block.is_none() && module_id == DefMap::ROOT {
|
||||||
|
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) =
|
||||||
tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
|
(def.take_types(), name)
|
||||||
|
{
|
||||||
// extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
|
if let Ok(def) = def.try_into() {
|
||||||
if let ImportSource::ExternCrate { id, .. } = import.source {
|
Arc::get_mut(&mut self.def_map.data)
|
||||||
if self.def_map.block.is_none() && module_id == DefMap::ROOT {
|
.unwrap()
|
||||||
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) =
|
.extern_prelude
|
||||||
(def.take_types(), name)
|
.insert(name.clone(), (def, Some(id)));
|
||||||
{
|
}
|
||||||
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);
|
tracing::debug!("glob import: {:?}", import);
|
||||||
match def.take_types() {
|
match def.take_types() {
|
||||||
Some(ModuleDefId::ModuleId(m)) => {
|
Some(ModuleDefId::ModuleId(m)) => {
|
||||||
|
@ -901,7 +910,7 @@ impl DefCollector<'_> {
|
||||||
.filter(|(_, res)| !res.is_none())
|
.filter(|(_, res)| !res.is_none())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
self.update(module_id, &items, vis, ImportType::Glob);
|
self.update(module_id, &items, vis, Some(ImportType::Glob(id)));
|
||||||
} else {
|
} else {
|
||||||
// glob import from same crate => we do an initial
|
// glob import from same crate => we do an initial
|
||||||
// import, and then need to propagate any further
|
// import, and then need to propagate any further
|
||||||
|
@ -933,11 +942,11 @@ impl DefCollector<'_> {
|
||||||
.filter(|(_, res)| !res.is_none())
|
.filter(|(_, res)| !res.is_none())
|
||||||
.collect::<Vec<_>>();
|
.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
|
// record the glob import in case we add further items
|
||||||
let glob = self.glob_imports.entry(m.local_id).or_default();
|
let glob = self.glob_imports.entry(m.local_id).or_default();
|
||||||
if !glob.iter().any(|(mid, _)| *mid == module_id) {
|
if !glob.iter().any(|(mid, _, _)| *mid == module_id) {
|
||||||
glob.push((module_id, vis));
|
glob.push((module_id, vis, id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -959,11 +968,11 @@ impl DefCollector<'_> {
|
||||||
.map(|(local_id, variant_data)| {
|
.map(|(local_id, variant_data)| {
|
||||||
let name = variant_data.name.clone();
|
let name = variant_data.name.clone();
|
||||||
let variant = EnumVariantId { parent: e, local_id };
|
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)
|
(Some(name), res)
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
self.update(module_id, &resolutions, vis, ImportType::Glob);
|
self.update(module_id, &resolutions, vis, Some(ImportType::Glob(id)));
|
||||||
}
|
}
|
||||||
Some(d) => {
|
Some(d) => {
|
||||||
tracing::debug!("glob import {:?} from non-module/enum {:?}", import, d);
|
tracing::debug!("glob import {:?} from non-module/enum {:?}", import, d);
|
||||||
|
@ -983,10 +992,10 @@ impl DefCollector<'_> {
|
||||||
resolutions: &[(Option<Name>, PerNs)],
|
resolutions: &[(Option<Name>, PerNs)],
|
||||||
// Visibility this import will have
|
// Visibility this import will have
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
import_type: ImportType,
|
import: Option<ImportType>,
|
||||||
) {
|
) {
|
||||||
self.db.unwind_if_cancelled();
|
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(
|
fn update_recursive(
|
||||||
|
@ -997,7 +1006,7 @@ impl DefCollector<'_> {
|
||||||
// All resolutions are imported with this visibility; the visibilities in
|
// All resolutions are imported with this visibility; the visibilities in
|
||||||
// the `PerNs` values are ignored and overwritten
|
// the `PerNs` values are ignored and overwritten
|
||||||
vis: Visibility,
|
vis: Visibility,
|
||||||
import_type: ImportType,
|
import: Option<ImportType>,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
) {
|
) {
|
||||||
if GLOB_RECURSION_LIMIT.check(depth).is_err() {
|
if GLOB_RECURSION_LIMIT.check(depth).is_err() {
|
||||||
|
@ -1014,7 +1023,7 @@ impl DefCollector<'_> {
|
||||||
&mut self.from_glob_import,
|
&mut self.from_glob_import,
|
||||||
(module_id, name.clone()),
|
(module_id, name.clone()),
|
||||||
res.with_visibility(vis),
|
res.with_visibility(vis),
|
||||||
import_type,
|
import,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -1059,7 +1068,7 @@ impl DefCollector<'_> {
|
||||||
.get(&module_id)
|
.get(&module_id)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.filter(|(glob_importing_module, _)| {
|
.filter(|(glob_importing_module, _, _)| {
|
||||||
// we know all resolutions have the same visibility (`vis`), so we
|
// we know all resolutions have the same visibility (`vis`), so we
|
||||||
// just need to check that once
|
// just need to check that once
|
||||||
vis.is_visible_from_def_map(self.db, &self.def_map, *glob_importing_module)
|
vis.is_visible_from_def_map(self.db, &self.def_map, *glob_importing_module)
|
||||||
|
@ -1067,12 +1076,12 @@ impl DefCollector<'_> {
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect::<Vec<_>>();
|
.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(
|
self.update_recursive(
|
||||||
glob_importing_module,
|
glob_importing_module,
|
||||||
resolutions,
|
resolutions,
|
||||||
glob_import_vis,
|
glob_import_vis,
|
||||||
ImportType::Glob,
|
Some(ImportType::Glob(use_)),
|
||||||
depth + 1,
|
depth + 1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1475,7 +1484,9 @@ impl DefCollector<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for directive in &self.unresolved_imports {
|
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!(
|
if matches!(
|
||||||
(directive.import.path.segments().first(), &directive.import.path.kind),
|
(directive.import.path.segments().first(), &directive.import.path.kind),
|
||||||
(Some(krate), PathKind::Plain | PathKind::Abs) if diagnosed_extern_crates.contains(krate)
|
(Some(krate), PathKind::Plain | PathKind::Abs) if diagnosed_extern_crates.contains(krate)
|
||||||
|
@ -1537,9 +1548,9 @@ impl ModCollector<'_, '_> {
|
||||||
def_collector.def_map.modules[module_id].scope.declare(id);
|
def_collector.def_map.modules[module_id].scope.declare(id);
|
||||||
def_collector.update(
|
def_collector.update(
|
||||||
module_id,
|
module_id,
|
||||||
&[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
|
&[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor, None))],
|
||||||
vis,
|
vis,
|
||||||
ImportType::Named,
|
None,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let resolve_vis = |def_map: &DefMap, visibility| {
|
let resolve_vis = |def_map: &DefMap, visibility| {
|
||||||
|
@ -1967,9 +1978,9 @@ impl ModCollector<'_, '_> {
|
||||||
def_map.modules[self.module_id].scope.declare(def);
|
def_map.modules[self.module_id].scope.declare(def);
|
||||||
self.def_collector.update(
|
self.def_collector.update(
|
||||||
self.module_id,
|
self.module_id,
|
||||||
&[(Some(name), PerNs::from_def(def, vis, false))],
|
&[(Some(name), PerNs::from_def(def, vis, false, None))],
|
||||||
vis,
|
vis,
|
||||||
ImportType::Named,
|
None,
|
||||||
);
|
);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,9 @@ use hir_expand::name::Name;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
data::adt::VariantData,
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
item_scope::BUILTIN_SCOPE,
|
item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
|
||||||
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
|
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
|
@ -65,7 +66,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)
|
||||||
});
|
});
|
||||||
|
@ -196,15 +197,15 @@ impl DefMap {
|
||||||
PathKind::DollarCrate(krate) => {
|
PathKind::DollarCrate(krate) => {
|
||||||
if krate == self.krate {
|
if krate == self.krate {
|
||||||
cov_mark::hit!(macro_dollar_crate_self);
|
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 {
|
} else {
|
||||||
let def_map = db.crate_def_map(krate);
|
let def_map = db.crate_def_map(krate);
|
||||||
let module = def_map.module_id(Self::ROOT);
|
let module = def_map.module_id(Self::ROOT);
|
||||||
cov_mark::hit!(macro_dollar_crate_other);
|
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
|
// plain import or absolute path in 2015: crate-relative with
|
||||||
// fallback to extern prelude (with the simplification in
|
// fallback to extern prelude (with the simplification in
|
||||||
// rust-lang/rust#57745)
|
// rust-lang/rust#57745)
|
||||||
|
@ -291,7 +292,7 @@ impl DefMap {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
PerNs::types(module.into(), Visibility::Public)
|
PerNs::types(module.into(), Visibility::Public, None)
|
||||||
}
|
}
|
||||||
PathKind::Abs => {
|
PathKind::Abs => {
|
||||||
// 2018-style absolute path -- only extern prelude
|
// 2018-style absolute path -- only extern prelude
|
||||||
|
@ -299,9 +300,13 @@ impl DefMap {
|
||||||
Some((_, segment)) => segment,
|
Some((_, segment)) => segment,
|
||||||
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
|
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);
|
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 {
|
} else {
|
||||||
return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
|
return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
|
||||||
}
|
}
|
||||||
|
@ -309,7 +314,7 @@ impl DefMap {
|
||||||
};
|
};
|
||||||
|
|
||||||
for (i, segment) in segments {
|
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,
|
Some(r) => r,
|
||||||
None => {
|
None => {
|
||||||
// we still have path segments left, but the path so far
|
// we still have path segments left, but the path so far
|
||||||
|
@ -364,18 +369,20 @@ impl DefMap {
|
||||||
Some(local_id) => {
|
Some(local_id) => {
|
||||||
let variant = EnumVariantId { parent: e, local_id };
|
let variant = EnumVariantId { parent: e, local_id };
|
||||||
match &*enum_data.variants[local_id].variant_data {
|
match &*enum_data.variants[local_id].variant_data {
|
||||||
crate::data::adt::VariantData::Record(_) => {
|
VariantData::Record(_) => {
|
||||||
PerNs::types(variant.into(), Visibility::Public)
|
PerNs::types(variant.into(), Visibility::Public, None)
|
||||||
}
|
|
||||||
crate::data::adt::VariantData::Tuple(_)
|
|
||||||
| crate::data::adt::VariantData::Unit => {
|
|
||||||
PerNs::both(variant.into(), variant.into(), Visibility::Public)
|
|
||||||
}
|
}
|
||||||
|
VariantData::Tuple(_) | VariantData::Unit => PerNs::both(
|
||||||
|
variant.into(),
|
||||||
|
variant.into(),
|
||||||
|
Visibility::Public,
|
||||||
|
None,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
return ResolvePathResult::with(
|
return ResolvePathResult::with(
|
||||||
PerNs::types(e.into(), vis),
|
PerNs::types(e.into(), vis, imp),
|
||||||
ReachedFixedPoint::Yes,
|
ReachedFixedPoint::Yes,
|
||||||
Some(i),
|
Some(i),
|
||||||
Some(self.krate),
|
Some(self.krate),
|
||||||
|
@ -393,7 +400,7 @@ impl DefMap {
|
||||||
);
|
);
|
||||||
|
|
||||||
return ResolvePathResult::with(
|
return ResolvePathResult::with(
|
||||||
PerNs::types(s, vis),
|
PerNs::types(s, vis, imp),
|
||||||
ReachedFixedPoint::Yes,
|
ReachedFixedPoint::Yes,
|
||||||
Some(i),
|
Some(i),
|
||||||
Some(self.krate),
|
Some(self.krate),
|
||||||
|
@ -430,7 +437,7 @@ impl DefMap {
|
||||||
.filter(|&id| {
|
.filter(|&id| {
|
||||||
sub_namespace_match(Some(MacroSubNs::from_id(db, id)), expected_macro_subns)
|
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_scope = self[module].scope.get(name).filter_macro(db, expected_macro_subns);
|
||||||
let from_builtin = match self.block {
|
let from_builtin = match self.block {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
|
@ -449,16 +456,26 @@ impl DefMap {
|
||||||
|
|
||||||
let extern_prelude = || {
|
let extern_prelude = || {
|
||||||
if self.block.is_some() {
|
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();
|
return PerNs::none();
|
||||||
}
|
}
|
||||||
self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
|
self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {
|
||||||
PerNs::types(it.into(), Visibility::Public)
|
PerNs::types(
|
||||||
|
it.into(),
|
||||||
|
Visibility::Public,
|
||||||
|
extern_crate.map(ImportOrExternCrate::ExternCrate),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let macro_use_prelude = || {
|
let macro_use_prelude = || {
|
||||||
self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
|
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);
|
let prelude = || self.resolve_in_prelude(db, name);
|
||||||
|
@ -487,13 +504,16 @@ impl DefMap {
|
||||||
// Don't resolve extern prelude in block `DefMap`s.
|
// Don't resolve extern prelude in block `DefMap`s.
|
||||||
return PerNs::none();
|
return PerNs::none();
|
||||||
}
|
}
|
||||||
self.data
|
self.data.extern_prelude.get(name).copied().map_or(
|
||||||
.extern_prelude
|
PerNs::none(),
|
||||||
.get(name)
|
|(it, extern_crate)| {
|
||||||
.copied()
|
PerNs::types(
|
||||||
.map_or(PerNs::none(), |(it, _extern_crate)| {
|
it.into(),
|
||||||
PerNs::types(it.into(), Visibility::Public)
|
Visibility::Public,
|
||||||
})
|
extern_crate.map(ImportOrExternCrate::ExternCrate),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
from_crate_root.or_else(from_extern_prelude)
|
from_crate_root.or_else(from_extern_prelude)
|
||||||
|
|
|
@ -168,7 +168,7 @@ pub struct Baz;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Foo: t v
|
Foo: ti vi
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
|
@ -194,8 +194,8 @@ pub enum Quux {};
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
Quux: t
|
Quux: ti
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
|
@ -225,11 +225,11 @@ pub struct Baz;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
bar: t
|
bar: t
|
||||||
|
|
||||||
crate::foo::bar
|
crate::foo::bar
|
||||||
|
@ -274,7 +274,7 @@ use self::E::V;
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
E: t
|
E: t
|
||||||
V: t v
|
V: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ pub struct FromLib;
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
Bar: _
|
Bar: _
|
||||||
FromLib: t v
|
FromLib: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -328,7 +328,7 @@ pub struct Baz;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Baz: t
|
Baz: ti
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
|
@ -352,7 +352,7 @@ pub struct Baz;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -375,13 +375,13 @@ pub struct Arc;
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
alloc: t
|
alloc: t
|
||||||
alloc_crate: t
|
alloc_crate: te
|
||||||
sync: t
|
sync: t
|
||||||
|
|
||||||
crate::alloc
|
crate::alloc
|
||||||
|
|
||||||
crate::sync
|
crate::sync
|
||||||
Arc: t v
|
Arc: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -404,13 +404,13 @@ pub struct Arc;
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
alloc: t
|
alloc: t
|
||||||
alloc_crate: t
|
alloc_crate: te
|
||||||
sync: t
|
sync: t
|
||||||
|
|
||||||
crate::alloc
|
crate::alloc
|
||||||
|
|
||||||
crate::sync
|
crate::sync
|
||||||
Arc: t v
|
Arc: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -426,7 +426,7 @@ extern crate self as bla;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
bla: t
|
bla: te
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -447,7 +447,7 @@ pub struct Baz;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -465,7 +465,7 @@ pub struct Bar;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
foo: v
|
foo: v
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
@ -492,9 +492,9 @@ fn no_std_prelude() {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Rust: t v
|
Rust: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,9 +516,9 @@ fn edition_specific_preludes() {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Rust2018: t v
|
Rust2018: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
check(
|
check(
|
||||||
r#"
|
r#"
|
||||||
|
@ -533,9 +533,9 @@ fn edition_specific_preludes() {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Rust2021: t v
|
Rust2021: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,8 +563,8 @@ pub mod prelude {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
Foo: t v
|
Foo: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -590,7 +590,7 @@ pub mod prelude {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
Baz: _
|
Baz: _
|
||||||
Foo: _
|
Foo: _
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -619,8 +619,8 @@ pub mod prelude {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: _
|
Bar: _
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
Foo: t v
|
Foo: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -643,7 +643,7 @@ mod b {
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
T: t v
|
T: ti vi
|
||||||
a: t
|
a: t
|
||||||
b: t
|
b: t
|
||||||
|
|
||||||
|
@ -816,8 +816,8 @@ fn bar() {}
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
bar: v
|
bar: v
|
||||||
baz: v
|
baz: vi
|
||||||
foo: t
|
foo: ti
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -836,7 +836,7 @@ use self::m::S::{self};
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
S: t
|
S: ti
|
||||||
m: t
|
m: t
|
||||||
|
|
||||||
crate::m
|
crate::m
|
||||||
|
@ -860,8 +860,8 @@ pub const settings: () = ();
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Settings: t v
|
Settings: ti vi
|
||||||
settings: v
|
settings: vi
|
||||||
"#]],
|
"#]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -890,8 +890,8 @@ pub struct Struct;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Struct: t v
|
Struct: ti vi
|
||||||
dep: t
|
dep: te
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -917,13 +917,13 @@ use some_module::unknown_func;
|
||||||
crate
|
crate
|
||||||
other_module: t
|
other_module: t
|
||||||
some_module: t
|
some_module: t
|
||||||
unknown_func: v
|
unknown_func: vi
|
||||||
|
|
||||||
crate::other_module
|
crate::other_module
|
||||||
some_submodule: t
|
some_submodule: t
|
||||||
|
|
||||||
crate::other_module::some_submodule
|
crate::other_module::some_submodule
|
||||||
unknown_func: v
|
unknown_func: vi
|
||||||
|
|
||||||
crate::some_module
|
crate::some_module
|
||||||
unknown_func: v
|
unknown_func: v
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub struct Baz;
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
Foo: t v
|
Foo: t v
|
||||||
bar: t
|
bar: t
|
||||||
|
|
||||||
|
@ -237,9 +237,9 @@ pub mod baz { pub struct Bar; }
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
bar: t
|
bar: t
|
||||||
baz: t
|
baz: ti
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::bar
|
crate::bar
|
||||||
|
@ -276,9 +276,9 @@ pub mod baz { pub struct Bar; }
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
bar: t
|
bar: t
|
||||||
baz: t
|
baz: ti
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::bar
|
crate::bar
|
||||||
|
@ -323,7 +323,7 @@ mod d {
|
||||||
X: t v
|
X: t v
|
||||||
|
|
||||||
crate::b
|
crate::b
|
||||||
foo: t
|
foo: ti
|
||||||
|
|
||||||
crate::c
|
crate::c
|
||||||
foo: t
|
foo: t
|
||||||
|
@ -332,8 +332,8 @@ mod d {
|
||||||
Y: t v
|
Y: t v
|
||||||
|
|
||||||
crate::d
|
crate::d
|
||||||
Y: t v
|
Y: ti vi
|
||||||
foo: t
|
foo: ti
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,7 @@ use event::Event;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Event: t
|
Event: ti
|
||||||
event: t
|
event: t
|
||||||
|
|
||||||
crate::event
|
crate::event
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -203,8 +203,8 @@ macro_rules! bar {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Foo: t
|
Foo: t
|
||||||
bar: m
|
bar: mi
|
||||||
foo: m
|
foo: mi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ mod priv_mod {
|
||||||
Bar: t v
|
Bar: t v
|
||||||
Foo: t v
|
Foo: t v
|
||||||
bar: t
|
bar: t
|
||||||
foo: t
|
foo: te
|
||||||
|
|
||||||
crate::bar
|
crate::bar
|
||||||
Baz: t v
|
Baz: t v
|
||||||
|
@ -318,9 +318,9 @@ macro_rules! baz3 { () => { struct OkBaz3; } }
|
||||||
OkBaz1: t v
|
OkBaz1: t v
|
||||||
OkBaz2: t v
|
OkBaz2: t v
|
||||||
OkBaz3: t v
|
OkBaz3: t v
|
||||||
all: t
|
all: te
|
||||||
empty: t
|
empty: te
|
||||||
multiple: t
|
multiple: te
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -551,8 +551,8 @@ fn baz() {}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
bar: t m
|
bar: ti mi
|
||||||
baz: t v m
|
baz: ti v mi
|
||||||
foo: t m
|
foo: t m
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
@ -583,7 +583,7 @@ mod m {
|
||||||
crate
|
crate
|
||||||
Alias: t v
|
Alias: t v
|
||||||
Direct: t v
|
Direct: t v
|
||||||
foo: t
|
foo: te
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -628,9 +628,9 @@ mod m {
|
||||||
m: t
|
m: t
|
||||||
|
|
||||||
crate::m
|
crate::m
|
||||||
alias1: m
|
alias1: mi
|
||||||
alias2: m
|
alias2: mi
|
||||||
alias3: m
|
alias3: mi
|
||||||
not_found: _
|
not_found: _
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
@ -682,11 +682,11 @@ pub struct Baz;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
Foo: t v
|
Foo: t v
|
||||||
FooSelf: t v
|
FooSelf: ti vi
|
||||||
foo: t
|
foo: te
|
||||||
m: t
|
m: t
|
||||||
|
|
||||||
crate::m
|
crate::m
|
||||||
|
@ -725,7 +725,7 @@ pub struct bar;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
bar: t v
|
bar: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1340,7 +1340,7 @@ pub mod prelude {
|
||||||
crate
|
crate
|
||||||
Ok: t v
|
Ok: t v
|
||||||
bar: m
|
bar: m
|
||||||
dep: t
|
dep: te
|
||||||
foo: m
|
foo: m
|
||||||
ok: v
|
ok: v
|
||||||
"#]],
|
"#]],
|
||||||
|
@ -1370,13 +1370,13 @@ macro_rules! mk_foo {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
a: t
|
a: t
|
||||||
lib: t
|
lib: te
|
||||||
|
|
||||||
crate::a
|
crate::a
|
||||||
Ok: t v
|
Ok: t v
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1427,8 +1427,8 @@ pub mod prelude {
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Ok: t v
|
Ok: t v
|
||||||
bar: m
|
bar: mi
|
||||||
foo: m
|
foo: mi
|
||||||
ok: v
|
ok: v
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
|
@ -80,18 +80,18 @@ pub trait Iterator;
|
||||||
prelude: t
|
prelude: t
|
||||||
|
|
||||||
crate::iter
|
crate::iter
|
||||||
Iterator: t
|
Iterator: ti
|
||||||
traits: t
|
traits: t
|
||||||
|
|
||||||
crate::iter::traits
|
crate::iter::traits
|
||||||
Iterator: t
|
Iterator: ti
|
||||||
iterator: t
|
iterator: t
|
||||||
|
|
||||||
crate::iter::traits::iterator
|
crate::iter::traits::iterator
|
||||||
Iterator: t
|
Iterator: t
|
||||||
|
|
||||||
crate::prelude
|
crate::prelude
|
||||||
Iterator: t
|
Iterator: ti
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ pub struct Bar;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
|
@ -139,7 +139,7 @@ pub struct Baz;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
r#async: t
|
r#async: t
|
||||||
|
|
||||||
crate::r#async
|
crate::r#async
|
||||||
|
@ -176,8 +176,8 @@ pub struct Bar;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
Foo: t v
|
Foo: ti vi
|
||||||
r#async: t
|
r#async: t
|
||||||
|
|
||||||
crate::r#async
|
crate::r#async
|
||||||
|
@ -207,7 +207,7 @@ pub struct Bar;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Bar: t v
|
Bar: ti vi
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
|
@ -236,7 +236,7 @@ pub struct Baz;
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
bar: t
|
bar: t
|
||||||
|
|
||||||
crate::foo::bar
|
crate::foo::bar
|
||||||
|
@ -265,7 +265,7 @@ pub struct Baz;
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
bar: t
|
bar: t
|
||||||
|
|
||||||
crate::foo::bar
|
crate::foo::bar
|
||||||
|
@ -292,7 +292,7 @@ use super::Baz;
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -626,7 +626,7 @@ pub struct Baz;
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
|
@ -660,7 +660,7 @@ pub struct Baz;
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
bar: t
|
bar: t
|
||||||
|
|
||||||
crate::foo::bar
|
crate::foo::bar
|
||||||
|
@ -694,7 +694,7 @@ pub struct Baz;
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
bar: t
|
bar: t
|
||||||
|
|
||||||
crate::foo::bar
|
crate::foo::bar
|
||||||
|
@ -728,7 +728,7 @@ pub struct Baz;
|
||||||
foo: t
|
foo: t
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
Baz: t v
|
Baz: ti vi
|
||||||
bar: t
|
bar: t
|
||||||
|
|
||||||
crate::foo::bar
|
crate::foo::bar
|
||||||
|
@ -868,7 +868,7 @@ pub mod hash { pub trait Hash {} }
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
Hash: t
|
Hash: ti
|
||||||
core: t
|
core: t
|
||||||
|
|
||||||
crate::core
|
crate::core
|
||||||
|
|
|
@ -14,10 +14,10 @@ pub use i32 as int;
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
crate
|
crate
|
||||||
foo: t
|
foo: t
|
||||||
int: t
|
int: ti
|
||||||
|
|
||||||
crate::foo
|
crate::foo
|
||||||
int: t
|
int: ti
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
@ -23,20 +27,29 @@ impl PerNs {
|
||||||
PerNs { types: None, values: None, macros: None }
|
PerNs { types: None, values: None, macros: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
|
pub fn values(t: ModuleDefId, v: Visibility, i: Option<ImportId>) -> PerNs {
|
||||||
PerNs { types: None, values: Some((t, v)), macros: None }
|
PerNs { types: None, values: Some((t, v, i)), macros: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
|
pub fn types(t: ModuleDefId, v: Visibility, i: Option<ImportOrExternCrate>) -> PerNs {
|
||||||
PerNs { types: Some((t, v)), values: None, macros: None }
|
PerNs { types: Some((t, v, i)), values: None, macros: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
|
pub fn both(
|
||||||
PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
|
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 {
|
pub fn macros(macro_: MacroId, v: Visibility, i: Option<ImportId>) -> PerNs {
|
||||||
PerNs { types: None, values: None, macros: Some((macro_, v)) }
|
PerNs { types: None, values: None, macros: Some((macro_, v, i)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_none(&self) -> bool {
|
pub fn is_none(&self) -> bool {
|
||||||
|
@ -51,7 +64,7 @@ impl PerNs {
|
||||||
self.types.map(|it| it.0)
|
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
|
self.types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,24 +72,32 @@ impl PerNs {
|
||||||
self.values.map(|it| it.0)
|
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> {
|
pub fn take_macros(self) -> Option<MacroId> {
|
||||||
self.macros.map(|it| it.0)
|
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 {
|
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)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
generics::{GenericParams, TypeOrConstParamData},
|
generics::{GenericParams, TypeOrConstParamData},
|
||||||
hir::{BindingId, ExprId, LabelId},
|
hir::{BindingId, ExprId, LabelId},
|
||||||
item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
|
item_scope::{BuiltinShadowMode, ImportId, ImportOrExternCrate, BUILTIN_SCOPE},
|
||||||
lang_item::LangItemTarget,
|
lang_item::LangItemTarget,
|
||||||
nameres::{DefMap, MacroSubNs},
|
nameres::{DefMap, MacroSubNs},
|
||||||
path::{ModPath, Path, PathKind},
|
path::{ModPath, Path, PathKind},
|
||||||
|
@ -100,8 +100,8 @@ pub enum TypeNs {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum ResolveValueResult {
|
pub enum ResolveValueResult {
|
||||||
ValueNs(ValueNs),
|
ValueNs(ValueNs, Option<ImportId>),
|
||||||
Partial(TypeNs, usize),
|
Partial(TypeNs, usize, Option<ImportOrExternCrate>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -152,7 +152,7 @@ impl Resolver {
|
||||||
&self,
|
&self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> Option<(TypeNs, Option<usize>)> {
|
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
|
||||||
let path = match path {
|
let path = match path {
|
||||||
Path::Normal { mod_path, .. } => mod_path,
|
Path::Normal { mod_path, .. } => mod_path,
|
||||||
Path::LangItem(l) => {
|
Path::LangItem(l) => {
|
||||||
|
@ -169,6 +169,7 @@ impl Resolver {
|
||||||
| LangItemTarget::Static(_) => return None,
|
| LangItemTarget::Static(_) => return None,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -185,17 +186,17 @@ impl Resolver {
|
||||||
Scope::ExprScope(_) => continue,
|
Scope::ExprScope(_) => continue,
|
||||||
Scope::GenericParams { params, def } => {
|
Scope::GenericParams { params, def } => {
|
||||||
if let Some(id) = params.find_type_by_name(first_name, *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_) => {
|
&Scope::ImplDefScope(impl_) => {
|
||||||
if first_name == &name![Self] {
|
if first_name == &name![Self] {
|
||||||
return Some((TypeNs::SelfType(impl_), remaining_idx()));
|
return Some((TypeNs::SelfType(impl_), remaining_idx(), None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Scope::AdtScope(adt) => {
|
&Scope::AdtScope(adt) => {
|
||||||
if first_name == &name![Self] {
|
if first_name == &name![Self] {
|
||||||
return Some((TypeNs::AdtSelfType(adt), remaining_idx()));
|
return Some((TypeNs::AdtSelfType(adt), remaining_idx(), None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Scope::BlockScope(m) => {
|
Scope::BlockScope(m) => {
|
||||||
|
@ -208,12 +209,24 @@ impl Resolver {
|
||||||
self.module_scope.resolve_path_in_type_ns(db, path)
|
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(
|
pub fn resolve_path_in_type_ns_fully(
|
||||||
&self,
|
&self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> Option<TypeNs> {
|
) -> 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() {
|
if unresolved.is_some() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +248,6 @@ impl Resolver {
|
||||||
RawVisibility::Public => Some(Visibility::Public),
|
RawVisibility::Public => Some(Visibility::Public),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_path_in_value_ns(
|
pub fn resolve_path_in_value_ns(
|
||||||
&self,
|
&self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
|
@ -244,17 +256,20 @@ impl Resolver {
|
||||||
let path = match path {
|
let path = match path {
|
||||||
Path::Normal { mod_path, .. } => mod_path,
|
Path::Normal { mod_path, .. } => mod_path,
|
||||||
Path::LangItem(l) => {
|
Path::LangItem(l) => {
|
||||||
return Some(ResolveValueResult::ValueNs(match *l {
|
return Some(ResolveValueResult::ValueNs(
|
||||||
LangItemTarget::Function(it) => ValueNs::FunctionId(it),
|
match *l {
|
||||||
LangItemTarget::Static(it) => ValueNs::StaticId(it),
|
LangItemTarget::Function(it) => ValueNs::FunctionId(it),
|
||||||
LangItemTarget::Struct(it) => ValueNs::StructId(it),
|
LangItemTarget::Static(it) => ValueNs::StaticId(it),
|
||||||
LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
|
LangItemTarget::Struct(it) => ValueNs::StructId(it),
|
||||||
LangItemTarget::Union(_)
|
LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
|
||||||
| LangItemTarget::ImplDef(_)
|
LangItemTarget::Union(_)
|
||||||
| LangItemTarget::TypeAlias(_)
|
| LangItemTarget::ImplDef(_)
|
||||||
| LangItemTarget::Trait(_)
|
| LangItemTarget::TypeAlias(_)
|
||||||
| LangItemTarget::EnumId(_) => return None,
|
| LangItemTarget::Trait(_)
|
||||||
}))
|
| LangItemTarget::EnumId(_) => return None,
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let n_segments = path.segments().len();
|
let n_segments = path.segments().len();
|
||||||
|
@ -276,20 +291,24 @@ impl Resolver {
|
||||||
.find(|entry| entry.name() == first_name);
|
.find(|entry| entry.name() == first_name);
|
||||||
|
|
||||||
if let Some(e) = entry {
|
if let Some(e) = entry {
|
||||||
return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(
|
return Some(ResolveValueResult::ValueNs(
|
||||||
e.binding(),
|
ValueNs::LocalBinding(e.binding()),
|
||||||
)));
|
None,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Scope::GenericParams { params, def } => {
|
Scope::GenericParams { params, def } => {
|
||||||
if let Some(id) = params.find_const_by_name(first_name, *def) {
|
if let Some(id) = params.find_const_by_name(first_name, *def) {
|
||||||
let val = ValueNs::GenericParam(id);
|
let val = ValueNs::GenericParam(id);
|
||||||
return Some(ResolveValueResult::ValueNs(val));
|
return Some(ResolveValueResult::ValueNs(val, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Scope::ImplDefScope(impl_) => {
|
&Scope::ImplDefScope(impl_) => {
|
||||||
if first_name == &name![Self] {
|
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
|
// bare `Self` doesn't work in the value namespace in a struct/enum definition
|
||||||
|
@ -308,18 +327,22 @@ impl Resolver {
|
||||||
Scope::GenericParams { params, def } => {
|
Scope::GenericParams { params, def } => {
|
||||||
if let Some(id) = params.find_type_by_name(first_name, *def) {
|
if let Some(id) = params.find_type_by_name(first_name, *def) {
|
||||||
let ty = TypeNs::GenericParam(id);
|
let ty = TypeNs::GenericParam(id);
|
||||||
return Some(ResolveValueResult::Partial(ty, 1));
|
return Some(ResolveValueResult::Partial(ty, 1, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Scope::ImplDefScope(impl_) => {
|
&Scope::ImplDefScope(impl_) => {
|
||||||
if first_name == &name![Self] {
|
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) => {
|
Scope::AdtScope(adt) => {
|
||||||
if first_name == &name![Self] {
|
if first_name == &name![Self] {
|
||||||
let ty = TypeNs::AdtSelfType(*adt);
|
let ty = TypeNs::AdtSelfType(*adt);
|
||||||
return Some(ResolveValueResult::Partial(ty, 1));
|
return Some(ResolveValueResult::Partial(ty, 1, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Scope::BlockScope(m) => {
|
Scope::BlockScope(m) => {
|
||||||
|
@ -340,7 +363,7 @@ impl Resolver {
|
||||||
// `use core::u16;`.
|
// `use core::u16;`.
|
||||||
if path.kind == PathKind::Plain && n_segments > 1 {
|
if path.kind == PathKind::Plain && n_segments > 1 {
|
||||||
if let Some(builtin) = BuiltinType::by_name(first_name) {
|
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 @@ impl Resolver {
|
||||||
path: &Path,
|
path: &Path,
|
||||||
) -> Option<ValueNs> {
|
) -> Option<ValueNs> {
|
||||||
match self.resolve_path_in_value_ns(db, path)? {
|
match self.resolve_path_in_value_ns(db, path)? {
|
||||||
ResolveValueResult::ValueNs(it) => Some(it),
|
ResolveValueResult::ValueNs(it, _) => Some(it),
|
||||||
ResolveValueResult::Partial(..) => None,
|
ResolveValueResult::Partial(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,12 +386,12 @@ impl Resolver {
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
path: &ModPath,
|
path: &ModPath,
|
||||||
expected_macro_kind: Option<MacroSubNs>,
|
expected_macro_kind: Option<MacroSubNs>,
|
||||||
) -> Option<MacroId> {
|
) -> Option<(MacroId, Option<ImportId>)> {
|
||||||
let (item_map, module) = self.item_scope();
|
let (item_map, module) = self.item_scope();
|
||||||
item_map
|
item_map
|
||||||
.resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind)
|
.resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind)
|
||||||
.0
|
.0
|
||||||
.take_macros()
|
.take_macros_import()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a set of names available in the current scope.
|
/// Returns a set of names available in the current scope.
|
||||||
|
@ -776,11 +799,12 @@ impl ModuleItemMap {
|
||||||
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
|
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
|
||||||
match idx {
|
match idx {
|
||||||
None => {
|
None => {
|
||||||
let value = to_value_ns(module_def)?;
|
let (value, import) = to_value_ns(module_def)?;
|
||||||
Some(ResolveValueResult::ValueNs(value))
|
Some(ResolveValueResult::ValueNs(value, import))
|
||||||
}
|
}
|
||||||
Some(idx) => {
|
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::AdtId(it) => TypeNs::AdtId(it),
|
||||||
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
|
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
|
||||||
ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
|
ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
|
||||||
|
@ -794,7 +818,7 @@ impl ModuleItemMap {
|
||||||
| ModuleDefId::MacroId(_)
|
| ModuleDefId::MacroId(_)
|
||||||
| ModuleDefId::StaticId(_) => return None,
|
| ModuleDefId::StaticId(_) => return None,
|
||||||
};
|
};
|
||||||
Some(ResolveValueResult::Partial(ty, idx))
|
Some(ResolveValueResult::Partial(ty, idx, import))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -803,16 +827,17 @@ impl ModuleItemMap {
|
||||||
&self,
|
&self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
path: &ModPath,
|
path: &ModPath,
|
||||||
) -> Option<(TypeNs, Option<usize>)> {
|
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
|
||||||
let (module_def, idx) =
|
let (module_def, idx) =
|
||||||
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
|
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
|
||||||
let res = to_type_ns(module_def)?;
|
let (res, import) = to_type_ns(module_def)?;
|
||||||
Some((res, idx))
|
Some((res, idx, import))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
|
fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportId>)> {
|
||||||
let res = match per_ns.take_values()? {
|
let (def, import) = per_ns.take_values_import()?;
|
||||||
|
let res = match def {
|
||||||
ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
|
ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
|
||||||
ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
|
ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
|
||||||
ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
|
ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
|
||||||
|
@ -827,11 +852,12 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
|
||||||
| ModuleDefId::MacroId(_)
|
| ModuleDefId::MacroId(_)
|
||||||
| ModuleDefId::ModuleId(_) => return None,
|
| ModuleDefId::ModuleId(_) => return None,
|
||||||
};
|
};
|
||||||
Some(res)
|
Some((res, import))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
|
fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
|
||||||
let res = match per_ns.take_types()? {
|
let (def, _, import) = per_ns.take_types_full()?;
|
||||||
|
let res = match def {
|
||||||
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
|
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
|
||||||
ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
|
ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
|
||||||
|
|
||||||
|
@ -847,7 +873,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
|
||||||
| ModuleDefId::StaticId(_)
|
| ModuleDefId::StaticId(_)
|
||||||
| ModuleDefId::ModuleId(_) => return None,
|
| ModuleDefId::ModuleId(_) => return None,
|
||||||
};
|
};
|
||||||
Some(res)
|
Some((res, import))
|
||||||
}
|
}
|
||||||
|
|
||||||
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<rustc_hash::FxHasher>>;
|
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<rustc_hash::FxHasher>>;
|
||||||
|
@ -864,13 +890,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() {
|
||||||
|
|
|
@ -75,7 +75,7 @@ fn walk_unsafe(
|
||||||
Expr::Path(path) => {
|
Expr::Path(path) => {
|
||||||
let resolver = resolver_for_expr(db.upcast(), def, current);
|
let resolver = resolver_for_expr(db.upcast(), def, current);
|
||||||
let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path);
|
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 {
|
if db.static_data(id).mutable {
|
||||||
unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
|
unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1017,7 +1017,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||||
let (resolution, unresolved) = if value_ns {
|
let (resolution, unresolved) = if value_ns {
|
||||||
match self.resolver.resolve_path_in_value_ns(self.db.upcast(), path) {
|
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) => {
|
ValueNs::EnumVariantId(var) => {
|
||||||
let substs = ctx.substs_from_path(path, var.into(), true);
|
let substs = ctx.substs_from_path(path, var.into(), true);
|
||||||
let ty = self.db.ty(var.parent.into());
|
let ty = self.db.ty(var.parent.into());
|
||||||
|
@ -1033,12 +1033,14 @@ impl<'a> InferenceContext<'a> {
|
||||||
ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
|
ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
|
||||||
_ => return (self.err_ty(), 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),
|
None => return (self.err_ty(), None),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
|
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),
|
None => return (self.err_ty(), None),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -322,7 +322,7 @@ impl InferenceContext<'_> {
|
||||||
Expr::Path(p) => {
|
Expr::Path(p) => {
|
||||||
let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
|
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 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 {
|
if let ValueNs::LocalBinding(b) = v {
|
||||||
return Some(HirPlace { local: b, projections: vec![] });
|
return Some(HirPlace { local: b, projections: vec![] });
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,8 @@ impl InferenceContext<'_> {
|
||||||
self.resolver.resolve_path_in_value_ns(self.db.upcast(), path)?;
|
self.resolver.resolve_path_in_value_ns(self.db.upcast(), path)?;
|
||||||
|
|
||||||
match value_or_partial {
|
match value_or_partial {
|
||||||
ResolveValueResult::ValueNs(it) => (it, None),
|
ResolveValueResult::ValueNs(it, _) => (it, None),
|
||||||
ResolveValueResult::Partial(def, remaining_index) => self
|
ResolveValueResult::Partial(def, remaining_index, _) => self
|
||||||
.resolve_assoc_item(def, path, remaining_index, id)
|
.resolve_assoc_item(def, path, remaining_index, id)
|
||||||
.map(|(it, substs)| (it, Some(substs)))?,
|
.map(|(it, substs)| (it, Some(substs)))?,
|
||||||
}
|
}
|
||||||
|
|
|
@ -393,11 +393,9 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
let ty = {
|
let ty = {
|
||||||
let macro_call = macro_call.to_node(self.db.upcast());
|
let macro_call = macro_call.to_node(self.db.upcast());
|
||||||
let resolver = |path| {
|
let resolver = |path| {
|
||||||
self.resolver.resolve_path_as_macro(
|
self.resolver
|
||||||
self.db.upcast(),
|
.resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
|
||||||
&path,
|
.map(|(it, _)| it)
|
||||||
Some(MacroSubNs::Bang),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call, resolver)
|
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call, resolver)
|
||||||
{
|
{
|
||||||
|
@ -449,7 +447,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let resolution = match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
|
let resolution = match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
|
||||||
Some((it, None)) => it,
|
Some((it, None, _)) => it,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
match resolution {
|
match resolution {
|
||||||
|
@ -629,7 +627,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||||
return self.lower_ty_relative_path(ty, res, path.segments());
|
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) {
|
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return (TyKind::Error.intern(Interner), None),
|
None => return (TyKind::Error.intern(Interner), None),
|
||||||
|
|
|
@ -1352,14 +1352,14 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
||||||
.resolve_path_in_value_ns(self.db.upcast(), c)
|
.resolve_path_in_value_ns(self.db.upcast(), c)
|
||||||
.ok_or_else(unresolved_name)?;
|
.ok_or_else(unresolved_name)?;
|
||||||
match pr {
|
match pr {
|
||||||
ResolveValueResult::ValueNs(v) => {
|
ResolveValueResult::ValueNs(v, _) => {
|
||||||
if let ValueNs::ConstId(c) = v {
|
if let ValueNs::ConstId(c) = v {
|
||||||
self.lower_const_to_operand(Substitution::empty(Interner), c.into(), ty)
|
self.lower_const_to_operand(Substitution::empty(Interner), c.into(), ty)
|
||||||
} else {
|
} else {
|
||||||
not_supported!("bad path in range pattern");
|
not_supported!("bad path in range pattern");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ResolveValueResult::Partial(_, _) => {
|
ResolveValueResult::Partial(_, _, _) => {
|
||||||
not_supported!("associated constants in range pattern")
|
not_supported!("associated constants in range pattern")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,7 +323,7 @@ impl MirLowerCtx<'_> {
|
||||||
break 'b (c, x.1);
|
break 'b (c, x.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let ResolveValueResult::ValueNs(v) = pr {
|
if let ResolveValueResult::ValueNs(v, _) = pr {
|
||||||
if let ValueNs::ConstId(c) = v {
|
if let ValueNs::ConstId(c) = v {
|
||||||
break 'b (c, Substitution::empty(Interner));
|
break 'b (c, Substitution::empty(Interner));
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,7 +623,7 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
|
let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
|
||||||
resolver
|
resolver
|
||||||
.resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
|
.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(
|
hir_expand::db::expand_speculative(
|
||||||
self.db.upcast(),
|
self.db.upcast(),
|
||||||
|
|
|
@ -487,7 +487,7 @@ impl SourceAnalyzer {
|
||||||
let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
|
let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
|
||||||
self.resolver
|
self.resolver
|
||||||
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Bang))
|
.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(
|
pub(crate) fn resolve_bind_pat_to_const(
|
||||||
|
@ -760,7 +760,7 @@ impl SourceAnalyzer {
|
||||||
let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
|
let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
|
||||||
self.resolver
|
self.resolver
|
||||||
.resolve_path_as_macro(db.upcast(), &path, Some(MacroSubNs::Bang))
|
.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)
|
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> {
|
) -> Option<Macro> {
|
||||||
resolver
|
resolver
|
||||||
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Attr))
|
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Attr))
|
||||||
|
.map(|(it, _)| it)
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -983,7 +984,7 @@ fn resolve_hir_path_(
|
||||||
res.map(|ty_ns| (ty_ns, path.segments().first()))
|
res.map(|ty_ns| (ty_ns, path.segments().first()))
|
||||||
}
|
}
|
||||||
None => {
|
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 {
|
match remaining_idx {
|
||||||
Some(remaining_idx) => {
|
Some(remaining_idx) => {
|
||||||
if remaining_idx + 1 == path.segments().len() {
|
if remaining_idx + 1 == path.segments().len() {
|
||||||
|
@ -1067,7 +1068,7 @@ fn resolve_hir_path_(
|
||||||
let macros = || {
|
let macros = || {
|
||||||
resolver
|
resolver
|
||||||
.resolve_path_as_macro(db.upcast(), path.mod_path()?, None)
|
.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) }
|
if prefer_value_ns { values().or_else(types) } else { types().or_else(values) }
|
||||||
|
|
|
@ -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…
Add table
Add a link
Reference in a new issue