Thread imports through the resolver
This commit is contained in:
parent
c4e9b5ac64
commit
a17d73ad36
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
);
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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>>;
|
||||
|
@ -75,7 +75,7 @@ fn walk_unsafe(
|
||||
Expr::Path(path) => {
|
||||
let resolver = resolver_for_expr(db.upcast(), def, current);
|
||||
let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path);
|
||||
if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial {
|
||||
if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
|
||||
if db.static_data(id).mutable {
|
||||
unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
|
||||
}
|
||||
|
@ -1017,7 +1017,7 @@ 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),
|
||||
}
|
||||
};
|
||||
|
@ -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![] });
|
||||
}
|
||||
|
@ -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)))?,
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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) }
|
||||
|
Loading…
x
Reference in New Issue
Block a user