Skip to content

Commit 74c18d6

Browse files
refactor ImportResolutionOutputs to use SideEffect
1 parent fd413a3 commit 74c18d6

File tree

1 file changed

+104
-68
lines changed

1 file changed

+104
-68
lines changed

compiler/rustc_resolve/src/imports.rs

Lines changed: 104 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::mem;
55
use std::ops::Deref;
66

77
use rustc_ast::NodeId;
8-
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
8+
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
99
use rustc_data_structures::intern::Interned;
1010
use rustc_errors::codes::*;
1111
use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err};
@@ -47,59 +47,89 @@ struct ImportResolver<'r, 'ra, 'tcx> {
4747
outputs: ImportResolutionOutputs<'ra>,
4848
}
4949

50+
enum SideEffect<'ra> {
51+
None,
52+
Prelude,
53+
Single {
54+
parent: Module<'ra>,
55+
import_bindings: PerNS<PendingBinding<'ra>>,
56+
},
57+
Glob {
58+
parent: Module<'ra>,
59+
import_bindings: Vec<(NameBinding<'ra>, BindingKey, bool /* warn_ambiguity */)>,
60+
path_res: PartialRes,
61+
},
62+
}
63+
5064
#[derive(Default)]
5165
struct ImportResolutionOutputs<'ra> {
52-
prelude: Option<Module<'ra>>,
5366
indeterminate_imports: Vec<Import<'ra>>,
54-
determined_imports: Vec<Import<'ra>>,
55-
module_glob_importers: FxIndexMap<Module<'ra>, Vec<Import<'ra>>>,
56-
glob_import_bindings:
57-
Vec<(Module<'ra>, BindingKey, NameBinding<'ra>, bool /* warn_ambiguity */)>,
58-
glob_path_res: Vec<(NodeId, PartialRes)>,
59-
single_import_bindings: PerNS<Vec<(Module<'ra>, Import<'ra>, PendingBinding<'ra>)>>,
67+
determined_imports: Vec<(Import<'ra>, SideEffect<'ra>)>,
6068
}
6169

6270
impl<'ra> ImportResolutionOutputs<'ra> {
6371
fn commit<'tcx>(self, r: &mut Resolver<'ra, 'tcx>) {
6472
r.indeterminate_imports = self.indeterminate_imports;
65-
r.determined_imports.extend(self.determined_imports);
66-
67-
// It's possible this particular round didn't set the prelude, so we should not
68-
// unset it in the main resolver.
69-
if self.prelude.is_some() {
70-
r.prelude = self.prelude;
71-
}
72-
73-
for (module, glob_importers) in self.module_glob_importers {
74-
module.glob_importers.borrow_mut().extend(glob_importers);
75-
}
76-
77-
for (module, key, binding, warn_ambiguity) in self.glob_import_bindings {
78-
let _ = r.try_define_local(module, key.ident.0, key.ns, binding, warn_ambiguity);
79-
}
73+
r.determined_imports.reserve(self.determined_imports.len());
74+
75+
for (import, side_effect) in self.determined_imports {
76+
r.determined_imports.push(import);
77+
78+
match (&import.kind, side_effect) {
79+
(
80+
ImportKind::Single { target, bindings, .. },
81+
SideEffect::Single { parent, import_bindings },
82+
) => {
83+
for (ns, pending_binding) in import_bindings.into_iter_with() {
84+
match pending_binding {
85+
PendingBinding::Ready(Some(binding)) => {
86+
r.define_binding_local(parent, *target, ns, binding);
87+
}
88+
PendingBinding::Ready(None) => {
89+
let key = BindingKey::new(*target, ns);
90+
r.update_local_resolution(parent, key, false, |_, resolution| {
91+
resolution.single_imports.swap_remove(&import);
92+
});
93+
}
94+
_ => {}
95+
}
96+
bindings[ns].set(pending_binding);
97+
}
98+
}
99+
(
100+
ImportKind::Glob { id, .. },
101+
SideEffect::Glob { parent, import_bindings, path_res },
102+
) => {
103+
let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap()
104+
else {
105+
unreachable!();
106+
};
80107

81-
for (id, res) in self.glob_path_res {
82-
r.record_partial_res(id, res);
83-
}
108+
module.glob_importers.borrow_mut().push(import);
84109

85-
for (ns, import_bindings) in self.single_import_bindings.into_iter_with() {
86-
for (parent, import, pending_binding) in import_bindings {
87-
let ImportKind::Single { target, ref bindings, .. } = import.kind else {
88-
unreachable!();
89-
};
90-
match pending_binding {
91-
PendingBinding::Ready(Some(binding)) => {
92-
r.define_binding_local(parent, target, ns, binding);
93-
}
94-
PendingBinding::Ready(None) => {
95-
let key = BindingKey::new(target, ns);
96-
r.update_local_resolution(parent, key, false, |_, resolution| {
97-
resolution.single_imports.swap_remove(&import);
98-
});
110+
for (binding, key, warn_ambiguity) in import_bindings {
111+
let _ = r.try_define_local(
112+
parent,
113+
key.ident.0,
114+
key.ns,
115+
binding,
116+
warn_ambiguity,
117+
);
99118
}
100-
_ => {}
119+
120+
r.record_partial_res(*id, path_res);
101121
}
102-
bindings[ns].set(pending_binding);
122+
(ImportKind::Glob { is_prelude: true, .. }, SideEffect::Prelude) => {
123+
let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap()
124+
else {
125+
unreachable!()
126+
};
127+
r.prelude = Some(module);
128+
}
129+
130+
(_, SideEffect::None) => {}
131+
// Something weird happened, which shouldn't have happened.
132+
_ => unreachable!("Mismatched import kind and side effect"),
103133
}
104134
}
105135
}
@@ -650,10 +680,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
650680
) -> (ImportResolutionOutputs<'ra>, usize) {
651681
let mut indeterminate_count = 0;
652682
for import in batch {
653-
let import_indeterminate_count = self.resolve_import(import);
683+
let (side_effect, import_indeterminate_count) = self.resolve_import(import);
654684
indeterminate_count += import_indeterminate_count;
655685
match import_indeterminate_count {
656-
0 => self.outputs.determined_imports.push(import),
686+
0 => self.outputs.determined_imports.push((import, side_effect)),
657687
_ => self.outputs.indeterminate_imports.push(import),
658688
}
659689
}
@@ -930,7 +960,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
930960
///
931961
/// Meanwhile, if resolve successful, the resolved bindings are written
932962
/// into the module.
933-
fn resolve_import<'r>(self: &mut ImportResolver<'r, 'ra, 'tcx>, import: Import<'ra>) -> usize {
963+
fn resolve_import<'r>(
964+
self: &mut ImportResolver<'r, 'ra, 'tcx>,
965+
import: Import<'ra>,
966+
) -> (SideEffect<'ra>, usize) {
934967
debug!(
935968
"(resolving import for module) resolving import `{}::{}` in `{}`",
936969
Segment::names_to_string(&import.module_path),
@@ -949,8 +982,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
949982

950983
match path_res {
951984
PathResult::Module(module) => module,
952-
PathResult::Indeterminate => return 3,
953-
PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
985+
PathResult::Indeterminate => return (SideEffect::None, 3),
986+
PathResult::NonModule(..) | PathResult::Failed { .. } => {
987+
return (SideEffect::None, 0);
988+
}
954989
}
955990
};
956991

@@ -960,12 +995,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
960995
(source, target, bindings, type_ns_only)
961996
}
962997
ImportKind::Glob { .. } => {
963-
self.resolve_glob_import(import);
964-
return 0;
998+
return (self.resolve_glob_import(import), 0);
965999
}
9661000
_ => unreachable!(),
9671001
};
9681002

1003+
let mut import_bindings = PerNS::default();
9691004
let mut indeterminate_count = 0;
9701005
self.r.reborrow().per_ns_cm(|this, ns| {
9711006
if !type_ns_only || ns == TypeNS {
@@ -979,7 +1014,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
9791014
&import.parent_scope,
9801015
Some(import),
9811016
);
982-
let parent = import.parent_scope.module;
9831017
let pending_binding = match binding_result {
9841018
Ok(binding) => {
9851019
if binding.is_assoc_item()
@@ -1009,11 +1043,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10091043
return;
10101044
}
10111045
};
1012-
self.outputs.single_import_bindings[ns].push((parent, import, pending_binding));
1046+
import_bindings[ns] = pending_binding;
10131047
}
10141048
});
10151049

1016-
indeterminate_count
1050+
(
1051+
SideEffect::Single { parent: import.parent_scope.module, import_bindings },
1052+
indeterminate_count,
1053+
)
10171054
}
10181055

10191056
/// Performs final import resolution, consistency checks and error reporting.
@@ -1554,13 +1591,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15541591
false
15551592
}
15561593

1557-
fn resolve_glob_import<'r>(self: &mut ImportResolver<'r, 'ra, 'tcx>, import: Import<'ra>) {
1594+
fn resolve_glob_import<'r>(
1595+
self: &mut ImportResolver<'r, 'ra, 'tcx>,
1596+
import: Import<'ra>,
1597+
) -> SideEffect<'ra> {
15581598
// This function is only called for glob imports.
1559-
let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
1599+
let ImportKind::Glob { is_prelude, .. } = import.kind else { unreachable!() };
15601600

15611601
let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else {
15621602
self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span });
1563-
return;
1603+
return SideEffect::None;
15641604
};
15651605

15661606
if module.is_trait() && !self.tcx.features().import_trait_associated_functions() {
@@ -1574,15 +1614,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15741614
}
15751615

15761616
if module == import.parent_scope.module {
1577-
return;
1617+
return SideEffect::None;
15781618
} else if is_prelude {
1579-
self.outputs.prelude = Some(module);
1580-
return;
1619+
return SideEffect::Prelude;
15811620
}
15821621

1583-
// Add to module's glob_importers
1584-
self.outputs.module_glob_importers.entry(module).or_default().push(import);
1585-
15861622
// Ensure that `resolutions` isn't borrowed during `try_define`,
15871623
// since it might get updated via a glob cycle.
15881624
let bindings = self
@@ -1593,6 +1629,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15931629
resolution.borrow().binding().map(|binding| (*key, binding))
15941630
})
15951631
.collect::<Vec<_>>();
1632+
let mut import_bindings = Vec::with_capacity(bindings.len());
15961633
for (mut key, binding) in bindings {
15971634
let scope = match key.ident.0.span.reverse_glob_adjust(module.expansion, import.span) {
15981635
Some(Some(def)) => self.expn_def_scope(def),
@@ -1605,17 +1642,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
16051642
.resolution(import.parent_scope.module, key)
16061643
.and_then(|r| r.binding())
16071644
.is_some_and(|binding| binding.warn_ambiguity_recursive());
1608-
self.outputs.glob_import_bindings.push((
1609-
import.parent_scope.module,
1610-
key,
1611-
imported_binding,
1612-
warn_ambiguity,
1613-
));
1645+
import_bindings.push((imported_binding, key, warn_ambiguity));
16141646
}
16151647
}
16161648

16171649
// Record the destination of this import
1618-
self.outputs.glob_path_res.push((id, PartialRes::new(module.res().unwrap())));
1650+
SideEffect::Glob {
1651+
parent: import.parent_scope.module,
1652+
import_bindings,
1653+
path_res: PartialRes::new(module.res().unwrap()),
1654+
}
16191655
}
16201656

16211657
// Miscellaneous post-processing, including recording re-exports,

0 commit comments

Comments
 (0)