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