Skip to content

Commit 445b193

Browse files
committed
resolve: Introduce separate (Local,Extern)ModuleData structures for local and external modules respectively
1 parent 99eed20 commit 445b193

2 files changed

Lines changed: 86 additions & 44 deletions

File tree

compiler/rustc_resolve/src/ident.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -643,10 +643,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
643643
Err(ControlFlow::Break(..)) => return decl,
644644
}
645645
}
646-
Scope::ModuleGlobs(module, _)
647-
if let ModuleKind::Def(_, def_id, _, _) = module.kind
648-
&& !def_id.is_local() =>
649-
{
646+
Scope::ModuleGlobs(module, _) if !module.kind.is_local() => {
650647
// Fast path: external module decoding only creates non-glob declarations.
651648
Err(Determined)
652649
}

compiler/rustc_resolve/src/lib.rs

Lines changed: 85 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ use rustc_hir::definitions::{PerParentDisambiguatorState, PerParentDisambiguator
6161
use rustc_hir::{PrimTy, TraitCandidate, find_attr};
6262
use rustc_index::bit_set::DenseBitSet;
6363
use rustc_metadata::creader::CStore;
64-
use rustc_middle::bug;
6564
use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport};
6665
use rustc_middle::middle::privacy::EffectiveVisibilities;
6766
use rustc_middle::query::Providers;
6867
use rustc_middle::ty::{
6968
self, DelegationInfo, MainDefinition, RegisteredTools, ResolverAstLowering, ResolverGlobalCtxt,
7069
TyCtxt, TyCtxtFeed, Visibility,
7170
};
71+
use rustc_middle::{bug, span_bug};
7272
use rustc_session::config::CrateType;
7373
use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
7474
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
@@ -561,6 +561,13 @@ impl ModuleKind {
561561
_ => None,
562562
}
563563
}
564+
565+
fn is_local(&self) -> bool {
566+
match self {
567+
ModuleKind::Def(_, def_id, ..) => def_id.is_local(),
568+
_ => true,
569+
}
570+
}
564571
}
565572

566573
/// Combination of a symbol and its macros 2.0 normalized hygiene context.
@@ -648,8 +655,8 @@ type Resolutions<'ra> = CmRefCell<FxIndexMap<BindingKey, &'ra CmRefCell<NameReso
648655
/// * `trait`
649656
/// * curly-braced block with statements
650657
///
651-
/// You can use [`ModuleData::kind`] to determine the kind of module this is.
652-
struct ModuleData<'ra> {
658+
/// You can use [`CommonModuleData::kind`] to determine the kind of module this is.
659+
struct CommonModuleData<'ra> {
653660
/// The direct parent module (it may not be a `mod`, however).
654661
parent: Option<Module<'ra>>,
655662
/// What kind of module this is, because this may not be a `mod`.
@@ -687,27 +694,40 @@ struct ModuleData<'ra> {
687694
self_decl: Option<Decl<'ra>>,
688695
}
689696

697+
#[derive(Hash)]
698+
struct LocalModuleData<'ra> {
699+
common: CommonModuleData<'ra>,
700+
}
701+
702+
#[derive(Hash)]
703+
struct ExternModuleData<'ra> {
704+
common: CommonModuleData<'ra>,
705+
}
706+
690707
/// All modules are unique and allocated on a same arena,
691708
/// so we can use referential equality to compare them.
692709
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
693710
#[rustc_pass_by_value]
694-
struct Module<'ra>(Interned<'ra, ModuleData<'ra>>);
711+
enum Module<'ra> {
712+
Local(LocalModule<'ra>),
713+
Extern(ExternModule<'ra>),
714+
}
695715

696716
/// Same as `Module`, but is guaranteed to be from the current crate.
697717
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
698718
#[rustc_pass_by_value]
699-
struct LocalModule<'ra>(Interned<'ra, ModuleData<'ra>>);
719+
struct LocalModule<'ra>(Interned<'ra, LocalModuleData<'ra>>);
700720

701721
/// Same as `Module`, but is guaranteed to be from an external crate.
702722
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
703723
#[rustc_pass_by_value]
704-
struct ExternModule<'ra>(Interned<'ra, ModuleData<'ra>>);
724+
struct ExternModule<'ra>(Interned<'ra, ExternModuleData<'ra>>);
705725

706726
// Allows us to use Interned without actually enforcing (via Hash/PartialEq/...) uniqueness of the
707727
// contained data.
708728
// FIXME: We may wish to actually have at least debug-level assertions that Interned's guarantees
709729
// are upheld.
710-
impl std::hash::Hash for ModuleData<'_> {
730+
impl std::hash::Hash for CommonModuleData<'_> {
711731
fn hash<H>(&self, _: &mut H)
712732
where
713733
H: std::hash::Hasher,
@@ -716,7 +736,7 @@ impl std::hash::Hash for ModuleData<'_> {
716736
}
717737
}
718738

719-
impl<'ra> ModuleData<'ra> {
739+
impl<'ra> CommonModuleData<'ra> {
720740
fn new(
721741
parent: Option<Module<'ra>>,
722742
kind: ModuleKind,
@@ -725,11 +745,8 @@ impl<'ra> ModuleData<'ra> {
725745
no_implicit_prelude: bool,
726746
self_decl: Option<Decl<'ra>>,
727747
) -> Self {
728-
let is_foreign = match kind {
729-
ModuleKind::Def(_, def_id, _, _) => !def_id.is_local(),
730-
ModuleKind::Block => false,
731-
};
732-
ModuleData {
748+
let is_foreign = !kind.is_local();
749+
CommonModuleData {
733750
parent,
734751
kind,
735752
lazy_resolutions: Default::default(),
@@ -751,7 +768,7 @@ impl<'ra> ModuleData<'ra> {
751768
}
752769

753770
fn def_id(&self) -> DefId {
754-
self.opt_def_id().expect("`ModuleData::def_id` is called on a block module")
771+
self.opt_def_id().expect("`CommonModuleData::def_id` is called on a block module")
755772
}
756773

757774
fn res(&self) -> Option<Res> {
@@ -860,61 +877,76 @@ impl<'ra> Module<'ra> {
860877

861878
#[track_caller]
862879
fn expect_local(self) -> LocalModule<'ra> {
863-
match self.kind {
864-
ModuleKind::Def(_, def_id, _, _) if !def_id.is_local() => {
865-
panic!("`Module::expect_local` is called on a non-local module: {self:?}")
866-
}
867-
ModuleKind::Def(..) | ModuleKind::Block => LocalModule(self.0),
880+
match self {
881+
Module::Local(m) => m,
882+
Module::Extern(m) => span_bug!(m.span, "unexpected extern module: {m:?}"),
868883
}
869884
}
870885

871886
#[track_caller]
872887
fn expect_extern(self) -> ExternModule<'ra> {
873-
match self.kind {
874-
ModuleKind::Def(_, def_id, _, _) if !def_id.is_local() => ExternModule(self.0),
875-
ModuleKind::Def(..) | ModuleKind::Block => {
876-
panic!("`Module::expect_extern` is called on a local module: {self:?}")
877-
}
888+
match self {
889+
Module::Extern(m) => m,
890+
Module::Local(m) => span_bug!(m.span, "unexpected local module: {m:?}"),
878891
}
879892
}
880893
}
881894

882895
impl<'ra> LocalModule<'ra> {
883896
fn to_module(self) -> Module<'ra> {
884-
Module(self.0)
897+
Module::Local(self)
885898
}
886899
}
887900

888901
impl<'ra> ExternModule<'ra> {
889902
fn to_module(self) -> Module<'ra> {
890-
Module(self.0)
903+
Module::Extern(self)
891904
}
892905
}
893906

894907
impl<'ra> std::ops::Deref for Module<'ra> {
895-
type Target = ModuleData<'ra>;
908+
type Target = CommonModuleData<'ra>;
896909

897910
fn deref(&self) -> &Self::Target {
898-
&self.0
911+
match self {
912+
Module::Local(m) => &m.common,
913+
Module::Extern(m) => &m.common,
914+
}
899915
}
900916
}
901917

902918
impl<'ra> std::ops::Deref for LocalModule<'ra> {
903-
type Target = ModuleData<'ra>;
919+
type Target = LocalModuleData<'ra>;
904920

905921
fn deref(&self) -> &Self::Target {
906922
&self.0
907923
}
908924
}
909925

926+
impl<'ra> std::ops::Deref for LocalModuleData<'ra> {
927+
type Target = CommonModuleData<'ra>;
928+
929+
fn deref(&self) -> &Self::Target {
930+
&self.common
931+
}
932+
}
933+
910934
impl<'ra> std::ops::Deref for ExternModule<'ra> {
911-
type Target = ModuleData<'ra>;
935+
type Target = ExternModuleData<'ra>;
912936

913937
fn deref(&self) -> &Self::Target {
914938
&self.0
915939
}
916940
}
917941

942+
impl<'ra> std::ops::Deref for ExternModuleData<'ra> {
943+
type Target = CommonModuleData<'ra>;
944+
945+
fn deref(&self) -> &Self::Target {
946+
&self.common
947+
}
948+
}
949+
918950
impl<'ra> fmt::Debug for Module<'ra> {
919951
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
920952
match self.kind {
@@ -930,6 +962,12 @@ impl<'ra> fmt::Debug for LocalModule<'ra> {
930962
}
931963
}
932964

965+
impl<'ra> fmt::Debug for ExternModule<'ra> {
966+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
967+
self.to_module().fmt(f)
968+
}
969+
}
970+
933971
/// Data associated with any name declaration.
934972
#[derive(Clone, Debug)]
935973
struct DeclData<'ra> {
@@ -1504,7 +1542,8 @@ pub struct Resolver<'ra, 'tcx> {
15041542
/// used by many types in this crate is an abbreviation of `ResolverArenas`.
15051543
#[derive(Default)]
15061544
pub struct ResolverArenas<'ra> {
1507-
modules: TypedArena<ModuleData<'ra>>,
1545+
local_modules: TypedArena<LocalModuleData<'ra>>,
1546+
extern_modules: TypedArena<ExternModuleData<'ra>>,
15081547
imports: TypedArena<ImportData<'ra>>,
15091548
name_resolutions: TypedArena<CmRefCell<NameResolution<'ra>>>,
15101549
ast_paths: TypedArena<ast::Path>,
@@ -1554,14 +1593,17 @@ impl<'ra> ResolverArenas<'ra> {
15541593
}
15551594
ModuleKind::Block => None,
15561595
};
1557-
Module(Interned::new_unchecked(self.modules.alloc(ModuleData::new(
1558-
parent,
1559-
kind,
1560-
expn_id,
1561-
span,
1562-
no_implicit_prelude,
1563-
self_decl,
1564-
))))
1596+
let common =
1597+
CommonModuleData::new(parent, kind, expn_id, span, no_implicit_prelude, self_decl);
1598+
if common.kind.is_local() {
1599+
Module::Local(LocalModule(Interned::new_unchecked(
1600+
self.local_modules.alloc(LocalModuleData { common }),
1601+
)))
1602+
} else {
1603+
Module::Extern(ExternModule(Interned::new_unchecked(
1604+
self.extern_modules.alloc(ExternModuleData { common }),
1605+
)))
1606+
}
15651607
}
15661608
fn alloc_decl(&'ra self, data: DeclData<'ra>) -> Decl<'ra> {
15671609
Interned::new_unchecked(self.dropless.alloc(data))
@@ -2149,7 +2191,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21492191
module.populate_on_access.set(false);
21502192
self.build_reduced_graph_external(module.expect_extern());
21512193
}
2152-
&module.0.0.lazy_resolutions
2194+
match module {
2195+
Module::Local(m) => &m.0.0.lazy_resolutions,
2196+
Module::Extern(m) => &m.0.0.lazy_resolutions,
2197+
}
21532198
}
21542199

21552200
fn resolution(

0 commit comments

Comments
 (0)