Skip to content

Commit 514467b

Browse files
Introduce and use CmCell during import resolution.
1 parent 0d6a806 commit 514467b

File tree

3 files changed

+88
-28
lines changed

3 files changed

+88
-28
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
//! unexpanded macros in the fragment are visited and registered.
66
//! Imports are also considered items and placed into modules here, but not resolved yet.
77
8-
use std::cell::Cell;
98
use std::sync::Arc;
109

1110
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
@@ -36,9 +35,9 @@ use crate::def_collector::collect_definitions;
3635
use crate::imports::{ImportData, ImportKind};
3736
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
3837
use crate::{
39-
BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot,
40-
NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, Used,
41-
VisResolutionError, errors,
38+
BindingKey, CmCell, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind,
39+
ModuleOrUniformRoot, NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment,
40+
Used, VisResolutionError, errors,
4241
};
4342

4443
type Res = def::Res<NodeId>;
@@ -87,7 +86,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
8786
// because they can be fetched by glob imports from those modules, and bring traits
8887
// into scope both directly and through glob imports.
8988
let key = BindingKey::new_disambiguated(ident, ns, || {
90-
parent.underscore_disambiguator.update(|d| d + 1);
89+
// FIXME(batched): Will be fixed in batched resolution.
90+
parent.underscore_disambiguator.update_unchecked(|d| d + 1);
9191
parent.underscore_disambiguator.get()
9292
});
9393
if self
@@ -477,7 +477,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
477477
kind,
478478
parent_scope: self.parent_scope,
479479
module_path,
480-
imported_module: Cell::new(None),
480+
imported_module: CmCell::new(None),
481481
span,
482482
use_span: item.span,
483483
use_span_with_attributes: item.span_with_attributes(),
@@ -668,7 +668,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
668668
}
669669
ast::UseTreeKind::Glob => {
670670
if !ast::attr::contains_name(&item.attrs, sym::prelude_import) {
671-
let kind = ImportKind::Glob { max_vis: Cell::new(None), id };
671+
let kind = ImportKind::Glob { max_vis: CmCell::new(None), id };
672672
self.add_import(prefix, kind, use_tree.span, item, root_span, item.id, vis);
673673
} else {
674674
// Resolve the prelude import early.
@@ -971,7 +971,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
971971
kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
972972
root_id: item.id,
973973
parent_scope: self.parent_scope,
974-
imported_module: Cell::new(module),
974+
imported_module: CmCell::new(module),
975975
has_attributes: !item.attrs.is_empty(),
976976
use_span_with_attributes: item.span_with_attributes(),
977977
use_span: item.span,
@@ -1103,7 +1103,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
11031103
kind: ImportKind::MacroUse { warn_private },
11041104
root_id: item.id,
11051105
parent_scope: this.parent_scope,
1106-
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
1106+
imported_module: CmCell::new(Some(ModuleOrUniformRoot::Module(module))),
11071107
use_span_with_attributes: item.span_with_attributes(),
11081108
has_attributes: !item.attrs.is_empty(),
11091109
use_span: item.span,
@@ -1274,7 +1274,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
12741274
kind: ImportKind::MacroExport,
12751275
root_id: item.id,
12761276
parent_scope: self.parent_scope,
1277-
imported_module: Cell::new(None),
1277+
imported_module: CmCell::new(None),
12781278
has_attributes: false,
12791279
use_span_with_attributes: span,
12801280
use_span: span,

compiler/rustc_resolve/src/imports.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! A bunch of methods and structures more or less related to resolving imports.
22
3-
use std::cell::Cell;
43
use std::mem;
54

65
use rustc_ast::NodeId;
@@ -33,10 +32,10 @@ use crate::errors::{
3332
ConsiderAddingMacroExport, ConsiderMarkingAsPub, ConsiderMarkingAsPubCrate,
3433
};
3534
use crate::{
36-
AmbiguityError, AmbiguityKind, BindingKey, CmResolver, Determinacy, Finalize, ImportSuggestion,
37-
Module, ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope,
38-
PathResult, PerNS, ResolutionError, Resolver, ScopeSet, Segment, Used, module_to_string,
39-
names_to_string,
35+
AmbiguityError, AmbiguityKind, BindingKey, CmCell, CmResolver, Determinacy, Finalize,
36+
ImportSuggestion, Module, ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind,
37+
ParentScope, PathResult, PerNS, ResolutionError, Resolver, ScopeSet, Segment, Used,
38+
module_to_string, names_to_string,
4039
};
4140

4241
type Res = def::Res<NodeId>;
@@ -68,7 +67,7 @@ pub(crate) enum ImportKind<'ra> {
6867
/// It will directly use `source` when the format is `use prefix::source`.
6968
target: Ident,
7069
/// Bindings introduced by the import.
71-
bindings: PerNS<Cell<PendingBinding<'ra>>>,
70+
bindings: PerNS<CmCell<PendingBinding<'ra>>>,
7271
/// `true` for `...::{self [as target]}` imports, `false` otherwise.
7372
type_ns_only: bool,
7473
/// Did this import result from a nested import? ie. `use foo::{bar, baz};`
@@ -89,7 +88,7 @@ pub(crate) enum ImportKind<'ra> {
8988
Glob {
9089
// The visibility of the greatest re-export.
9190
// n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
92-
max_vis: Cell<Option<Visibility>>,
91+
max_vis: CmCell<Option<Visibility>>,
9392
id: NodeId,
9493
},
9594
ExternCrate {
@@ -182,7 +181,7 @@ pub(crate) struct ImportData<'ra> {
182181
/// |`use ::foo` | `ModuleOrUniformRoot::ExternPrelude` | 2018+ editions |
183182
/// |`use ::foo` | `ModuleOrUniformRoot::ModuleAndExternPrelude` | a special case in 2015 edition |
184183
/// |`use foo` | `ModuleOrUniformRoot::CurrentScope` | - |
185-
pub imported_module: Cell<Option<ModuleOrUniformRoot<'ra>>>,
184+
pub imported_module: CmCell<Option<ModuleOrUniformRoot<'ra>>>,
186185
pub vis: Visibility,
187186

188187
/// Span of the visibility.
@@ -320,7 +319,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
320319
&& (vis == import_vis
321320
|| max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx)))
322321
{
323-
max_vis.set(Some(vis.expect_local()))
322+
// FIXME(batched): Will be fixed in batched import resolution.
323+
max_vis.set_unchecked(Some(vis.expect_local()))
324324
}
325325

326326
self.arenas.alloc_name_binding(NameBindingData {
@@ -349,7 +349,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
349349
// because they can be fetched by glob imports from those modules, and bring traits
350350
// into scope both directly and through glob imports.
351351
let key = BindingKey::new_disambiguated(ident, ns, || {
352-
module.underscore_disambiguator.update(|d| d + 1);
352+
// FIXME(batched): Will be fixed in batched resolution.
353+
module.underscore_disambiguator.update_unchecked(|d| d + 1);
353354
module.underscore_disambiguator.get()
354355
});
355356
self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| {
@@ -862,7 +863,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
862863
}
863864
};
864865

865-
import.imported_module.set(Some(module));
866+
// FIXME(batched): Will be fixed in batched import resolution.
867+
import.imported_module.set_unchecked(Some(module));
866868
let (source, target, bindings, type_ns_only) = match import.kind {
867869
ImportKind::Single { source, target, ref bindings, type_ns_only, .. } => {
868870
(source, target, bindings, type_ns_only)
@@ -937,7 +939,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
937939
PendingBinding::Pending
938940
}
939941
};
940-
bindings[ns].set(binding);
942+
// FIXME(batched): Will be fixed in batched import resolution.
943+
bindings[ns].set_unchecked(binding);
941944
}
942945
});
943946

compiler/rustc_resolve/src/lib.rs

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919
#![feature(default_field_values)]
2020
#![feature(if_let_guard)]
2121
#![feature(iter_intersperse)]
22+
#![feature(ptr_as_ref_unchecked)]
2223
#![feature(rustc_attrs)]
2324
#![feature(rustdoc_internals)]
2425
#![recursion_limit = "256"]
2526
// tidy-alphabetical-end
2627

2728
use std::cell::{Cell, Ref, RefCell};
2829
use std::collections::BTreeSet;
29-
use std::fmt;
30+
use std::fmt::{self, Formatter};
3031
use std::sync::Arc;
3132

3233
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
@@ -592,9 +593,9 @@ struct ModuleData<'ra> {
592593
/// Resolutions in modules from other crates are not populated until accessed.
593594
lazy_resolutions: Resolutions<'ra>,
594595
/// True if this is a module from other crate that needs to be populated on access.
595-
populate_on_access: Cell<bool>,
596+
populate_on_access: CmCell<bool>, // FIXME(batched): Use an atomic in batched import resolution?
596597
/// Used to disambiguate underscore items (`const _: T = ...`) in the module.
597-
underscore_disambiguator: Cell<u32>,
598+
underscore_disambiguator: CmCell<u32>, // FIXME(batched): Use an atomic in batched import resolution?
598599

599600
/// Macro invocations that can expand into items in this module.
600601
unexpanded_invocations: RefCell<FxHashSet<LocalExpnId>>,
@@ -655,8 +656,8 @@ impl<'ra> ModuleData<'ra> {
655656
parent,
656657
kind,
657658
lazy_resolutions: Default::default(),
658-
populate_on_access: Cell::new(is_foreign),
659-
underscore_disambiguator: Cell::new(0),
659+
populate_on_access: CmCell::new(is_foreign),
660+
underscore_disambiguator: CmCell::new(0),
660661
unexpanded_invocations: Default::default(),
661662
no_implicit_prelude,
662663
glob_importers: RefCell::new(Vec::new()),
@@ -1974,7 +1975,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19741975

19751976
fn resolutions(&self, module: Module<'ra>) -> &'ra Resolutions<'ra> {
19761977
if module.populate_on_access.get() {
1977-
module.populate_on_access.set(false);
1978+
// FIXME(batched): Will be fixed in batched import resolution.
1979+
module.populate_on_access.set_unchecked(false);
19781980
self.build_reduced_graph_external(module);
19791981
}
19801982
&module.0.0.lazy_resolutions
@@ -2561,3 +2563,58 @@ mod ref_mut {
25612563
///
25622564
/// Prefer constructing it through [`Resolver::cm`] to ensure correctness.
25632565
type CmResolver<'r, 'ra, 'tcx> = ref_mut::RefOrMut<'r, Resolver<'ra, 'tcx>>;
2566+
2567+
#[derive(Default)]
2568+
struct CmCell<T> {
2569+
value: Cell<T>,
2570+
}
2571+
2572+
impl<T: Copy + fmt::Debug> fmt::Debug for CmCell<T> {
2573+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2574+
f.debug_struct("CmCell").field("value", &self.get()).finish()
2575+
}
2576+
}
2577+
2578+
impl<T: Copy> Clone for CmCell<T> {
2579+
#[inline]
2580+
fn clone(&self) -> CmCell<T> {
2581+
CmCell::new(self.get())
2582+
}
2583+
}
2584+
2585+
impl<T: Copy> CmCell<T> {
2586+
const fn get(&self) -> T {
2587+
self.value.get()
2588+
}
2589+
2590+
pub fn update_unchecked(&self, f: impl FnOnce(T) -> T)
2591+
where
2592+
T: Copy,
2593+
{
2594+
let old = self.get();
2595+
self.set_unchecked(f(old));
2596+
}
2597+
}
2598+
2599+
impl<T> CmCell<T> {
2600+
const fn new(value: T) -> CmCell<T> {
2601+
CmCell { value: Cell::new(value) }
2602+
}
2603+
2604+
#[track_caller]
2605+
#[allow(dead_code)]
2606+
fn set<'ra, 'tcx>(&self, val: T, r: &Resolver<'ra, 'tcx>) {
2607+
if r.assert_speculative {
2608+
panic!("Not allowed to mutate CmCell during speculative resolution");
2609+
}
2610+
self.value.set(val);
2611+
}
2612+
2613+
fn set_unchecked(&self, val: T) {
2614+
self.value.set(val);
2615+
}
2616+
2617+
fn into_inner(self) -> T {
2618+
self.value.into_inner()
2619+
}
2620+
}

0 commit comments

Comments
 (0)