Skip to content

Commit

Permalink
Thread imports through the resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Aug 17, 2023
1 parent c4e9b5a commit a17d73a
Show file tree
Hide file tree
Showing 15 changed files with 218 additions and 131 deletions.
60 changes: 41 additions & 19 deletions crates/hir-def/src/item_scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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()
});

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

Expand All @@ -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 {
Expand Down Expand Up @@ -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))
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-def/src/macro_expansion_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
13 changes: 7 additions & 6 deletions crates/hir-def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
Expand Down Expand Up @@ -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,
);
Expand All @@ -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,
);
Expand Down Expand Up @@ -783,6 +783,7 @@ impl DefCollector<'_> {
Some(res) => PartialResolvedImport::Resolved(PerNs::types(
res.into(),
Visibility::Public,
None,
)),
None => PartialResolvedImport::Unresolved,
}
Expand Down Expand Up @@ -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<_>>();
Expand Down Expand Up @@ -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,
)
Expand Down Expand Up @@ -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,
);
Expand Down
76 changes: 48 additions & 28 deletions crates/hir-def/src/nameres/path_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -291,25 +292,29 @@ impl DefMap {
);
}

PerNs::types(module.into(), Visibility::Public)
PerNs::types(module.into(), Visibility::Public, None)
}
PathKind::Abs => {
// 2018-style absolute path -- only extern prelude
let segment = match segments.next() {
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
}
}
};

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
Expand Down Expand Up @@ -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),
Expand All @@ -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),
Expand Down Expand Up @@ -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(_) => {
Expand All @@ -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);
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit a17d73a

Please sign in to comment.