diff options
| author | bors <bors@rust-lang.org> | 2018-04-10 09:00:27 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-04-10 09:00:27 +0000 |
| commit | 67712d79451b042b6fca2167c1a57d91d86f663b (patch) | |
| tree | 4027dafb2a803d522019bc41052763d61b056f5c | |
| parent | a1c21ed7e21642b85947ba5d030bbaeffbe377de (diff) | |
| parent | 1e3f6388361e1489d27679d6b9e8ba16681e3d26 (diff) | |
| download | rust-67712d79451b042b6fca2167c1a57d91d86f663b.tar.gz rust-67712d79451b042b6fca2167c1a57d91d86f663b.zip | |
Auto merge of #49390 - Zoxc:sync-syntax, r=michaelwoerister
More thread-safety changes r? @michaelwoerister
| -rw-r--r-- | src/librustc/hir/map/mod.rs | 14 | ||||
| -rw-r--r-- | src/librustc/lint/mod.rs | 7 | ||||
| -rw-r--r-- | src/librustc/mir/cache.rs | 10 | ||||
| -rw-r--r-- | src/librustc/mir/mod.rs | 8 | ||||
| -rw-r--r-- | src/librustc/ty/context.rs | 50 | ||||
| -rw-r--r-- | src/librustc/ty/steal.rs | 12 | ||||
| -rw-r--r-- | src/librustc_borrowck/borrowck/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_data_structures/sync.rs | 12 | ||||
| -rw-r--r-- | src/librustc_trans/back/write.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 21 |
14 files changed, 101 insertions, 89 deletions
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index e8bcbfbb77a..1e348e3a31c 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -33,10 +33,11 @@ use hir::svh::Svh; use util::nodemap::{DefIdMap, FxHashMap}; use arena::TypedArena; -use std::cell::RefCell; use std::io; use ty::TyCtxt; +use rustc_data_structures::sync::Lock; + pub mod blocks; mod collector; mod def_collector; @@ -264,7 +265,7 @@ pub struct Map<'hir> { definitions: &'hir Definitions, /// Bodies inlined from other crates are cached here. - inlined_bodies: RefCell<DefIdMap<&'hir Body>>, + inlined_bodies: Lock<DefIdMap<&'hir Body>>, /// The reverse mapping of `node_to_hir_id`. hir_to_node_id: FxHashMap<HirId, NodeId>, @@ -927,8 +928,13 @@ impl<'hir> Map<'hir> { } pub fn intern_inlined_body(&self, def_id: DefId, body: Body) -> &'hir Body { + let mut inlined_bodies = self.inlined_bodies.borrow_mut(); + if let Some(&b) = inlined_bodies.get(&def_id) { + debug_assert_eq!(&body, b); + return b; + } let body = self.forest.inlined_bodies.alloc(body); - self.inlined_bodies.borrow_mut().insert(def_id, body); + inlined_bodies.insert(def_id, body); body } @@ -1189,7 +1195,7 @@ pub fn map_crate<'hir>(sess: &::session::Session, map, hir_to_node_id, definitions, - inlined_bodies: RefCell::new(DefIdMap()), + inlined_bodies: Lock::new(DefIdMap()), }; hir_id_validator::check_crate(&map); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 89a9f303478..0d4fd99995f 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -31,7 +31,7 @@ pub use self::Level::*; pub use self::LintSource::*; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{self, Lrc}; use errors::{DiagnosticBuilder, DiagnosticId}; use hir::def_id::{CrateNum, LOCAL_CRATE}; @@ -287,8 +287,9 @@ pub trait EarlyLintPass: LintPass { } /// A lint pass boxed up as a trait object. -pub type EarlyLintPassObject = Box<dyn EarlyLintPass + 'static>; -pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + 'static>; +pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync + 'static>; +pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + sync::Send + + sync::Sync + 'static>; /// Identifies a lint known to the compiler. #[derive(Clone, Copy, Debug)] diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index 9b75c19a875..1ed5a22257c 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::cell::{Ref, RefCell}; use rustc_data_structures::indexed_vec::IndexVec; +use rustc_data_structures::sync::{RwLock, ReadGuard}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; use ich::StableHashingContext; @@ -19,7 +19,7 @@ use rustc_serialize as serialize; #[derive(Clone, Debug)] pub struct Cache { - predecessors: RefCell<Option<IndexVec<BasicBlock, Vec<BasicBlock>>>> + predecessors: RwLock<Option<IndexVec<BasicBlock, Vec<BasicBlock>>>> } @@ -46,7 +46,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Cache { impl Cache { pub fn new() -> Self { Cache { - predecessors: RefCell::new(None) + predecessors: RwLock::new(None) } } @@ -55,12 +55,12 @@ impl Cache { *self.predecessors.borrow_mut() = None; } - pub fn predecessors(&self, mir: &Mir) -> Ref<IndexVec<BasicBlock, Vec<BasicBlock>>> { + pub fn predecessors(&self, mir: &Mir) -> ReadGuard<IndexVec<BasicBlock, Vec<BasicBlock>>> { if self.predecessors.borrow().is_none() { *self.predecessors.borrow_mut() = Some(calculate_predecessors(mir)); } - Ref::map(self.predecessors.borrow(), |p| p.as_ref().unwrap()) + ReadGuard::map(self.predecessors.borrow(), |p| p.as_ref().unwrap()) } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9ed4e6a8e00..33f52ab09c8 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -34,7 +34,7 @@ use util::ppaux; use std::slice; use hir::{self, InlineAsm}; use std::borrow::{Cow}; -use std::cell::Ref; +use rustc_data_structures::sync::ReadGuard; use std::fmt::{self, Debug, Formatter, Write}; use std::{iter, mem, u32}; use std::ops::{Index, IndexMut}; @@ -187,13 +187,13 @@ impl<'tcx> Mir<'tcx> { } #[inline] - pub fn predecessors(&self) -> Ref<IndexVec<BasicBlock, Vec<BasicBlock>>> { + pub fn predecessors(&self) -> ReadGuard<IndexVec<BasicBlock, Vec<BasicBlock>>> { self.cache.predecessors(self) } #[inline] - pub fn predecessors_for(&self, bb: BasicBlock) -> Ref<Vec<BasicBlock>> { - Ref::map(self.predecessors(), |p| &p[bb]) + pub fn predecessors_for(&self, bb: BasicBlock) -> ReadGuard<Vec<BasicBlock>> { + ReadGuard::map(self.predecessors(), |p| &p[bb]) } #[inline] diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 69b33efdb35..e6ad95ec3c7 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -58,7 +58,7 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap, StableVec}; use arena::{TypedArena, DroplessArena}; use rustc_data_structures::indexed_vec::IndexVec; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Lock}; use std::any::Any; use std::borrow::Borrow; use std::cell::{Cell, RefCell}; @@ -131,28 +131,28 @@ pub struct CtxtInterners<'tcx> { /// Specifically use a speedy hash algorithm for these hash sets, /// they're accessed quite often. - type_: RefCell<FxHashSet<Interned<'tcx, TyS<'tcx>>>>, - type_list: RefCell<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>, - substs: RefCell<FxHashSet<Interned<'tcx, Substs<'tcx>>>>, - canonical_var_infos: RefCell<FxHashSet<Interned<'tcx, Slice<CanonicalVarInfo>>>>, - region: RefCell<FxHashSet<Interned<'tcx, RegionKind>>>, - existential_predicates: RefCell<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>, - predicates: RefCell<FxHashSet<Interned<'tcx, Slice<Predicate<'tcx>>>>>, - const_: RefCell<FxHashSet<Interned<'tcx, Const<'tcx>>>>, + type_: Lock<FxHashSet<Interned<'tcx, TyS<'tcx>>>>, + type_list: Lock<FxHashSet<Interned<'tcx, Slice<Ty<'tcx>>>>>, + substs: Lock<FxHashSet<Interned<'tcx, Substs<'tcx>>>>, + canonical_var_infos: Lock<FxHashSet<Interned<'tcx, Slice<CanonicalVarInfo>>>>, + region: Lock<FxHashSet<Interned<'tcx, RegionKind>>>, + existential_predicates: Lock<FxHashSet<Interned<'tcx, Slice<ExistentialPredicate<'tcx>>>>>, + predicates: Lock<FxHashSet<Interned<'tcx, Slice<Predicate<'tcx>>>>>, + const_: Lock<FxHashSet<Interned<'tcx, Const<'tcx>>>>, } impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { fn new(arena: &'tcx DroplessArena) -> CtxtInterners<'tcx> { CtxtInterners { - arena, - type_: RefCell::new(FxHashSet()), - type_list: RefCell::new(FxHashSet()), - substs: RefCell::new(FxHashSet()), - region: RefCell::new(FxHashSet()), - existential_predicates: RefCell::new(FxHashSet()), - canonical_var_infos: RefCell::new(FxHashSet()), - predicates: RefCell::new(FxHashSet()), - const_: RefCell::new(FxHashSet()), + arena: arena, + type_: Lock::new(FxHashSet()), + type_list: Lock::new(FxHashSet()), + substs: Lock::new(FxHashSet()), + canonical_var_infos: Lock::new(FxHashSet()), + region: Lock::new(FxHashSet()), + existential_predicates: Lock::new(FxHashSet()), + predicates: Lock::new(FxHashSet()), + const_: Lock::new(FxHashSet()), } } @@ -892,11 +892,11 @@ pub struct GlobalCtxt<'tcx> { /// by `proc-macro` crates. pub derive_macros: RefCell<NodeMap<Symbol>>, - stability_interner: RefCell<FxHashSet<&'tcx attr::Stability>>, + stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>, pub interpret_interner: InterpretInterner<'tcx>, - layout_interner: RefCell<FxHashSet<&'tcx LayoutDetails>>, + layout_interner: Lock<FxHashSet<&'tcx LayoutDetails>>, /// A vector of every trait accessible in the whole crate /// (i.e. including those from subcrates). This is used only for @@ -910,7 +910,7 @@ pub struct GlobalCtxt<'tcx> { /// This is intended to only get used during the trans phase of the compiler /// when satisfying the query for a particular codegen unit. Internally in /// the query it'll send data along this channel to get processed later. - pub tx_to_llvm_workers: mpsc::Sender<Box<dyn Any + Send>>, + pub tx_to_llvm_workers: Lock<mpsc::Sender<Box<dyn Any + Send>>>, output_filenames: Arc<OutputFilenames>, } @@ -918,7 +918,7 @@ pub struct GlobalCtxt<'tcx> { /// Everything needed to efficiently work with interned allocations #[derive(Debug, Default)] pub struct InterpretInterner<'tcx> { - inner: RefCell<InterpretInternerInner<'tcx>>, + inner: Lock<InterpretInternerInner<'tcx>>, } #[derive(Debug, Default)] @@ -1278,13 +1278,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { evaluation_cache: traits::EvaluationCache::new(), crate_name: Symbol::intern(crate_name), data_layout, - layout_interner: RefCell::new(FxHashSet()), + layout_interner: Lock::new(FxHashSet()), layout_depth: Cell::new(0), derive_macros: RefCell::new(NodeMap()), - stability_interner: RefCell::new(FxHashSet()), + stability_interner: Lock::new(FxHashSet()), interpret_interner: Default::default(), all_traits: RefCell::new(None), - tx_to_llvm_workers: tx, + tx_to_llvm_workers: Lock::new(tx), output_filenames: Arc::new(output_filenames.clone()), }; diff --git a/src/librustc/ty/steal.rs b/src/librustc/ty/steal.rs index 0b081888881..842c0d65734 100644 --- a/src/librustc/ty/steal.rs +++ b/src/librustc/ty/steal.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::cell::{Ref, RefCell}; +use rustc_data_structures::sync::{RwLock, ReadGuard}; use std::mem; /// The `Steal` struct is intended to used as the value for a query. @@ -32,25 +32,25 @@ use std::mem; /// /// FIXME(#41710) -- what is the best way to model linear queries? pub struct Steal<T> { - value: RefCell<Option<T>> + value: RwLock<Option<T>> } impl<T> Steal<T> { pub fn new(value: T) -> Self { Steal { - value: RefCell::new(Some(value)) + value: RwLock::new(Some(value)) } } - pub fn borrow(&self) -> Ref<T> { - Ref::map(self.value.borrow(), |opt| match *opt { + pub fn borrow(&self) -> ReadGuard<T> { + ReadGuard::map(self.value.borrow(), |opt| match *opt { None => bug!("attempted to read from stolen value"), Some(ref v) => v }) } pub fn steal(&self) -> T { - let value_ref = &mut *self.value.borrow_mut(); + let value_ref = &mut *self.value.try_write().expect("stealing value which is locked"); let value = mem::replace(value_ref, None); value.expect("attempt to read from stolen value") } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 93d6247eeae..2049a146a0f 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -128,7 +128,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) // Note that `mir_validated` is a "stealable" result; the // thief, `optimized_mir()`, forces borrowck, so we know that // is not yet stolen. - tcx.mir_validated(owner_def_id).borrow(); + ty::maps::queries::mir_validated::ensure(tcx, owner_def_id); // option dance because you can't capture an uninitialized variable // by mut-ref. diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 184ef136976..0f534f0adec 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -390,6 +390,18 @@ impl<T> RwLock<T> { #[cfg(not(parallel_queries))] #[inline(always)] + pub fn try_write(&self) -> Result<WriteGuard<T>, ()> { + self.0.try_borrow_mut().map_err(|_| ()) + } + + #[cfg(parallel_queries)] + #[inline(always)] + pub fn try_write(&self) -> Result<WriteGuard<T>, ()> { + self.0.try_write().ok_or(()) + } + + #[cfg(not(parallel_queries))] + #[inline(always)] pub fn write(&self) -> WriteGuard<T> { self.0.borrow_mut() } diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index fc699f7569f..6c756576411 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -1035,7 +1035,7 @@ pub fn start_async_translation(tcx: TyCtxt, crate_info, time_graph, - coordinator_send: tcx.tx_to_llvm_workers.clone(), + coordinator_send: tcx.tx_to_llvm_workers.lock().clone(), trans_worker_receive, shared_emitter_main, future: coordinator_thread, @@ -1428,7 +1428,7 @@ fn start_executing_work(tcx: TyCtxt, metadata_config: Arc<ModuleConfig>, allocator_config: Arc<ModuleConfig>) -> thread::JoinHandle<Result<CompiledModules, ()>> { - let coordinator_send = tcx.tx_to_llvm_workers.clone(); + let coordinator_send = tcx.tx_to_llvm_workers.lock().clone(); let sess = tcx.sess; // Compute the set of symbols we need to retain when doing LTO (if we need to) @@ -2340,7 +2340,7 @@ pub(crate) fn submit_translated_module_to_llvm(tcx: TyCtxt, mtrans: ModuleTranslation, cost: u64) { let llvm_work_item = WorkItem::Optimize(mtrans); - drop(tcx.tx_to_llvm_workers.send(Box::new(Message::TranslationDone { + drop(tcx.tx_to_llvm_workers.lock().send(Box::new(Message::TranslationDone { llvm_work_item, cost, }))); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index a09bea25a24..c25a7686bea 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -28,7 +28,7 @@ use std::collections::HashMap; use std::iter; use std::path::PathBuf; use std::rc::Rc; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{self, Lrc}; use std::default::Default; use tokenstream::{self, TokenStream}; @@ -565,26 +565,26 @@ pub enum SyntaxExtension { /// `#[derive(...)]` is a `MultiItemDecorator`. /// /// Prefer ProcMacro or MultiModifier since they are more flexible. - MultiDecorator(Box<MultiItemDecorator>), + MultiDecorator(Box<MultiItemDecorator + sync::Sync + sync::Send>), /// A syntax extension that is attached to an item and modifies it /// in-place. Also allows decoration, i.e., creating new items. - MultiModifier(Box<MultiItemModifier>), + MultiModifier(Box<MultiItemModifier + sync::Sync + sync::Send>), /// A function-like procedural macro. TokenStream -> TokenStream. - ProcMacro(Box<ProcMacro>), + ProcMacro(Box<ProcMacro + sync::Sync + sync::Send>), /// An attribute-like procedural macro. TokenStream, TokenStream -> TokenStream. /// The first TokenSteam is the attribute, the second is the annotated item. /// Allows modification of the input items and adding new items, similar to /// MultiModifier, but uses TokenStreams, rather than AST nodes. - AttrProcMacro(Box<AttrProcMacro>), + AttrProcMacro(Box<AttrProcMacro + sync::Sync + sync::Send>), /// A normal, function-like syntax extension. /// /// `bytes!` is a `NormalTT`. NormalTT { - expander: Box<TTMacroExpander>, + expander: Box<TTMacroExpander + sync::Sync + sync::Send>, def_info: Option<(ast::NodeId, Span)>, /// Whether the contents of the macro can /// directly use `#[unstable]` things (true == yes). @@ -599,13 +599,15 @@ pub enum SyntaxExtension { /// A function-like syntax extension that has an extra ident before /// the block. /// - IdentTT(Box<IdentMacroExpander>, Option<Span>, bool), + IdentTT(Box<IdentMacroExpander + sync::Sync + sync::Send>, Option<Span>, bool), /// An attribute-like procedural macro. TokenStream -> TokenStream. /// The input is the annotated item. /// Allows generating code to implement a Trait for a given struct /// or enum item. - ProcMacroDerive(Box<MultiItemModifier>, Vec<Symbol> /* inert attribute names */), + ProcMacroDerive(Box<MultiItemModifier + + sync::Sync + + sync::Send>, Vec<Symbol> /* inert attribute names */), /// An attribute-like procedural macro that derives a builtin trait. BuiltinDerive(BuiltinDeriveFn), @@ -613,7 +615,7 @@ pub enum SyntaxExtension { /// A declarative macro, e.g. `macro m() {}`. /// /// The second element is the definition site span. - DeclMacro(Box<TTMacroExpander>, Option<(ast::NodeId, Span)>), + DeclMacro(Box<TTMacroExpander + sync::Sync + sync::Send>, Option<(ast::NodeId, Span)>), } impl SyntaxExtension { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index c456dc45d21..b1a22724a9a 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -26,6 +26,8 @@ #![feature(const_atomic_usize_new)] #![feature(rustc_attrs)] +#![recursion_limit="256"] + // See librustc_cratesio_shim/Cargo.toml for a comment explaining this. #[allow(unused_extern_crates)] extern crate rustc_cratesio_shim; diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 152c4c31eb3..39b2f77f230 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1781,7 +1781,6 @@ mod tests { use errors; use feature_gate::UnstableFeatures; use parse::token; - use std::cell::RefCell; use std::collections::HashSet; use std::io; use std::path::PathBuf; @@ -1797,12 +1796,12 @@ mod tests { span_diagnostic: errors::Handler::with_emitter(true, false, Box::new(emitter)), unstable_features: UnstableFeatures::from_environment(), config: CrateConfig::new(), - included_mod_stack: RefCell::new(Vec::new()), + included_mod_stack: Lock::new(Vec::new()), code_map: cm, - missing_fragment_specifiers: RefCell::new(HashSet::new()), - raw_identifier_spans: RefCell::new(Vec::new()), + missing_fragment_specifiers: Lock::new(HashSet::new()), + raw_identifier_spans: Lock::new(Vec::new()), registered_diagnostics: Lock::new(ErrorMap::new()), - non_modrs_mods: RefCell::new(vec![]), + non_modrs_mods: Lock::new(vec![]), } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 428b3b136df..ff63c9a5c6d 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -23,7 +23,6 @@ use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; use diagnostics::plugin::ErrorMap; -use std::cell::RefCell; use std::collections::HashSet; use std::iter; use std::path::{Path, PathBuf}; @@ -46,17 +45,17 @@ pub struct ParseSess { pub span_diagnostic: Handler, pub unstable_features: UnstableFeatures, pub config: CrateConfig, - pub missing_fragment_specifiers: RefCell<HashSet<Span>>, + pub missing_fragment_specifiers: Lock<HashSet<Span>>, /// Places where raw identifiers were used. This is used for feature gating /// raw identifiers - pub raw_identifier_spans: RefCell<Vec<Span>>, + pub raw_identifier_spans: Lock<Vec<Span>>, /// The registered diagnostics codes pub registered_diagnostics: Lock<ErrorMap>, // Spans where a `mod foo;` statement was included in a non-mod.rs file. // These are used to issue errors if the non_modrs_mods feature is not enabled. - pub non_modrs_mods: RefCell<Vec<(ast::Ident, Span)>>, + pub non_modrs_mods: Lock<Vec<(ast::Ident, Span)>>, /// Used to determine and report recursive mod inclusions - included_mod_stack: RefCell<Vec<PathBuf>>, + included_mod_stack: Lock<Vec<PathBuf>>, code_map: Lrc<CodeMap>, } @@ -75,12 +74,12 @@ impl ParseSess { span_diagnostic: handler, unstable_features: UnstableFeatures::from_environment(), config: HashSet::new(), - missing_fragment_specifiers: RefCell::new(HashSet::new()), - raw_identifier_spans: RefCell::new(Vec::new()), + missing_fragment_specifiers: Lock::new(HashSet::new()), + raw_identifier_spans: Lock::new(Vec::new()), registered_diagnostics: Lock::new(ErrorMap::new()), - included_mod_stack: RefCell::new(vec![]), + included_mod_stack: Lock::new(vec![]), code_map, - non_modrs_mods: RefCell::new(vec![]), + non_modrs_mods: Lock::new(vec![]), } } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index df0ea05005c..8da79f92768 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -25,9 +25,8 @@ use syntax_pos::{self, Span, FileName}; use tokenstream::{TokenStream, TokenTree}; use tokenstream; -use std::cell::Cell; use std::{cmp, fmt}; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Lock}; #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] pub enum BinOpToken { @@ -627,15 +626,8 @@ pub fn is_op(tok: &Token) -> bool { } } -pub struct LazyTokenStream(Cell<Option<TokenStream>>); - -impl Clone for LazyTokenStream { - fn clone(&self) -> Self { - let opt_stream = self.0.take(); - self.0.set(opt_stream.clone()); - LazyTokenStream(Cell::new(opt_stream)) - } -} +#[derive(Clone)] +pub struct LazyTokenStream(Lock<Option<TokenStream>>); impl cmp::Eq for LazyTokenStream {} impl PartialEq for LazyTokenStream { @@ -652,15 +644,14 @@ impl fmt::Debug for LazyTokenStream { impl LazyTokenStream { pub fn new() -> Self { - LazyTokenStream(Cell::new(None)) + LazyTokenStream(Lock::new(None)) } pub fn force<F: FnOnce() -> TokenStream>(&self, f: F) -> TokenStream { - let mut opt_stream = self.0.take(); + let mut opt_stream = self.0.lock(); if opt_stream.is_none() { - opt_stream = Some(f()); + *opt_stream = Some(f()); } - self.0.set(opt_stream.clone()); opt_stream.clone().unwrap() } } |
