Unnamed repository; edit this file 'description' to name the repository.
Thread imports through the resolver
Lukas Wirth 2023-08-17
parent c4e9b5a · commit a17d73a
-rw-r--r--crates/hir-def/src/item_scope.rs60
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mod.rs2
-rw-r--r--crates/hir-def/src/nameres/collector.rs13
-rw-r--r--crates/hir-def/src/nameres/path_resolution.rs76
-rw-r--r--crates/hir-def/src/per_ns.rs37
-rw-r--r--crates/hir-def/src/resolver.rs116
-rw-r--r--crates/hir-ty/src/diagnostics/unsafe_check.rs2
-rw-r--r--crates/hir-ty/src/infer.rs8
-rw-r--r--crates/hir-ty/src/infer/closure.rs2
-rw-r--r--crates/hir-ty/src/infer/path.rs4
-rw-r--r--crates/hir-ty/src/lower.rs12
-rw-r--r--crates/hir-ty/src/mir/lower.rs4
-rw-r--r--crates/hir-ty/src/mir/lower/pattern_matching.rs2
-rw-r--r--crates/hir/src/semantics.rs2
-rw-r--r--crates/hir/src/source_analyzer.rs9
15 files changed, 218 insertions, 131 deletions
diff --git a/crates/hir-def/src/item_scope.rs b/crates/hir-def/src/item_scope.rs
index 59a1c5f49e..0baf3fa7f4 100644
--- a/crates/hir-def/src/item_scope.rs
+++ b/crates/hir-def/src/item_scope.rs
@@ -34,7 +34,7 @@ pub enum ImportOrExternCrate {
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum ImportType {
+pub(crate) enum ImportType {
Import(ImportId),
Glob(UseId),
ExternCrate(ExternCrateId),
@@ -118,7 +118,7 @@ struct DeriveMacroInvocation {
pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
BuiltinType::ALL
.iter()
- .map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public)))
+ .map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public, None)))
.collect()
});
@@ -234,9 +234,16 @@ impl ItemScope {
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))),
+ self.unnamed_trait_imports.iter().map(|(tr, (vis, i))| {
+ (
+ None,
+ PerNs::types(
+ ModuleDefId::TraitId(*tr),
+ *vis,
+ i.map(ImportOrExternCrate::Import),
+ ),
+ )
+ }),
)
}
}
@@ -327,11 +334,13 @@ 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> {
self.unnamed_trait_imports.get(&tr).copied().map(|(a, _)| a)
}
pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) {
+ // FIXME: import
self.unnamed_trait_imports.insert(tr, (vis, None));
}
@@ -344,6 +353,8 @@ impl ItemScope {
) -> bool {
let mut changed = false;
+ // FIXME: Document and simplify this
+
if let Some(mut fld) = def.types {
let existing = self.types.entry(lookup.1.clone());
match existing {
@@ -626,28 +637,39 @@ impl ItemScope {
}
impl PerNs {
- pub(crate) fn from_def(def: ModuleDefId, v: Visibility, has_constructor: bool) -> PerNs {
+ pub(crate) fn from_def(
+ def: ModuleDefId,
+ v: Visibility,
+ has_constructor: bool,
+ import: Option<ImportOrExternCrate>,
+ ) -> PerNs {
match def {
- ModuleDefId::ModuleId(_) => PerNs::types(def, v),
- ModuleDefId::FunctionId(_) => PerNs::values(def, v),
+ ModuleDefId::ModuleId(_) => PerNs::types(def, v, import),
+ ModuleDefId::FunctionId(_) => {
+ PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
+ }
ModuleDefId::AdtId(adt) => match adt {
- AdtId::UnionId(_) => PerNs::types(def, v),
- AdtId::EnumId(_) => PerNs::types(def, v),
+ AdtId::UnionId(_) => PerNs::types(def, v, import),
+ AdtId::EnumId(_) => PerNs::types(def, v, import),
AdtId::StructId(_) => {
if has_constructor {
- PerNs::both(def, def, v)
+ PerNs::both(def, def, v, import)
} else {
- PerNs::types(def, v)
+ PerNs::types(def, v, import)
}
}
},
- ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v),
- ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),
- ModuleDefId::TraitId(_) => PerNs::types(def, v),
- ModuleDefId::TraitAliasId(_) => PerNs::types(def, v),
- ModuleDefId::TypeAliasId(_) => PerNs::types(def, v),
- ModuleDefId::BuiltinType(_) => PerNs::types(def, v),
- ModuleDefId::MacroId(mac) => PerNs::macros(mac, v),
+ ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v, import),
+ ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => {
+ PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
+ }
+ ModuleDefId::TraitId(_) => PerNs::types(def, v, import),
+ ModuleDefId::TraitAliasId(_) => PerNs::types(def, v, import),
+ ModuleDefId::TypeAliasId(_) => PerNs::types(def, v, import),
+ ModuleDefId::BuiltinType(_) => PerNs::types(def, v, import),
+ ModuleDefId::MacroId(mac) => {
+ PerNs::macros(mac, v, import.and_then(ImportOrExternCrate::into_import))
+ }
}
}
}
diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs
index 7a87e61c69..8adced4e08 100644
--- a/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -131,7 +131,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
.as_call_id_with_errors(&db, krate, |path| {
resolver
.resolve_path_as_macro(&db, &path, Some(MacroSubNs::Bang))
- .map(|it| macro_id_to_def_id(&db, it))
+ .map(|(it, _)| macro_id_to_def_id(&db, it))
})
.unwrap();
let macro_call_id = res.value.unwrap();
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 48eaec0f4e..e9e71a8747 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -648,7 +648,7 @@ impl DefCollector<'_> {
self.def_map.modules[module_id].scope.declare(macro_.into());
self.update(
module_id,
- &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
+ &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
Visibility::Public,
None,
);
@@ -684,7 +684,7 @@ impl DefCollector<'_> {
self.def_map.modules[module_id].scope.declare(macro_.into());
self.update(
module_id,
- &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
+ &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
vis,
None,
);
@@ -699,7 +699,7 @@ impl DefCollector<'_> {
self.def_map.modules[module_id].scope.declare(macro_.into());
self.update(
module_id,
- &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
+ &[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
Visibility::Public,
None,
);
@@ -783,6 +783,7 @@ impl DefCollector<'_> {
Some(res) => PartialResolvedImport::Resolved(PerNs::types(
res.into(),
Visibility::Public,
+ None,
)),
None => PartialResolvedImport::Unresolved,
}
@@ -967,7 +968,7 @@ impl DefCollector<'_> {
.map(|(local_id, variant_data)| {
let name = variant_data.name.clone();
let variant = EnumVariantId { parent: e, local_id };
- let res = PerNs::both(variant.into(), variant.into(), vis);
+ let res = PerNs::both(variant.into(), variant.into(), vis, None);
(Some(name), res)
})
.collect::<Vec<_>>();
@@ -1547,7 +1548,7 @@ impl ModCollector<'_, '_> {
def_collector.def_map.modules[module_id].scope.declare(id);
def_collector.update(
module_id,
- &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
+ &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor, None))],
vis,
None,
)
@@ -1977,7 +1978,7 @@ impl ModCollector<'_, '_> {
def_map.modules[self.module_id].scope.declare(def);
self.def_collector.update(
self.module_id,
- &[(Some(name), PerNs::from_def(def, vis, false))],
+ &[(Some(name), PerNs::from_def(def, vis, false, None))],
vis,
None,
);
diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs
index fc296e1e58..460a908b6d 100644
--- a/crates/hir-def/src/nameres/path_resolution.rs
+++ b/crates/hir-def/src/nameres/path_resolution.rs
@@ -15,8 +15,9 @@ use hir_expand::name::Name;
use triomphe::Arc;
use crate::{
+ data::adt::VariantData,
db::DefDatabase,
- item_scope::BUILTIN_SCOPE,
+ item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
path::{ModPath, PathKind},
per_ns::PerNs,
@@ -196,15 +197,15 @@ impl DefMap {
PathKind::DollarCrate(krate) => {
if krate == self.krate {
cov_mark::hit!(macro_dollar_crate_self);
- PerNs::types(self.crate_root().into(), Visibility::Public)
+ PerNs::types(self.crate_root().into(), Visibility::Public, None)
} else {
let def_map = db.crate_def_map(krate);
let module = def_map.module_id(Self::ROOT);
cov_mark::hit!(macro_dollar_crate_other);
- PerNs::types(module.into(), Visibility::Public)
+ PerNs::types(module.into(), Visibility::Public, None)
}
}
- PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public),
+ PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public, None),
// plain import or absolute path in 2015: crate-relative with
// fallback to extern prelude (with the simplification in
// rust-lang/rust#57745)
@@ -291,7 +292,7 @@ impl DefMap {
);
}
- PerNs::types(module.into(), Visibility::Public)
+ PerNs::types(module.into(), Visibility::Public, None)
}
PathKind::Abs => {
// 2018-style absolute path -- only extern prelude
@@ -299,9 +300,13 @@ impl DefMap {
Some((_, segment)) => segment,
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
};
- if let Some(&(def, _extern_crate)) = self.data.extern_prelude.get(segment) {
+ if let Some(&(def, extern_crate)) = self.data.extern_prelude.get(segment) {
tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def);
- PerNs::types(def.into(), Visibility::Public)
+ PerNs::types(
+ def.into(),
+ Visibility::Public,
+ extern_crate.map(ImportOrExternCrate::ExternCrate),
+ )
} else {
return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
}
@@ -309,7 +314,7 @@ impl DefMap {
};
for (i, segment) in segments {
- let (curr, vis) = match curr_per_ns.take_types_vis() {
+ let (curr, vis, imp) = match curr_per_ns.take_types_full() {
Some(r) => r,
None => {
// we still have path segments left, but the path so far
@@ -364,18 +369,20 @@ impl DefMap {
Some(local_id) => {
let variant = EnumVariantId { parent: e, local_id };
match &*enum_data.variants[local_id].variant_data {
- crate::data::adt::VariantData::Record(_) => {
- PerNs::types(variant.into(), Visibility::Public)
- }
- crate::data::adt::VariantData::Tuple(_)
- | crate::data::adt::VariantData::Unit => {
- PerNs::both(variant.into(), variant.into(), Visibility::Public)
+ VariantData::Record(_) => {
+ PerNs::types(variant.into(), Visibility::Public, None)
}
+ VariantData::Tuple(_) | VariantData::Unit => PerNs::both(
+ variant.into(),
+ variant.into(),
+ Visibility::Public,
+ None,
+ ),
}
}
None => {
return ResolvePathResult::with(
- PerNs::types(e.into(), vis),
+ PerNs::types(e.into(), vis, imp),
ReachedFixedPoint::Yes,
Some(i),
Some(self.krate),
@@ -393,7 +400,7 @@ impl DefMap {
);
return ResolvePathResult::with(
- PerNs::types(s, vis),
+ PerNs::types(s, vis, imp),
ReachedFixedPoint::Yes,
Some(i),
Some(self.krate),
@@ -430,7 +437,7 @@ impl DefMap {
.filter(|&id| {
sub_namespace_match(Some(MacroSubNs::from_id(db, id)), expected_macro_subns)
})
- .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
+ .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public, None));
let from_scope = self[module].scope.get(name).filter_macro(db, expected_macro_subns);
let from_builtin = match self.block {
Some(_) => {
@@ -449,16 +456,26 @@ impl DefMap {
let extern_prelude = || {
if self.block.is_some() {
- // Don't resolve extern prelude in block `DefMap`s.
+ // Don't resolve extern prelude in block `DefMap`s, defer it to the crate def map so
+ // that blocks can properly shadow them
return PerNs::none();
}
- self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
- PerNs::types(it.into(), Visibility::Public)
+ self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {
+ PerNs::types(
+ it.into(),
+ Visibility::Public,
+ extern_crate.map(ImportOrExternCrate::ExternCrate),
+ )
})
};
let macro_use_prelude = || {
self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
- PerNs::macros(it.into(), Visibility::Public)
+ PerNs::macros(
+ it.into(),
+ Visibility::Public,
+ // FIXME?
+ None, // extern_crate.map(ImportOrExternCrate::ExternCrate),
+ )
})
};
let prelude = || self.resolve_in_prelude(db, name);
@@ -487,13 +504,16 @@ impl DefMap {
// Don't resolve extern prelude in block `DefMap`s.
return PerNs::none();
}
- self.data
- .extern_prelude
- .get(name)
- .copied()
- .map_or(PerNs::none(), |(it, _extern_crate)| {
- PerNs::types(it.into(), Visibility::Public)
- })
+ self.data.extern_prelude.get(name).copied().map_or(
+ PerNs::none(),
+ |(it, extern_crate)| {
+ PerNs::types(
+ it.into(),
+ Visibility::Public,
+ extern_crate.map(ImportOrExternCrate::ExternCrate),
+ )
+ },
+ )
};
from_crate_root.or_else(from_extern_prelude)
diff --git a/crates/hir-def/src/per_ns.rs b/crates/hir-def/src/per_ns.rs
index f32a97d1a3..3f3f9f4249 100644
--- a/crates/hir-def/src/per_ns.rs
+++ b/crates/hir-def/src/per_ns.rs
@@ -27,20 +27,29 @@ impl PerNs {
PerNs { types: None, values: None, macros: None }
}
- pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
- PerNs { types: None, values: Some((t, v, None)), macros: None }
+ pub fn values(t: ModuleDefId, v: Visibility, i: Option<ImportId>) -> PerNs {
+ PerNs { types: None, values: Some((t, v, i)), macros: None }
}
- pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
- PerNs { types: Some((t, v, None)), values: None, macros: None }
+ pub fn types(t: ModuleDefId, v: Visibility, i: Option<ImportOrExternCrate>) -> PerNs {
+ PerNs { types: Some((t, v, i)), values: None, macros: None }
}
- pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
- PerNs { types: Some((types, v, None)), values: Some((values, v, None)), macros: None }
+ pub fn both(
+ types: ModuleDefId,
+ values: ModuleDefId,
+ v: Visibility,
+ i: Option<ImportOrExternCrate>,
+ ) -> PerNs {
+ PerNs {
+ types: Some((types, v, i)),
+ values: Some((values, v, i.and_then(ImportOrExternCrate::into_import))),
+ macros: None,
+ }
}
- pub fn macros(macro_: MacroId, v: Visibility) -> PerNs {
- PerNs { types: None, values: None, macros: Some((macro_, v, None)) }
+ pub fn macros(macro_: MacroId, v: Visibility, i: Option<ImportId>) -> PerNs {
+ PerNs { types: None, values: None, macros: Some((macro_, v, i)) }
}
pub fn is_none(&self) -> bool {
@@ -55,18 +64,26 @@ impl PerNs {
self.types.map(|it| it.0)
}
- pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> {
- self.types.map(|(a, b, _)| (a, b))
+ pub fn take_types_full(self) -> Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)> {
+ self.types
}
pub fn take_values(self) -> Option<ModuleDefId> {
self.values.map(|it| it.0)
}
+ pub fn take_values_import(self) -> Option<(ModuleDefId, Option<ImportId>)> {
+ self.values.map(|it| (it.0, it.2))
+ }
+
pub fn take_macros(self) -> Option<MacroId> {
self.macros.map(|it| it.0)
}
+ pub fn take_macros_import(self) -> Option<(MacroId, Option<ImportId>)> {
+ self.macros.map(|it| (it.0, it.2))
+ }
+
pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
let _p = profile::span("PerNs::filter_visibility");
PerNs {
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 28ab0f8f6e..62576100ea 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -15,7 +15,7 @@ use crate::{
db::DefDatabase,
generics::{GenericParams, TypeOrConstParamData},
hir::{BindingId, ExprId, LabelId},
- item_scope::{BuiltinShadowMode, BUILTIN_SCOPE},
+ item_scope::{BuiltinShadowMode, ImportId, ImportOrExternCrate, BUILTIN_SCOPE},
lang_item::LangItemTarget,
nameres::{DefMap, MacroSubNs},
path::{ModPath, Path, PathKind},
@@ -100,8 +100,8 @@ pub enum TypeNs {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ResolveValueResult {
- ValueNs(ValueNs),
- Partial(TypeNs, usize),
+ ValueNs(ValueNs, Option<ImportId>),
+ Partial(TypeNs, usize, Option<ImportOrExternCrate>),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -152,7 +152,7 @@ impl Resolver {
&self,
db: &dyn DefDatabase,
path: &Path,
- ) -> Option<(TypeNs, Option<usize>)> {
+ ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
let path = match path {
Path::Normal { mod_path, .. } => mod_path,
Path::LangItem(l) => {
@@ -169,6 +169,7 @@ impl Resolver {
| LangItemTarget::Static(_) => return None,
},
None,
+ None,
))
}
};
@@ -185,17 +186,17 @@ impl Resolver {
Scope::ExprScope(_) => continue,
Scope::GenericParams { params, def } => {
if let Some(id) = params.find_type_by_name(first_name, *def) {
- return Some((TypeNs::GenericParam(id), remaining_idx()));
+ return Some((TypeNs::GenericParam(id), remaining_idx(), None));
}
}
&Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
- return Some((TypeNs::SelfType(impl_), remaining_idx()));
+ return Some((TypeNs::SelfType(impl_), remaining_idx(), None));
}
}
&Scope::AdtScope(adt) => {
if first_name == &name![Self] {
- return Some((TypeNs::AdtSelfType(adt), remaining_idx()));
+ return Some((TypeNs::AdtSelfType(adt), remaining_idx(), None));
}
}
Scope::BlockScope(m) => {
@@ -208,12 +209,24 @@ impl Resolver {
self.module_scope.resolve_path_in_type_ns(db, path)
}
+ pub fn resolve_path_in_type_ns_fully_with_imports(
+ &self,
+ db: &dyn DefDatabase,
+ path: &Path,
+ ) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
+ let (res, unresolved, imp) = self.resolve_path_in_type_ns(db, path)?;
+ if unresolved.is_some() {
+ return None;
+ }
+ Some((res, imp))
+ }
+
pub fn resolve_path_in_type_ns_fully(
&self,
db: &dyn DefDatabase,
path: &Path,
) -> Option<TypeNs> {
- let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
+ let (res, unresolved, _) = self.resolve_path_in_type_ns(db, path)?;
if unresolved.is_some() {
return None;
}
@@ -235,7 +248,6 @@ impl Resolver {
RawVisibility::Public => Some(Visibility::Public),
}
}
-
pub fn resolve_path_in_value_ns(
&self,
db: &dyn DefDatabase,
@@ -244,17 +256,20 @@ impl Resolver {
let path = match path {
Path::Normal { mod_path, .. } => mod_path,
Path::LangItem(l) => {
- return Some(ResolveValueResult::ValueNs(match *l {
- LangItemTarget::Function(it) => ValueNs::FunctionId(it),
- LangItemTarget::Static(it) => ValueNs::StaticId(it),
- LangItemTarget::Struct(it) => ValueNs::StructId(it),
- LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
- LangItemTarget::Union(_)
- | LangItemTarget::ImplDef(_)
- | LangItemTarget::TypeAlias(_)
- | LangItemTarget::Trait(_)
- | LangItemTarget::EnumId(_) => return None,
- }))
+ return Some(ResolveValueResult::ValueNs(
+ match *l {
+ LangItemTarget::Function(it) => ValueNs::FunctionId(it),
+ LangItemTarget::Static(it) => ValueNs::StaticId(it),
+ LangItemTarget::Struct(it) => ValueNs::StructId(it),
+ LangItemTarget::EnumVariant(it) => ValueNs::EnumVariantId(it),
+ LangItemTarget::Union(_)
+ | LangItemTarget::ImplDef(_)
+ | LangItemTarget::TypeAlias(_)
+ | LangItemTarget::Trait(_)
+ | LangItemTarget::EnumId(_) => return None,
+ },
+ None,
+ ))
}
};
let n_segments = path.segments().len();
@@ -276,20 +291,24 @@ impl Resolver {
.find(|entry| entry.name() == first_name);
if let Some(e) = entry {
- return Some(ResolveValueResult::ValueNs(ValueNs::LocalBinding(
- e.binding(),
- )));
+ return Some(ResolveValueResult::ValueNs(
+ ValueNs::LocalBinding(e.binding()),
+ None,
+ ));
}
}
Scope::GenericParams { params, def } => {
if let Some(id) = params.find_const_by_name(first_name, *def) {
let val = ValueNs::GenericParam(id);
- return Some(ResolveValueResult::ValueNs(val));
+ return Some(ResolveValueResult::ValueNs(val, None));
}
}
&Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
- return Some(ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_)));
+ return Some(ResolveValueResult::ValueNs(
+ ValueNs::ImplSelf(impl_),
+ None,
+ ));
}
}
// bare `Self` doesn't work in the value namespace in a struct/enum definition
@@ -308,18 +327,22 @@ impl Resolver {
Scope::GenericParams { params, def } => {
if let Some(id) = params.find_type_by_name(first_name, *def) {
let ty = TypeNs::GenericParam(id);
- return Some(ResolveValueResult::Partial(ty, 1));
+ return Some(ResolveValueResult::Partial(ty, 1, None));
}
}
&Scope::ImplDefScope(impl_) => {
if first_name == &name![Self] {
- return Some(ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1));
+ return Some(ResolveValueResult::Partial(
+ TypeNs::SelfType(impl_),
+ 1,
+ None,
+ ));
}
}
Scope::AdtScope(adt) => {
if first_name == &name![Self] {
let ty = TypeNs::AdtSelfType(*adt);
- return Some(ResolveValueResult::Partial(ty, 1));
+ return Some(ResolveValueResult::Partial(ty, 1, None));
}
}
Scope::BlockScope(m) => {
@@ -340,7 +363,7 @@ impl Resolver {
// `use core::u16;`.
if path.kind == PathKind::Plain && n_segments > 1 {
if let Some(builtin) = BuiltinType::by_name(first_name) {
- return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1));
+ return Some(ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None));
}
}
@@ -353,7 +376,7 @@ impl Resolver {
path: &Path,
) -> Option<ValueNs> {
match self.resolve_path_in_value_ns(db, path)? {
- ResolveValueResult::ValueNs(it) => Some(it),
+ ResolveValueResult::ValueNs(it, _) => Some(it),
ResolveValueResult::Partial(..) => None,
}
}
@@ -363,12 +386,12 @@ impl Resolver {
db: &dyn DefDatabase,
path: &ModPath,
expected_macro_kind: Option<MacroSubNs>,
- ) -> Option<MacroId> {
+ ) -> Option<(MacroId, Option<ImportId>)> {
let (item_map, module) = self.item_scope();
item_map
.resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind)
.0
- .take_macros()
+ .take_macros_import()
}
/// Returns a set of names available in the current scope.
@@ -776,11 +799,12 @@ impl ModuleItemMap {
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
match idx {
None => {
- let value = to_value_ns(module_def)?;
- Some(ResolveValueResult::ValueNs(value))
+ let (value, import) = to_value_ns(module_def)?;
+ Some(ResolveValueResult::ValueNs(value, import))
}
Some(idx) => {
- let ty = match module_def.take_types()? {
+ let (def, _, import) = module_def.take_types_full()?;
+ let ty = match def {
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
@@ -794,7 +818,7 @@ impl ModuleItemMap {
| ModuleDefId::MacroId(_)
| ModuleDefId::StaticId(_) => return None,
};
- Some(ResolveValueResult::Partial(ty, idx))
+ Some(ResolveValueResult::Partial(ty, idx, import))
}
}
}
@@ -803,16 +827,17 @@ impl ModuleItemMap {
&self,
db: &dyn DefDatabase,
path: &ModPath,
- ) -> Option<(TypeNs, Option<usize>)> {
+ ) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>)> {
let (module_def, idx) =
self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
- let res = to_type_ns(module_def)?;
- Some((res, idx))
+ let (res, import) = to_type_ns(module_def)?;
+ Some((res, idx, import))
}
}
-fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
- let res = match per_ns.take_values()? {
+fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportId>)> {
+ let (def, import) = per_ns.take_values_import()?;
+ let res = match def {
ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it),
ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it),
ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it),
@@ -827,11 +852,12 @@ fn to_value_ns(per_ns: PerNs) -> Option<ValueNs> {
| ModuleDefId::MacroId(_)
| ModuleDefId::ModuleId(_) => return None,
};
- Some(res)
+ Some((res, import))
}
-fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
- let res = match per_ns.take_types()? {
+fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
+ let (def, _, import) = per_ns.take_types_full()?;
+ let res = match def {
ModuleDefId::AdtId(it) => TypeNs::AdtId(it),
ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it),
@@ -847,7 +873,7 @@ fn to_type_ns(per_ns: PerNs) -> Option<TypeNs> {
| ModuleDefId::StaticId(_)
| ModuleDefId::ModuleId(_) => return None,
};
- Some(res)
+ Some((res, import))
}
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<rustc_hash::FxHasher>>;
diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs
index 9f9a56ffab..cbca0e801d 100644
--- a/crates/hir-ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir-ty/src/diagnostics/unsafe_check.rs
@@ -75,7 +75,7 @@ fn walk_unsafe(
Expr::Path(path) => {
let resolver = resolver_for_expr(db.upcast(), def, current);
let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path);
- if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial {
+ if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
if db.static_data(id).mutable {
unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
}
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index b4915dbf0f..0fb4934444 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -1017,7 +1017,7 @@ impl<'a> InferenceContext<'a> {
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
let (resolution, unresolved) = if value_ns {
match self.resolver.resolve_path_in_value_ns(self.db.upcast(), path) {
- Some(ResolveValueResult::ValueNs(value)) => match value {
+ Some(ResolveValueResult::ValueNs(value, _)) => match value {
ValueNs::EnumVariantId(var) => {
let substs = ctx.substs_from_path(path, var.into(), true);
let ty = self.db.ty(var.parent.into());
@@ -1033,12 +1033,14 @@ impl<'a> InferenceContext<'a> {
ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
_ => return (self.err_ty(), None),
},
- Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
+ Some(ResolveValueResult::Partial(typens, unresolved, _)) => {
+ (typens, Some(unresolved))
+ }
None => return (self.err_ty(), None),
}
} else {
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
- Some(it) => it,
+ Some((it, idx, _)) => (it, idx),
None => return (self.err_ty(), None),
}
};
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 1781f6c58f..23efe616f4 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -322,7 +322,7 @@ impl InferenceContext<'_> {
Expr::Path(p) => {
let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
if let Some(r) = resolver.resolve_path_in_value_ns(self.db.upcast(), p) {
- if let ResolveValueResult::ValueNs(v) = r {
+ if let ResolveValueResult::ValueNs(v, _) = r {
if let ValueNs::LocalBinding(b) = v {
return Some(HirPlace { local: b, projections: vec![] });
}
diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs
index 79d9e21e79..2a51c84db3 100644
--- a/crates/hir-ty/src/infer/path.rs
+++ b/crates/hir-ty/src/infer/path.rs
@@ -61,8 +61,8 @@ impl InferenceContext<'_> {
self.resolver.resolve_path_in_value_ns(self.db.upcast(), path)?;
match value_or_partial {
- ResolveValueResult::ValueNs(it) => (it, None),
- ResolveValueResult::Partial(def, remaining_index) => self
+ ResolveValueResult::ValueNs(it, _) => (it, None),
+ ResolveValueResult::Partial(def, remaining_index, _) => self
.resolve_assoc_item(def, path, remaining_index, id)
.map(|(it, substs)| (it, Some(substs)))?,
}
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 20dccfafb3..0ab04b83cf 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -390,11 +390,9 @@ impl<'a> TyLoweringContext<'a> {
let ty = {
let macro_call = macro_call.to_node(self.db.upcast());
let resolver = |path| {
- self.resolver.resolve_path_as_macro(
- self.db.upcast(),
- &path,
- Some(MacroSubNs::Bang),
- )
+ self.resolver
+ .resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
+ .map(|(it, _)| it)
};
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call, resolver)
{
@@ -446,7 +444,7 @@ impl<'a> TyLoweringContext<'a> {
return None;
}
let resolution = match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
- Some((it, None)) => it,
+ Some((it, None, _)) => it,
_ => return None,
};
match resolution {
@@ -626,7 +624,7 @@ impl<'a> TyLoweringContext<'a> {
return self.lower_ty_relative_path(ty, res, path.segments());
}
- let (resolution, remaining_index) =
+ let (resolution, remaining_index, _) =
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
Some(it) => it,
None => return (TyKind::Error.intern(Interner), None),
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 7ab0c1f7f2..51cf882d05 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -1352,14 +1352,14 @@ impl<'ctx> MirLowerCtx<'ctx> {
.resolve_path_in_value_ns(self.db.upcast(), c)
.ok_or_else(unresolved_name)?;
match pr {
- ResolveValueResult::ValueNs(v) => {
+ ResolveValueResult::ValueNs(v, _) => {
if let ValueNs::ConstId(c) = v {
self.lower_const_to_operand(Substitution::empty(Interner), c.into(), ty)
} else {
not_supported!("bad path in range pattern");
}
}
- ResolveValueResult::Partial(_, _) => {
+ ResolveValueResult::Partial(_, _, _) => {
not_supported!("associated constants in range pattern")
}
}
diff --git a/crates/hir-ty/src/mir/lower/pattern_matching.rs b/crates/hir-ty/src/mir/lower/pattern_matching.rs
index 3354cbd76a..1cdfd91974 100644
--- a/crates/hir-ty/src/mir/lower/pattern_matching.rs
+++ b/crates/hir-ty/src/mir/lower/pattern_matching.rs
@@ -323,7 +323,7 @@ impl MirLowerCtx<'_> {
break 'b (c, x.1);
}
}
- if let ResolveValueResult::ValueNs(v) = pr {
+ if let ResolveValueResult::ValueNs(v, _) = pr {
if let ValueNs::ConstId(c) = v {
break 'b (c, Substitution::empty(Interner));
}
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index e99d2984c3..55760ba75a 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -606,7 +606,7 @@ impl<'db> SemanticsImpl<'db> {
let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| {
resolver
.resolve_path_as_macro(self.db.upcast(), &path, Some(MacroSubNs::Bang))
- .map(|it| macro_id_to_def_id(self.db.upcast(), it))
+ .map(|(it, _)| macro_id_to_def_id(self.db.upcast(), it))
})?;
hir_expand::db::expand_speculative(
self.db.upcast(),
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 3499daf114..f29fb1edf0 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -487,7 +487,7 @@ impl SourceAnalyzer {
let path = macro_call.value.path().and_then(|ast| Path::from_src(ast, &ctx))?;
self.resolver
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Bang))
- .map(|it| it.into())
+ .map(|(it, _)| it.into())
}
pub(crate) fn resolve_bind_pat_to_const(
@@ -760,7 +760,7 @@ impl SourceAnalyzer {
let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
self.resolver
.resolve_path_as_macro(db.upcast(), &path, Some(MacroSubNs::Bang))
- .map(|it| macro_id_to_def_id(db.upcast(), it))
+ .map(|(it, _)| macro_id_to_def_id(db.upcast(), it))
})?;
Some(macro_call_id.as_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
}
@@ -966,6 +966,7 @@ pub(crate) fn resolve_hir_path_as_attr_macro(
) -> Option<Macro> {
resolver
.resolve_path_as_macro(db.upcast(), path.mod_path()?, Some(MacroSubNs::Attr))
+ .map(|(it, _)| it)
.map(Into::into)
}
@@ -983,7 +984,7 @@ fn resolve_hir_path_(
res.map(|ty_ns| (ty_ns, path.segments().first()))
}
None => {
- let (ty, remaining_idx) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
+ let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
match remaining_idx {
Some(remaining_idx) => {
if remaining_idx + 1 == path.segments().len() {
@@ -1067,7 +1068,7 @@ fn resolve_hir_path_(
let macros = || {
resolver
.resolve_path_as_macro(db.upcast(), path.mod_path()?, None)
- .map(|def| PathResolution::Def(ModuleDef::Macro(def.into())))
+ .map(|(def, _)| PathResolution::Def(ModuleDef::Macro(def.into())))
};
if prefer_value_ns { values().or_else(types) } else { types().or_else(values) }