Thread imports through the resolver

This commit is contained in:
Lukas Wirth 2023-08-17 10:52:13 +02:00
parent c4e9b5ac64
commit a17d73ad36
15 changed files with 218 additions and 131 deletions

View File

@ -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))
}
}
}
}

View File

@ -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();

View File

@ -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,
);

View File

@ -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)

View File

@ -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 {

View File

@ -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>>;

View File

@ -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 });
}

View File

@ -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),
}
};

View File

@ -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![] });
}

View File

@ -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)))?,
}

View File

@ -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),

View File

@ -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")
}
}

View File

@ -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));
}

View File

@ -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(),

View File

@ -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) }