Skip to content

Commit a17d73a

Browse files
committed
Thread imports through the resolver
1 parent c4e9b5a commit a17d73a

File tree

15 files changed

+218
-131
lines changed

15 files changed

+218
-131
lines changed

crates/hir-def/src/item_scope.rs

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub enum ImportOrExternCrate {
3434
}
3535

3636
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
37-
pub enum ImportType {
37+
pub(crate) enum ImportType {
3838
Import(ImportId),
3939
Glob(UseId),
4040
ExternCrate(ExternCrateId),
@@ -118,7 +118,7 @@ struct DeriveMacroInvocation {
118118
pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
119119
BuiltinType::ALL
120120
.iter()
121-
.map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public)))
121+
.map(|(name, ty)| (name.clone(), PerNs::types((*ty).into(), Visibility::Public, None)))
122122
.collect()
123123
});
124124

@@ -234,9 +234,16 @@ impl ItemScope {
234234

235235
pub(crate) fn resolutions(&self) -> impl Iterator<Item = (Option<Name>, PerNs)> + '_ {
236236
self.entries().map(|(name, res)| (Some(name.clone()), res)).chain(
237-
self.unnamed_trait_imports
238-
.iter()
239-
.map(|(tr, (vis, _))| (None, PerNs::types(ModuleDefId::TraitId(*tr), *vis))),
237+
self.unnamed_trait_imports.iter().map(|(tr, (vis, i))| {
238+
(
239+
None,
240+
PerNs::types(
241+
ModuleDefId::TraitId(*tr),
242+
*vis,
243+
i.map(ImportOrExternCrate::Import),
244+
),
245+
)
246+
}),
240247
)
241248
}
242249
}
@@ -327,11 +334,13 @@ impl ItemScope {
327334
})
328335
}
329336

337+
// FIXME: This is only used in collection, we should move the relevant parts of it out of ItemScope
330338
pub(crate) fn unnamed_trait_vis(&self, tr: TraitId) -> Option<Visibility> {
331339
self.unnamed_trait_imports.get(&tr).copied().map(|(a, _)| a)
332340
}
333341

334342
pub(crate) fn push_unnamed_trait(&mut self, tr: TraitId, vis: Visibility) {
343+
// FIXME: import
335344
self.unnamed_trait_imports.insert(tr, (vis, None));
336345
}
337346

@@ -344,6 +353,8 @@ impl ItemScope {
344353
) -> bool {
345354
let mut changed = false;
346355

356+
// FIXME: Document and simplify this
357+
347358
if let Some(mut fld) = def.types {
348359
let existing = self.types.entry(lookup.1.clone());
349360
match existing {
@@ -626,28 +637,39 @@ impl ItemScope {
626637
}
627638

628639
impl PerNs {
629-
pub(crate) fn from_def(def: ModuleDefId, v: Visibility, has_constructor: bool) -> PerNs {
640+
pub(crate) fn from_def(
641+
def: ModuleDefId,
642+
v: Visibility,
643+
has_constructor: bool,
644+
import: Option<ImportOrExternCrate>,
645+
) -> PerNs {
630646
match def {
631-
ModuleDefId::ModuleId(_) => PerNs::types(def, v),
632-
ModuleDefId::FunctionId(_) => PerNs::values(def, v),
647+
ModuleDefId::ModuleId(_) => PerNs::types(def, v, import),
648+
ModuleDefId::FunctionId(_) => {
649+
PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
650+
}
633651
ModuleDefId::AdtId(adt) => match adt {
634-
AdtId::UnionId(_) => PerNs::types(def, v),
635-
AdtId::EnumId(_) => PerNs::types(def, v),
652+
AdtId::UnionId(_) => PerNs::types(def, v, import),
653+
AdtId::EnumId(_) => PerNs::types(def, v, import),
636654
AdtId::StructId(_) => {
637655
if has_constructor {
638-
PerNs::both(def, def, v)
656+
PerNs::both(def, def, v, import)
639657
} else {
640-
PerNs::types(def, v)
658+
PerNs::types(def, v, import)
641659
}
642660
}
643661
},
644-
ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v),
645-
ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def, v),
646-
ModuleDefId::TraitId(_) => PerNs::types(def, v),
647-
ModuleDefId::TraitAliasId(_) => PerNs::types(def, v),
648-
ModuleDefId::TypeAliasId(_) => PerNs::types(def, v),
649-
ModuleDefId::BuiltinType(_) => PerNs::types(def, v),
650-
ModuleDefId::MacroId(mac) => PerNs::macros(mac, v),
662+
ModuleDefId::EnumVariantId(_) => PerNs::both(def, def, v, import),
663+
ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => {
664+
PerNs::values(def, v, import.and_then(ImportOrExternCrate::into_import))
665+
}
666+
ModuleDefId::TraitId(_) => PerNs::types(def, v, import),
667+
ModuleDefId::TraitAliasId(_) => PerNs::types(def, v, import),
668+
ModuleDefId::TypeAliasId(_) => PerNs::types(def, v, import),
669+
ModuleDefId::BuiltinType(_) => PerNs::types(def, v, import),
670+
ModuleDefId::MacroId(mac) => {
671+
PerNs::macros(mac, v, import.and_then(ImportOrExternCrate::into_import))
672+
}
651673
}
652674
}
653675
}

crates/hir-def/src/macro_expansion_tests/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
131131
.as_call_id_with_errors(&db, krate, |path| {
132132
resolver
133133
.resolve_path_as_macro(&db, &path, Some(MacroSubNs::Bang))
134-
.map(|it| macro_id_to_def_id(&db, it))
134+
.map(|(it, _)| macro_id_to_def_id(&db, it))
135135
})
136136
.unwrap();
137137
let macro_call_id = res.value.unwrap();

crates/hir-def/src/nameres/collector.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ impl DefCollector<'_> {
648648
self.def_map.modules[module_id].scope.declare(macro_.into());
649649
self.update(
650650
module_id,
651-
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
651+
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
652652
Visibility::Public,
653653
None,
654654
);
@@ -684,7 +684,7 @@ impl DefCollector<'_> {
684684
self.def_map.modules[module_id].scope.declare(macro_.into());
685685
self.update(
686686
module_id,
687-
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
687+
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
688688
vis,
689689
None,
690690
);
@@ -699,7 +699,7 @@ impl DefCollector<'_> {
699699
self.def_map.modules[module_id].scope.declare(macro_.into());
700700
self.update(
701701
module_id,
702-
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public))],
702+
&[(Some(name), PerNs::macros(macro_.into(), Visibility::Public, None))],
703703
Visibility::Public,
704704
None,
705705
);
@@ -783,6 +783,7 @@ impl DefCollector<'_> {
783783
Some(res) => PartialResolvedImport::Resolved(PerNs::types(
784784
res.into(),
785785
Visibility::Public,
786+
None,
786787
)),
787788
None => PartialResolvedImport::Unresolved,
788789
}
@@ -967,7 +968,7 @@ impl DefCollector<'_> {
967968
.map(|(local_id, variant_data)| {
968969
let name = variant_data.name.clone();
969970
let variant = EnumVariantId { parent: e, local_id };
970-
let res = PerNs::both(variant.into(), variant.into(), vis);
971+
let res = PerNs::both(variant.into(), variant.into(), vis, None);
971972
(Some(name), res)
972973
})
973974
.collect::<Vec<_>>();
@@ -1547,7 +1548,7 @@ impl ModCollector<'_, '_> {
15471548
def_collector.def_map.modules[module_id].scope.declare(id);
15481549
def_collector.update(
15491550
module_id,
1550-
&[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
1551+
&[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor, None))],
15511552
vis,
15521553
None,
15531554
)
@@ -1977,7 +1978,7 @@ impl ModCollector<'_, '_> {
19771978
def_map.modules[self.module_id].scope.declare(def);
19781979
self.def_collector.update(
19791980
self.module_id,
1980-
&[(Some(name), PerNs::from_def(def, vis, false))],
1981+
&[(Some(name), PerNs::from_def(def, vis, false, None))],
19811982
vis,
19821983
None,
19831984
);

crates/hir-def/src/nameres/path_resolution.rs

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ use hir_expand::name::Name;
1515
use triomphe::Arc;
1616

1717
use crate::{
18+
data::adt::VariantData,
1819
db::DefDatabase,
19-
item_scope::BUILTIN_SCOPE,
20+
item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},
2021
nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},
2122
path::{ModPath, PathKind},
2223
per_ns::PerNs,
@@ -196,15 +197,15 @@ impl DefMap {
196197
PathKind::DollarCrate(krate) => {
197198
if krate == self.krate {
198199
cov_mark::hit!(macro_dollar_crate_self);
199-
PerNs::types(self.crate_root().into(), Visibility::Public)
200+
PerNs::types(self.crate_root().into(), Visibility::Public, None)
200201
} else {
201202
let def_map = db.crate_def_map(krate);
202203
let module = def_map.module_id(Self::ROOT);
203204
cov_mark::hit!(macro_dollar_crate_other);
204-
PerNs::types(module.into(), Visibility::Public)
205+
PerNs::types(module.into(), Visibility::Public, None)
205206
}
206207
}
207-
PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public),
208+
PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public, None),
208209
// plain import or absolute path in 2015: crate-relative with
209210
// fallback to extern prelude (with the simplification in
210211
// rust-lang/rust#57745)
@@ -291,25 +292,29 @@ impl DefMap {
291292
);
292293
}
293294

294-
PerNs::types(module.into(), Visibility::Public)
295+
PerNs::types(module.into(), Visibility::Public, None)
295296
}
296297
PathKind::Abs => {
297298
// 2018-style absolute path -- only extern prelude
298299
let segment = match segments.next() {
299300
Some((_, segment)) => segment,
300301
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
301302
};
302-
if let Some(&(def, _extern_crate)) = self.data.extern_prelude.get(segment) {
303+
if let Some(&(def, extern_crate)) = self.data.extern_prelude.get(segment) {
303304
tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def);
304-
PerNs::types(def.into(), Visibility::Public)
305+
PerNs::types(
306+
def.into(),
307+
Visibility::Public,
308+
extern_crate.map(ImportOrExternCrate::ExternCrate),
309+
)
305310
} else {
306311
return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
307312
}
308313
}
309314
};
310315

311316
for (i, segment) in segments {
312-
let (curr, vis) = match curr_per_ns.take_types_vis() {
317+
let (curr, vis, imp) = match curr_per_ns.take_types_full() {
313318
Some(r) => r,
314319
None => {
315320
// we still have path segments left, but the path so far
@@ -364,18 +369,20 @@ impl DefMap {
364369
Some(local_id) => {
365370
let variant = EnumVariantId { parent: e, local_id };
366371
match &*enum_data.variants[local_id].variant_data {
367-
crate::data::adt::VariantData::Record(_) => {
368-
PerNs::types(variant.into(), Visibility::Public)
369-
}
370-
crate::data::adt::VariantData::Tuple(_)
371-
| crate::data::adt::VariantData::Unit => {
372-
PerNs::both(variant.into(), variant.into(), Visibility::Public)
372+
VariantData::Record(_) => {
373+
PerNs::types(variant.into(), Visibility::Public, None)
373374
}
375+
VariantData::Tuple(_) | VariantData::Unit => PerNs::both(
376+
variant.into(),
377+
variant.into(),
378+
Visibility::Public,
379+
None,
380+
),
374381
}
375382
}
376383
None => {
377384
return ResolvePathResult::with(
378-
PerNs::types(e.into(), vis),
385+
PerNs::types(e.into(), vis, imp),
379386
ReachedFixedPoint::Yes,
380387
Some(i),
381388
Some(self.krate),
@@ -393,7 +400,7 @@ impl DefMap {
393400
);
394401

395402
return ResolvePathResult::with(
396-
PerNs::types(s, vis),
403+
PerNs::types(s, vis, imp),
397404
ReachedFixedPoint::Yes,
398405
Some(i),
399406
Some(self.krate),
@@ -430,7 +437,7 @@ impl DefMap {
430437
.filter(|&id| {
431438
sub_namespace_match(Some(MacroSubNs::from_id(db, id)), expected_macro_subns)
432439
})
433-
.map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public));
440+
.map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public, None));
434441
let from_scope = self[module].scope.get(name).filter_macro(db, expected_macro_subns);
435442
let from_builtin = match self.block {
436443
Some(_) => {
@@ -449,16 +456,26 @@ impl DefMap {
449456

450457
let extern_prelude = || {
451458
if self.block.is_some() {
452-
// Don't resolve extern prelude in block `DefMap`s.
459+
// Don't resolve extern prelude in block `DefMap`s, defer it to the crate def map so
460+
// that blocks can properly shadow them
453461
return PerNs::none();
454462
}
455-
self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
456-
PerNs::types(it.into(), Visibility::Public)
463+
self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {
464+
PerNs::types(
465+
it.into(),
466+
Visibility::Public,
467+
extern_crate.map(ImportOrExternCrate::ExternCrate),
468+
)
457469
})
458470
};
459471
let macro_use_prelude = || {
460472
self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
461-
PerNs::macros(it.into(), Visibility::Public)
473+
PerNs::macros(
474+
it.into(),
475+
Visibility::Public,
476+
// FIXME?
477+
None, // extern_crate.map(ImportOrExternCrate::ExternCrate),
478+
)
462479
})
463480
};
464481
let prelude = || self.resolve_in_prelude(db, name);
@@ -487,13 +504,16 @@ impl DefMap {
487504
// Don't resolve extern prelude in block `DefMap`s.
488505
return PerNs::none();
489506
}
490-
self.data
491-
.extern_prelude
492-
.get(name)
493-
.copied()
494-
.map_or(PerNs::none(), |(it, _extern_crate)| {
495-
PerNs::types(it.into(), Visibility::Public)
496-
})
507+
self.data.extern_prelude.get(name).copied().map_or(
508+
PerNs::none(),
509+
|(it, extern_crate)| {
510+
PerNs::types(
511+
it.into(),
512+
Visibility::Public,
513+
extern_crate.map(ImportOrExternCrate::ExternCrate),
514+
)
515+
},
516+
)
497517
};
498518

499519
from_crate_root.or_else(from_extern_prelude)

0 commit comments

Comments
 (0)