Skip to content

Commit 204508d

Browse files
committed
resolve: Use primitives for conditional mutability more consistently
1 parent 64d9d42 commit 204508d

File tree

5 files changed

+45
-52
lines changed

5 files changed

+45
-52
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
8787
// because they can be fetched by glob imports from those modules, and bring traits
8888
// into scope both directly and through glob imports.
8989
let key = BindingKey::new_disambiguated(ident, ns, || {
90-
// FIXME(batched): Will be fixed in batched resolution.
9190
parent.underscore_disambiguator.update_unchecked(|d| d + 1);
9291
parent.underscore_disambiguator.get()
9392
});
9493
if self
9594
.resolution_or_default(parent, key)
96-
.borrow_mut()
95+
.borrow_mut_unchecked()
9796
.non_glob_binding
9897
.replace(binding)
9998
.is_some()
@@ -499,7 +498,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
499498
if !type_ns_only || ns == TypeNS {
500499
let key = BindingKey::new(target, ns);
501500
this.resolution_or_default(current_module, key)
502-
.borrow_mut()
501+
.borrow_mut(this)
503502
.single_imports
504503
.insert(import);
505504
}

compiler/rustc_resolve/src/ident.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
891891
// the exclusive access infinite recursion will crash the compiler with stack overflow.
892892
let resolution = &*self
893893
.resolution_or_default(module, key)
894-
.try_borrow_mut()
894+
.try_borrow_mut_unchecked()
895895
.map_err(|_| (Determined, Weak::No))?;
896896

897897
// If the primary binding is unusable, search further and return the shadowed glob

compiler/rustc_resolve/src/imports.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
320320
&& (vis == import_vis
321321
|| max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx)))
322322
{
323-
// FIXME(batched): Will be fixed in batched import resolution.
324323
max_vis.set_unchecked(Some(vis.expect_local()))
325324
}
326325

@@ -350,7 +349,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
350349
// because they can be fetched by glob imports from those modules, and bring traits
351350
// into scope both directly and through glob imports.
352351
let key = BindingKey::new_disambiguated(ident, ns, || {
353-
// FIXME(batched): Will be fixed in batched resolution.
354352
module.underscore_disambiguator.update_unchecked(|d| d + 1);
355353
module.underscore_disambiguator.get()
356354
});
@@ -470,7 +468,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
470468
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
471469
// during which the resolution might end up getting re-defined via a glob cycle.
472470
let (binding, t, warn_ambiguity) = {
473-
let resolution = &mut *self.resolution_or_default(module, key).borrow_mut();
471+
let resolution = &mut *self.resolution_or_default(module, key).borrow_mut_unchecked();
474472
let old_binding = resolution.binding();
475473

476474
let t = f(self, resolution);
@@ -553,12 +551,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
553551
/// Resolves all imports for the crate. This method performs the fixed-
554552
/// point iteration.
555553
pub(crate) fn resolve_imports(&mut self) {
556-
self.assert_speculative = true;
557554
let mut prev_indeterminate_count = usize::MAX;
558555
let mut indeterminate_count = self.indeterminate_imports.len() * 3;
559556
while indeterminate_count < prev_indeterminate_count {
560557
prev_indeterminate_count = indeterminate_count;
561558
indeterminate_count = 0;
559+
self.assert_speculative = true;
562560
for import in mem::take(&mut self.indeterminate_imports) {
563561
let import_indeterminate_count = self.cm().resolve_import(import);
564562
indeterminate_count += import_indeterminate_count;
@@ -567,8 +565,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
567565
_ => self.indeterminate_imports.push(import),
568566
}
569567
}
568+
self.assert_speculative = false;
570569
}
571-
self.assert_speculative = false;
572570
}
573571

574572
pub(crate) fn finalize_imports(&mut self) {
@@ -862,15 +860,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
862860
}
863861
};
864862

865-
// FIXME(batched): Will be fixed in batched import resolution.
866863
import.imported_module.set_unchecked(Some(module));
867864
let (source, target, bindings, type_ns_only) = match import.kind {
868865
ImportKind::Single { source, target, ref bindings, type_ns_only, .. } => {
869866
(source, target, bindings, type_ns_only)
870867
}
871868
ImportKind::Glob { .. } => {
872-
// FIXME: Use mutable resolver directly as a hack, this should be an output of
873-
// speculative resolution.
874869
self.get_mut_unchecked().resolve_glob_import(import);
875870
return 0;
876871
}
@@ -906,8 +901,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
906901
}
907902
// We need the `target`, `source` can be extracted.
908903
let imported_binding = this.import(binding, import);
909-
// FIXME: Use mutable resolver directly as a hack, this should be an output of
910-
// speculative resolution.
911904
this.get_mut_unchecked().define_binding_local(
912905
parent,
913906
target,
@@ -920,8 +913,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
920913
// Don't remove underscores from `single_imports`, they were never added.
921914
if target.name != kw::Underscore {
922915
let key = BindingKey::new(target, ns);
923-
// FIXME: Use mutable resolver directly as a hack, this should be an output of
924-
// speculative resolution.
925916
this.get_mut_unchecked().update_local_resolution(
926917
parent,
927918
key,
@@ -938,7 +929,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
938929
PendingBinding::Pending
939930
}
940931
};
941-
// FIXME(batched): Will be fixed in batched import resolution.
942932
bindings[ns].set_unchecked(binding);
943933
}
944934
});

compiler/rustc_resolve/src/lib.rs

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#![recursion_limit = "256"]
2626
// tidy-alphabetical-end
2727

28-
use std::cell::{Cell, Ref, RefCell};
28+
use std::cell::Ref;
2929
use std::collections::BTreeSet;
3030
use std::fmt::{self};
3131
use std::sync::Arc;
@@ -572,7 +572,7 @@ impl BindingKey {
572572
}
573573
}
574574

575-
type Resolutions<'ra> = RefCell<FxIndexMap<BindingKey, &'ra RefCell<NameResolution<'ra>>>>;
575+
type Resolutions<'ra> = CmRefCell<FxIndexMap<BindingKey, &'ra CmRefCell<NameResolution<'ra>>>>;
576576

577577
/// One node in the tree of modules.
578578
///
@@ -595,7 +595,7 @@ struct ModuleData<'ra> {
595595
/// Resolutions in modules from other crates are not populated until accessed.
596596
lazy_resolutions: Resolutions<'ra>,
597597
/// True if this is a module from other crate that needs to be populated on access.
598-
populate_on_access: Cell<bool>, // FIXME(parallel): Use an atomic in parallel import resolution
598+
populate_on_access: CacheCell<bool>,
599599
/// Used to disambiguate underscore items (`const _: T = ...`) in the module.
600600
underscore_disambiguator: CmCell<u32>,
601601

@@ -658,7 +658,7 @@ impl<'ra> ModuleData<'ra> {
658658
parent,
659659
kind,
660660
lazy_resolutions: Default::default(),
661-
populate_on_access: Cell::new(is_foreign),
661+
populate_on_access: CacheCell::new(is_foreign),
662662
underscore_disambiguator: CmCell::new(0),
663663
unexpanded_invocations: Default::default(),
664664
no_implicit_prelude,
@@ -1034,7 +1034,7 @@ struct ExternPreludeEntry<'ra> {
10341034
/// `flag_binding` is `None`, or when `extern crate` introducing `item_binding` used renaming.
10351035
item_binding: Option<(NameBinding<'ra>, /* introduced by item */ bool)>,
10361036
/// Binding from an `--extern` flag, lazily populated on first use.
1037-
flag_binding: Option<Cell<(PendingBinding<'ra>, /* finalized */ bool)>>,
1037+
flag_binding: Option<CacheCell<(PendingBinding<'ra>, /* finalized */ bool)>>,
10381038
}
10391039

10401040
impl ExternPreludeEntry<'_> {
@@ -1045,7 +1045,7 @@ impl ExternPreludeEntry<'_> {
10451045
fn flag() -> Self {
10461046
ExternPreludeEntry {
10471047
item_binding: None,
1048-
flag_binding: Some(Cell::new((PendingBinding::Pending, false))),
1048+
flag_binding: Some(CacheCell::new((PendingBinding::Pending, false))),
10491049
}
10501050
}
10511051
}
@@ -1150,7 +1150,7 @@ pub struct Resolver<'ra, 'tcx> {
11501150
/// Eagerly populated map of all local non-block modules.
11511151
local_module_map: FxIndexMap<LocalDefId, Module<'ra>>,
11521152
/// Lazily populated cache of modules loaded from external crates.
1153-
extern_module_map: RefCell<FxIndexMap<DefId, Module<'ra>>>,
1153+
extern_module_map: CacheRefCell<FxIndexMap<DefId, Module<'ra>>>,
11541154
binding_parent_modules: FxHashMap<NameBinding<'ra>, Module<'ra>>,
11551155

11561156
/// Maps glob imports to the names of items actually imported.
@@ -1186,7 +1186,7 @@ pub struct Resolver<'ra, 'tcx> {
11861186
/// Eagerly populated map of all local macro definitions.
11871187
local_macro_map: FxHashMap<LocalDefId, &'ra MacroData>,
11881188
/// Lazily populated cache of macro definitions loaded from external crates.
1189-
extern_macro_map: RefCell<FxHashMap<DefId, &'ra MacroData>>,
1189+
extern_macro_map: CacheRefCell<FxHashMap<DefId, &'ra MacroData>>,
11901190
dummy_ext_bang: Arc<SyntaxExtension>,
11911191
dummy_ext_derive: Arc<SyntaxExtension>,
11921192
non_macro_attr: &'ra MacroData,
@@ -1197,11 +1197,10 @@ pub struct Resolver<'ra, 'tcx> {
11971197
unused_macro_rules: FxIndexMap<NodeId, DenseBitSet<usize>>,
11981198
proc_macro_stubs: FxHashSet<LocalDefId>,
11991199
/// Traces collected during macro resolution and validated when it's complete.
1200-
// FIXME: Remove interior mutability when speculative resolution produces these as outputs.
12011200
single_segment_macro_resolutions:
1202-
RefCell<Vec<(Ident, MacroKind, ParentScope<'ra>, Option<NameBinding<'ra>>, Option<Span>)>>,
1201+
CmRefCell<Vec<(Ident, MacroKind, ParentScope<'ra>, Option<NameBinding<'ra>>, Option<Span>)>>,
12031202
multi_segment_macro_resolutions:
1204-
RefCell<Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'ra>, Option<Res>, Namespace)>>,
1203+
CmRefCell<Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'ra>, Option<Res>, Namespace)>>,
12051204
builtin_attrs: Vec<(Ident, ParentScope<'ra>)>,
12061205
/// `derive(Copy)` marks items they are applied to so they are treated specially later.
12071206
/// Derive macros cannot modify the item themselves and have to store the markers in the global
@@ -1301,7 +1300,7 @@ pub struct Resolver<'ra, 'tcx> {
13011300
pub struct ResolverArenas<'ra> {
13021301
modules: TypedArena<ModuleData<'ra>>,
13031302
imports: TypedArena<ImportData<'ra>>,
1304-
name_resolutions: TypedArena<RefCell<NameResolution<'ra>>>,
1303+
name_resolutions: TypedArena<CmRefCell<NameResolution<'ra>>>,
13051304
ast_paths: TypedArena<ast::Path>,
13061305
macros: TypedArena<MacroData>,
13071306
dropless: DroplessArena,
@@ -1363,11 +1362,11 @@ impl<'ra> ResolverArenas<'ra> {
13631362
fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> {
13641363
Interned::new_unchecked(self.imports.alloc(import))
13651364
}
1366-
fn alloc_name_resolution(&'ra self) -> &'ra RefCell<NameResolution<'ra>> {
1365+
fn alloc_name_resolution(&'ra self) -> &'ra CmRefCell<NameResolution<'ra>> {
13671366
self.name_resolutions.alloc(Default::default())
13681367
}
13691368
fn alloc_macro_rules_scope(&'ra self, scope: MacroRulesScope<'ra>) -> MacroRulesScopeRef<'ra> {
1370-
self.dropless.alloc(Cell::new(scope))
1369+
self.dropless.alloc(CacheCell::new(scope))
13711370
}
13721371
fn alloc_macro_rules_binding(
13731372
&'ra self,
@@ -1978,7 +1977,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19781977

19791978
fn resolutions(&self, module: Module<'ra>) -> &'ra Resolutions<'ra> {
19801979
if module.populate_on_access.get() {
1981-
// FIXME(batched): Will be fixed in batched import resolution.
19821980
module.populate_on_access.set(false);
19831981
self.build_reduced_graph_external(module);
19841982
}
@@ -1997,9 +1995,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19971995
&self,
19981996
module: Module<'ra>,
19991997
key: BindingKey,
2000-
) -> &'ra RefCell<NameResolution<'ra>> {
1998+
) -> &'ra CmRefCell<NameResolution<'ra>> {
20011999
self.resolutions(module)
2002-
.borrow_mut()
2000+
.borrow_mut_unchecked()
20032001
.entry(key)
20042002
.or_insert_with(|| self.arenas.alloc_name_resolution())
20052003
}
@@ -2514,6 +2512,13 @@ pub fn provide(providers: &mut Providers) {
25142512
/// Prefer constructing it through [`Resolver::cm`] to ensure correctness.
25152513
type CmResolver<'r, 'ra, 'tcx> = ref_mut::RefOrMut<'r, Resolver<'ra, 'tcx>>;
25162514

2515+
// FIXME: These are cells for caches that can be populated even during speculative resolution,
2516+
// and should be replaced with mutexes, atomics, or other synchronized data when migrating to
2517+
// parallel name resolution.
2518+
use std::cell::{Cell as CacheCell, RefCell as CacheRefCell};
2519+
2520+
// FIXME: `*_unchecked` methods in the module below should be eliminated in the process
2521+
// of migration to parallel name resolution.
25172522
mod ref_mut {
25182523
use std::cell::{BorrowMutError, Cell, Ref, RefCell, RefMut};
25192524
use std::fmt;
@@ -2581,7 +2586,6 @@ mod ref_mut {
25812586
}
25822587

25832588
impl<T: Copy> Clone for CmCell<T> {
2584-
#[inline]
25852589
fn clone(&self) -> CmCell<T> {
25862590
CmCell::new(self.get())
25872591
}
@@ -2624,13 +2628,11 @@ mod ref_mut {
26242628
CmRefCell(RefCell::new(value))
26252629
}
26262630

2627-
#[inline]
26282631
#[track_caller]
26292632
pub(crate) fn borrow_mut_unchecked(&self) -> RefMut<'_, T> {
26302633
self.0.borrow_mut()
26312634
}
26322635

2633-
#[inline]
26342636
#[track_caller]
26352637
pub(crate) fn borrow_mut<'ra, 'tcx>(&self, r: &Resolver<'ra, 'tcx>) -> RefMut<'_, T> {
26362638
if r.assert_speculative {
@@ -2639,16 +2641,23 @@ mod ref_mut {
26392641
self.borrow_mut_unchecked()
26402642
}
26412643

2642-
#[inline]
26432644
#[track_caller]
26442645
pub(crate) fn try_borrow_mut_unchecked(&self) -> Result<RefMut<'_, T>, BorrowMutError> {
26452646
self.0.try_borrow_mut()
26462647
}
26472648

2648-
#[inline]
26492649
#[track_caller]
26502650
pub(crate) fn borrow(&self) -> Ref<'_, T> {
26512651
self.0.borrow()
26522652
}
26532653
}
2654+
2655+
impl<T: Default> CmRefCell<T> {
2656+
pub(crate) fn take<'ra, 'tcx>(&self, r: &Resolver<'ra, 'tcx>) -> T {
2657+
if r.assert_speculative {
2658+
panic!("Not allowed to mutate a CmRefCell during speculative resolution");
2659+
}
2660+
self.0.take()
2661+
}
2662+
}
26542663
}

compiler/rustc_resolve/src/macros.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! A bunch of methods and structures more or less related to resolving macros and
22
//! interface provided by `Resolver` to macro expander.
33
4-
use std::cell::Cell;
54
use std::mem;
65
use std::sync::Arc;
76

@@ -40,9 +39,9 @@ use crate::errors::{
4039
};
4140
use crate::imports::Import;
4241
use crate::{
43-
BindingKey, CmResolver, DeriveData, Determinacy, Finalize, InvocationParent, MacroData,
44-
ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult,
45-
ResolutionError, Resolver, ScopeSet, Segment, Used,
42+
BindingKey, CacheCell, CmResolver, DeriveData, Determinacy, Finalize, InvocationParent,
43+
MacroData, ModuleKind, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope,
44+
PathResult, ResolutionError, Resolver, ScopeSet, Segment, Used,
4645
};
4746

4847
type Res = def::Res<NodeId>;
@@ -79,7 +78,7 @@ pub(crate) enum MacroRulesScope<'ra> {
7978
/// This helps to avoid uncontrollable growth of `macro_rules!` scope chains,
8079
/// which usually grow linearly with the number of macro invocations
8180
/// in a module (including derives) and hurt performance.
82-
pub(crate) type MacroRulesScopeRef<'ra> = &'ra Cell<MacroRulesScope<'ra>>;
81+
pub(crate) type MacroRulesScopeRef<'ra> = &'ra CacheCell<MacroRulesScope<'ra>>;
8382

8483
/// Macro namespace is separated into two sub-namespaces, one for bang macros and
8584
/// one for attribute-like macros (attributes, derives).
@@ -775,8 +774,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
775774
};
776775

777776
if trace {
778-
// FIXME: Should be an output of Speculative Resolution.
779-
self.multi_segment_macro_resolutions.borrow_mut().push((
777+
self.multi_segment_macro_resolutions.borrow_mut(&self).push((
780778
path,
781779
path_span,
782780
kind,
@@ -803,8 +801,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
803801
}
804802

805803
if trace {
806-
// FIXME: Should be an output of Speculative Resolution.
807-
self.single_segment_macro_resolutions.borrow_mut().push((
804+
self.single_segment_macro_resolutions.borrow_mut(&self).push((
808805
path[0].ident,
809806
kind,
810807
*parent_scope,
@@ -870,8 +867,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
870867
}
871868
};
872869

873-
// FIXME: Should be an output of Speculative Resolution.
874-
let macro_resolutions = self.multi_segment_macro_resolutions.take();
870+
let macro_resolutions = self.multi_segment_macro_resolutions.take(self);
875871
for (mut path, path_span, kind, parent_scope, initial_res, ns) in macro_resolutions {
876872
// FIXME: Path resolution will ICE if segment IDs present.
877873
for seg in &mut path {
@@ -948,8 +944,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
948944
}
949945
}
950946

951-
// FIXME: Should be an output of Speculative Resolution.
952-
let macro_resolutions = self.single_segment_macro_resolutions.take();
947+
let macro_resolutions = self.single_segment_macro_resolutions.take(self);
953948
for (ident, kind, parent_scope, initial_binding, sugg_span) in macro_resolutions {
954949
match self.cm().resolve_ident_in_scope_set(
955950
ident,

0 commit comments

Comments
 (0)