@@ -24,6 +24,8 @@ use ty::tls;
use util::nodemap::{FxHashMap, FxHashSet};
use util::common::{duration_to_secs_str, ErrorReported};

use rustc_data_structures::sync::{self, Lrc, RwLock, Lock, LockCell, ReadGuard};

use syntax::ast::NodeId;
use errors::{self, DiagnosticBuilder, DiagnosticId};
use errors::emitter::{Emitter, EmitterWriter};
@@ -41,7 +43,6 @@ use rustc_back::target::Target;
use rustc_data_structures::flock;
use jobserver::Client;

use std::cell::{self, Cell, RefCell};
use std::collections::HashMap;
use std::env;
use std::fmt;
@@ -63,55 +64,55 @@ pub struct Session {
pub opts: config::Options,
pub parse_sess: ParseSess,
/// For a library crate, this is always none
pub entry_fn: RefCell<Option<(NodeId, Span)>>,
pub entry_type: Cell<Option<config::EntryFnType>>,
pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
pub derive_registrar_fn: Cell<Option<ast::NodeId>>,
pub entry_fn: Lock<Option<(NodeId, Span)>>,
pub entry_type: LockCell<Option<config::EntryFnType>>,
pub plugin_registrar_fn: LockCell<Option<ast::NodeId>>,
pub derive_registrar_fn: LockCell<Option<ast::NodeId>>,
pub default_sysroot: Option<PathBuf>,
/// The name of the root source file of the crate, in the local file system.
/// `None` means that there is no source file.
pub local_crate_source_file: Option<PathBuf>,
/// The directory the compiler has been executed in plus a flag indicating
/// if the value stored here has been affected by path remapping.
pub working_dir: (PathBuf, bool),
pub lint_store: RefCell<lint::LintStore>,
pub buffered_lints: RefCell<Option<lint::LintBuffer>>,
pub lint_store: RwLock<lint::LintStore>,
pub buffered_lints: Lock<Option<lint::LintBuffer>>,
/// Set of (DiagnosticId, Option<Span>, message) tuples tracking
/// (sub)diagnostics that have been set once, but should not be set again,
/// in order to avoid redundantly verbose output (Issue #24690, #44953).
pub one_time_diagnostics: RefCell<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
pub plugin_llvm_passes: RefCell<Vec<String>>,
pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
pub crate_types: RefCell<Vec<config::CrateType>>,
pub dependency_formats: RefCell<dependency_format::Dependencies>,
pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
pub plugin_llvm_passes: Lock<Vec<String>>,
pub plugin_attributes: Lock<Vec<(String, AttributeType)>>,
pub crate_types: RwLock<Vec<config::CrateType>>,
pub dependency_formats: Lock<dependency_format::Dependencies>,
/// The crate_disambiguator is constructed out of all the `-C metadata`
/// arguments passed to the compiler. Its value together with the crate-name
/// forms a unique global identifier for the crate. It is used to allow
/// multiple crates with the same name to coexist. See the
/// trans::back::symbol_names module for more information.
pub crate_disambiguator: RefCell<Option<CrateDisambiguator>>,
pub features: RefCell<feature_gate::Features>,
pub crate_disambiguator: Lock<Option<CrateDisambiguator>>,
pub features: RwLock<feature_gate::Features>,

/// The maximum recursion limit for potentially infinitely recursive
/// operations such as auto-dereference and monomorphization.
pub recursion_limit: Cell<usize>,
pub recursion_limit: LockCell<usize>,

/// The maximum length of types during monomorphization.
pub type_length_limit: Cell<usize>,
pub type_length_limit: LockCell<usize>,

/// The metadata::creader module may inject an allocator/panic_runtime
/// dependency if it didn't already find one, and this tracks what was
/// injected.
pub injected_allocator: Cell<Option<CrateNum>>,
pub allocator_kind: Cell<Option<AllocatorKind>>,
pub injected_panic_runtime: Cell<Option<CrateNum>>,
pub injected_allocator: LockCell<Option<CrateNum>>,
pub allocator_kind: LockCell<Option<AllocatorKind>>,
pub injected_panic_runtime: LockCell<Option<CrateNum>>,

/// Map from imported macro spans (which consist of
/// the localized span for the macro body) to the
/// macro name and definition span in the source crate.
pub imported_macro_spans: RefCell<HashMap<Span, (String, Span)>>,
pub imported_macro_spans: Lock<HashMap<Span, (String, Span)>>,

incr_comp_session: RefCell<IncrCompSession>,
incr_comp_session: RwLock<IncrCompSession>,

/// A cache of attributes ignored by StableHashingContext
pub ignored_attr_names: FxHashSet<Symbol>,
@@ -120,45 +121,45 @@ pub struct Session {
pub perf_stats: PerfStats,

/// Data about code being compiled, gathered during compilation.
pub code_stats: RefCell<CodeStats>,
pub code_stats: Lock<CodeStats>,

next_node_id: Cell<ast::NodeId>,
next_node_id: LockCell<ast::NodeId>,

/// If -zfuel=crate=n is specified, Some(crate).
optimization_fuel_crate: Option<String>,
/// If -zfuel=crate=n is specified, initially set to n. Otherwise 0.
optimization_fuel_limit: Cell<u64>,
optimization_fuel_limit: LockCell<u64>,
/// We're rejecting all further optimizations.
out_of_fuel: Cell<bool>,
out_of_fuel: LockCell<bool>,

// The next two are public because the driver needs to read them.

/// If -zprint-fuel=crate, Some(crate).
pub print_fuel_crate: Option<String>,
/// Always set to zero and incremented so that we can print fuel expended by a crate.
pub print_fuel: Cell<u64>,
pub print_fuel: LockCell<u64>,

/// Loaded up early on in the initialization of this `Session` to avoid
/// false positives about a job server in our environment.
pub jobserver_from_env: Option<Client>,

/// Metadata about the allocators for the current crate being compiled
pub has_global_allocator: Cell<bool>,
pub has_global_allocator: LockCell<bool>,
}

pub struct PerfStats {
/// The accumulated time needed for computing the SVH of the crate
pub svh_time: Cell<Duration>,
pub svh_time: LockCell<Duration>,
/// The accumulated time spent on computing incr. comp. hashes
pub incr_comp_hashes_time: Cell<Duration>,
pub incr_comp_hashes_time: LockCell<Duration>,
/// The number of incr. comp. hash computations performed
pub incr_comp_hashes_count: Cell<u64>,
pub incr_comp_hashes_count: LockCell<u64>,
/// The number of bytes hashed when computing ICH values
pub incr_comp_bytes_hashed: Cell<u64>,
pub incr_comp_bytes_hashed: LockCell<u64>,
/// The accumulated time spent on computing symbol hashes
pub symbol_hash_time: Cell<Duration>,
pub symbol_hash_time: LockCell<Duration>,
/// The accumulated time spent decoding def path tables from metadata
pub decode_def_path_tables_time: Cell<Duration>,
pub decode_def_path_tables_time: LockCell<Duration>,
}

/// Enum to support dispatch of one-time diagnostics (in Session.diag_once)
@@ -718,9 +719,9 @@ impl Session {
};
}

pub fn incr_comp_session_dir(&self) -> cell::Ref<PathBuf> {
pub fn incr_comp_session_dir(&self) -> ReadGuard<PathBuf> {
let incr_comp_session = self.incr_comp_session.borrow();
cell::Ref::map(incr_comp_session, |incr_comp_session| {
ReadGuard::map(incr_comp_session, |incr_comp_session| {
match *incr_comp_session {
IncrCompSession::NotInitialized => {
bug!("Trying to get session directory from IncrCompSession `{:?}`",
@@ -735,7 +736,7 @@ impl Session {
})
}

pub fn incr_comp_session_dir_opt(&self) -> Option<cell::Ref<PathBuf>> {
pub fn incr_comp_session_dir_opt(&self) -> Option<ReadGuard<PathBuf>> {
if self.opts.incremental.is_some() {
Some(self.incr_comp_session_dir())
} else {
@@ -974,10 +975,10 @@ pub fn build_session_(sopts: config::Options,
});

let optimization_fuel_crate = sopts.debugging_opts.fuel.as_ref().map(|i| i.0.clone());
let optimization_fuel_limit = Cell::new(sopts.debugging_opts.fuel.as_ref()
let optimization_fuel_limit = LockCell::new(sopts.debugging_opts.fuel.as_ref()
.map(|i| i.1).unwrap_or(0));
let print_fuel_crate = sopts.debugging_opts.print_fuel.clone();
let print_fuel = Cell::new(0);
let print_fuel = LockCell::new(0);

let working_dir = match env::current_dir() {
Ok(dir) => dir,
@@ -993,45 +994,45 @@ pub fn build_session_(sopts: config::Options,
opts: sopts,
parse_sess: p_s,
// For a library crate, this is always none
entry_fn: RefCell::new(None),
entry_type: Cell::new(None),
plugin_registrar_fn: Cell::new(None),
derive_registrar_fn: Cell::new(None),
entry_fn: Lock::new(None),
entry_type: LockCell::new(None),
plugin_registrar_fn: LockCell::new(None),
derive_registrar_fn: LockCell::new(None),
default_sysroot,
local_crate_source_file,
working_dir,
lint_store: RefCell::new(lint::LintStore::new()),
buffered_lints: RefCell::new(Some(lint::LintBuffer::new())),
one_time_diagnostics: RefCell::new(FxHashSet()),
plugin_llvm_passes: RefCell::new(Vec::new()),
plugin_attributes: RefCell::new(Vec::new()),
crate_types: RefCell::new(Vec::new()),
dependency_formats: RefCell::new(FxHashMap()),
crate_disambiguator: RefCell::new(None),
features: RefCell::new(feature_gate::Features::new()),
recursion_limit: Cell::new(64),
type_length_limit: Cell::new(1048576),
next_node_id: Cell::new(NodeId::new(1)),
injected_allocator: Cell::new(None),
allocator_kind: Cell::new(None),
injected_panic_runtime: Cell::new(None),
imported_macro_spans: RefCell::new(HashMap::new()),
incr_comp_session: RefCell::new(IncrCompSession::NotInitialized),
lint_store: RwLock::new(lint::LintStore::new()),
buffered_lints: Lock::new(Some(lint::LintBuffer::new())),
one_time_diagnostics: Lock::new(FxHashSet()),
plugin_llvm_passes: Lock::new(Vec::new()),
plugin_attributes: Lock::new(Vec::new()),
crate_types: RwLock::new(Vec::new()),
dependency_formats: Lock::new(FxHashMap()),
crate_disambiguator: Lock::new(None),
features: RwLock::new(feature_gate::Features::new()),
recursion_limit: LockCell::new(64),
type_length_limit: LockCell::new(1048576),
next_node_id: LockCell::new(NodeId::new(1)),
injected_allocator: LockCell::new(None),
allocator_kind: LockCell::new(None),
injected_panic_runtime: LockCell::new(None),
imported_macro_spans: Lock::new(HashMap::new()),
incr_comp_session: RwLock::new(IncrCompSession::NotInitialized),
ignored_attr_names: ich::compute_ignored_attr_names(),
perf_stats: PerfStats {
svh_time: Cell::new(Duration::from_secs(0)),
incr_comp_hashes_time: Cell::new(Duration::from_secs(0)),
incr_comp_hashes_count: Cell::new(0),
incr_comp_bytes_hashed: Cell::new(0),
symbol_hash_time: Cell::new(Duration::from_secs(0)),
decode_def_path_tables_time: Cell::new(Duration::from_secs(0)),
svh_time: LockCell::new(Duration::from_secs(0)),
incr_comp_hashes_time: LockCell::new(Duration::from_secs(0)),
incr_comp_hashes_count: LockCell::new(0),
incr_comp_bytes_hashed: LockCell::new(0),
symbol_hash_time: LockCell::new(Duration::from_secs(0)),
decode_def_path_tables_time: LockCell::new(Duration::from_secs(0)),
},
code_stats: RefCell::new(CodeStats::new()),
code_stats: Lock::new(CodeStats::new()),
optimization_fuel_crate,
optimization_fuel_limit,
print_fuel_crate,
print_fuel,
out_of_fuel: Cell::new(false),
out_of_fuel: LockCell::new(false),
// Note that this is unsafe because it may misinterpret file descriptors
// on Unix as jobserver file descriptors. We hopefully execute this near
// the beginning of the process though to ensure we don't get false
@@ -1049,7 +1050,7 @@ pub fn build_session_(sopts: config::Options,
});
(*GLOBAL_JOBSERVER).clone()
},
has_global_allocator: Cell::new(false),
has_global_allocator: LockCell::new(false),
};

sess
@@ -41,10 +41,10 @@ use ty::fast_reject;
use ty::relate::TypeRelation;
use middle::lang_items;

use rustc_data_structures::sync::Lock;
use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
use std::iter;
use std::cell::RefCell;
use std::cmp;
use std::fmt;
use std::marker::PhantomData;
@@ -148,7 +148,7 @@ struct TraitObligationStack<'prev, 'tcx: 'prev> {

#[derive(Clone)]
pub struct SelectionCache<'tcx> {
hashmap: RefCell<FxHashMap<ty::TraitRef<'tcx>,
hashmap: Lock<FxHashMap<ty::TraitRef<'tcx>,
WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>>>,
}

@@ -413,7 +413,7 @@ impl EvaluationResult {

#[derive(Clone)]
pub struct EvaluationCache<'tcx> {
hashmap: RefCell<FxHashMap<ty::PolyTraitRef<'tcx>, WithDepNode<EvaluationResult>>>
hashmap: Lock<FxHashMap<ty::PolyTraitRef<'tcx>, WithDepNode<EvaluationResult>>>
}

impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
@@ -3334,15 +3334,15 @@ impl<'tcx> TraitObligation<'tcx> {
impl<'tcx> SelectionCache<'tcx> {
pub fn new() -> SelectionCache<'tcx> {
SelectionCache {
hashmap: RefCell::new(FxHashMap())
hashmap: Lock::new(FxHashMap())
}
}
}

impl<'tcx> EvaluationCache<'tcx> {
pub fn new() -> EvaluationCache<'tcx> {
EvaluationCache {
hashmap: RefCell::new(FxHashMap())
hashmap: Lock::new(FxHashMap())
}
}
}
@@ -55,9 +55,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
use arena::{TypedArena, DroplessArena};
use rustc_const_math::{ConstInt, ConstUsize};
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::sync::{Sync, Lrc, Lock, LockCell};
use std::any::Any;
use std::borrow::Borrow;
use std::cell::{Cell, RefCell};
use std::cmp::Ordering;
use std::collections::hash_map::{self, Entry};
use std::hash::{Hash, Hasher};
@@ -126,26 +126,26 @@ 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>>>>,
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>>>>,
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()),
predicates: RefCell::new(FxHashSet()),
const_: RefCell::new(FxHashSet()),
arena: arena,
type_: Lock::new(FxHashSet()),
type_list: Lock::new(FxHashSet()),
substs: Lock::new(FxHashSet()),
region: Lock::new(FxHashSet()),
existential_predicates: Lock::new(FxHashSet()),
predicates: Lock::new(FxHashSet()),
const_: Lock::new(FxHashSet()),
}
}

@@ -839,7 +839,7 @@ pub struct GlobalCtxt<'tcx> {
maybe_unused_extern_crates: Vec<(DefId, Span)>,

// Internal cache for metadata decoding. No need to track deps on this.
pub rcache: RefCell<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,
pub rcache: Lock<FxHashMap<ty::CReaderCacheKey, Ty<'tcx>>>,

/// Caches the results of trait selection. This cache is used
/// for things that do not have to do with the parameters in scope.
@@ -858,31 +858,31 @@ pub struct GlobalCtxt<'tcx> {
pub data_layout: TargetDataLayout,

/// Used to prevent layout from recursing too deeply.
pub layout_depth: Cell<usize>,
pub layout_depth: LockCell<usize>,

/// Map from function to the `#[derive]` mode that it's defining. Only used
/// by `proc-macro` crates.
pub derive_macros: RefCell<NodeMap<Symbol>>,
pub derive_macros: Lock<NodeMap<Symbol>>,

stability_interner: RefCell<FxHashSet<&'tcx attr::Stability>>,
stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,

pub interpret_interner: RefCell<InterpretInterner<'tcx>>,
pub interpret_interner: Lock<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
/// error reporting, and so is lazily initialized and generally
/// shouldn't taint the common path (hence the RefCell).
pub all_traits: RefCell<Option<Vec<DefId>>>,
/// shouldn't taint the common path (hence the Lock).
pub all_traits: Lock<Option<Vec<DefId>>>,

/// A general purpose channel to throw data out the back towards LLVM worker
/// threads.
///
/// 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<Any + Send>>,
pub tx_to_llvm_workers: Lock<mpsc::Sender<Box<Any + Send>>>,

output_filenames: Arc<OutputFilenames>,
}
@@ -1221,18 +1221,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
hir,
def_path_hash_to_def_id,
maps: maps::Maps::new(providers),
rcache: RefCell::new(FxHashMap()),
rcache: Lock::new(FxHashMap()),
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
crate_name: Symbol::intern(crate_name),
data_layout,
layout_interner: RefCell::new(FxHashSet()),
layout_depth: Cell::new(0),
derive_macros: RefCell::new(NodeMap()),
stability_interner: RefCell::new(FxHashSet()),
interpret_interner: Default::default(),
all_traits: RefCell::new(None),
tx_to_llvm_workers: tx,
layout_interner: Lock::new(FxHashSet()),
layout_depth: LockCell::new(0),
derive_macros: Lock::new(NodeMap()),
stability_interner: Lock::new(FxHashSet()),
interpret_interner: Lock::new(Default::default()),
all_traits: Lock::new(None),
tx_to_llvm_workers: Lock::new(tx),
output_filenames: Arc::new(output_filenames.clone()),
}, f)
}
@@ -17,12 +17,12 @@ use hir::map::definitions::DefPathHash;
use ich::{CachingCodemapView, Fingerprint};
use mir;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::{Lrc, Lock};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
SpecializedDecoder, SpecializedEncoder,
UseSpecializedDecodable, UseSpecializedEncodable};
use session::{CrateDisambiguator, Session};
use std::cell::RefCell;
use std::mem;
use syntax::ast::NodeId;
use syntax::codemap::{CodeMap, StableFilemapId};
@@ -55,17 +55,17 @@ pub struct OnDiskCache<'sess> {

// This field collects all Diagnostics emitted during the current
// compilation session.
current_diagnostics: RefCell<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
current_diagnostics: Lock<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,

prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
cnum_map: RefCell<Option<IndexVec<CrateNum, Option<CrateNum>>>>,
cnum_map: Lock<Option<IndexVec<CrateNum, Option<CrateNum>>>>,

codemap: &'sess CodeMap,
file_index_to_stable_id: FxHashMap<FileMapIndex, StableFilemapId>,

// These two fields caches that are populated lazily during decoding.
file_index_to_file: RefCell<FxHashMap<FileMapIndex, Rc<FileMap>>>,
synthetic_expansion_infos: RefCell<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
file_index_to_file: Lock<FxHashMap<FileMapIndex, Lrc<FileMap>>>,
synthetic_expansion_infos: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,

// A map from dep-node to the position of the cached query result in
// `serialized_data`.
@@ -131,29 +131,29 @@ impl<'sess> OnDiskCache<'sess> {
OnDiskCache {
serialized_data: data,
file_index_to_stable_id: footer.file_index_to_stable_id,
file_index_to_file: RefCell::new(FxHashMap()),
file_index_to_file: Lock::new(FxHashMap()),
prev_cnums: footer.prev_cnums,
cnum_map: RefCell::new(None),
cnum_map: Lock::new(None),
codemap: sess.codemap(),
current_diagnostics: RefCell::new(FxHashMap()),
current_diagnostics: Lock::new(FxHashMap()),
query_result_index: footer.query_result_index.into_iter().collect(),
prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
synthetic_expansion_infos: RefCell::new(FxHashMap()),
synthetic_expansion_infos: Lock::new(FxHashMap()),
}
}

pub fn new_empty(codemap: &'sess CodeMap) -> OnDiskCache<'sess> {
OnDiskCache {
serialized_data: Vec::new(),
file_index_to_stable_id: FxHashMap(),
file_index_to_file: RefCell::new(FxHashMap()),
file_index_to_file: Lock::new(FxHashMap()),
prev_cnums: vec![],
cnum_map: RefCell::new(None),
cnum_map: Lock::new(None),
codemap,
current_diagnostics: RefCell::new(FxHashMap()),
current_diagnostics: Lock::new(FxHashMap()),
query_result_index: FxHashMap(),
prev_diagnostics_index: FxHashMap(),
synthetic_expansion_infos: RefCell::new(FxHashMap()),
synthetic_expansion_infos: Lock::new(FxHashMap()),
}
}

@@ -359,9 +359,9 @@ impl<'sess> OnDiskCache<'sess> {
opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()),
codemap: self.codemap,
cnum_map: cnum_map.as_ref().unwrap(),
file_index_to_file: &mut file_index_to_file,
file_index_to_file: &mut *file_index_to_file,
file_index_to_stable_id: &self.file_index_to_stable_id,
synthetic_expansion_infos: &mut synthetic_expansion_infos,
synthetic_expansion_infos: &mut *synthetic_expansion_infos,
};

match decode_tagged(&mut decoder, dep_node_index) {
@@ -421,7 +421,7 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> {
codemap: &'x CodeMap,
cnum_map: &'x IndexVec<CrateNum, Option<CrateNum>>,
synthetic_expansion_infos: &'x mut FxHashMap<AbsoluteBytePos, SyntaxContext>,
file_index_to_file: &'x mut FxHashMap<FileMapIndex, Rc<FileMap>>,
file_index_to_file: &'x mut FxHashMap<FileMapIndex, Lrc<FileMap>>,
file_index_to_stable_id: &'x FxHashMap<FileMapIndex, StableFilemapId>,
}

@@ -20,7 +20,7 @@ use ty::maps::config::QueryDescription;
use ty::item_path;

use rustc_data_structures::fx::{FxHashMap};
use std::cell::{Ref, RefMut};
use rustc_data_structures::sync::LockGuard;
use std::marker::PhantomData;
use std::mem;
use syntax_pos::Span;
@@ -57,12 +57,12 @@ impl<'tcx, M: QueryDescription<'tcx>> QueryMap<'tcx, M> {

pub(super) trait GetCacheInternal<'tcx>: QueryDescription<'tcx> + Sized {
fn get_cache_internal<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
-> Ref<'a, QueryMap<'tcx, Self>>;
-> LockGuard<'a, QueryMap<'tcx, Self>>;
}

pub(super) struct CycleError<'a, 'tcx: 'a> {
span: Span,
cycle: RefMut<'a, [(Span, Query<'tcx>)]>,
cycle: LockGuard<'a, [(Span, Query<'tcx>)]>,
}

impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
@@ -112,7 +112,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
.find(|&(_, &(_, ref q))| *q == query) {
return Err(CycleError {
span,
cycle: RefMut::map(stack, |stack| &mut stack[i..])
cycle: LockGuard::map(stack, |stack| &mut stack[i..])
});
}
stack.push((span, query));
@@ -189,7 +189,7 @@ macro_rules! define_maps {
[$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => {

use dep_graph::DepNodeIndex;
use std::cell::RefCell;
use rustc_data_structures::sync::{Lock, LockGuard};

define_map_struct! {
tcx: $tcx,
@@ -201,8 +201,8 @@ macro_rules! define_maps {
-> Self {
Maps {
providers,
query_stack: RefCell::new(vec![]),
$($name: RefCell::new(QueryMap::new())),*
query_stack: Lock::new(vec![]),
$($name: Lock::new(QueryMap::new())),*
}
}
}
@@ -250,7 +250,7 @@ macro_rules! define_maps {

impl<$tcx> GetCacheInternal<$tcx> for queries::$name<$tcx> {
fn get_cache_internal<'a>(tcx: TyCtxt<'a, $tcx, $tcx>)
-> ::std::cell::Ref<'a, QueryMap<$tcx, Self>> {
-> LockGuard<'a, QueryMap<$tcx, Self>> {
tcx.maps.$name.borrow()
}
}
@@ -586,8 +586,8 @@ macro_rules! define_map_struct {
input: ($(([$(modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
pub struct Maps<$tcx> {
providers: IndexVec<CrateNum, Providers<$tcx>>,
query_stack: RefCell<Vec<(Span, Query<$tcx>)>>,
$($(#[$attr])* $name: RefCell<QueryMap<$tcx, queries::$name<$tcx>>>,)*
query_stack: Lock<Vec<(Span, Query<$tcx>)>>,
$($(#[$attr])* $name: Lock<QueryMap<$tcx, queries::$name<$tcx>>>,)*
}
};
}
@@ -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,18 +32,18 @@ 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
})
@@ -10,6 +10,8 @@

#![allow(non_camel_case_types)]

use rustc_data_structures::sync::LockCell;

use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::ffi::CString;
@@ -205,7 +207,7 @@ pub fn to_readable_str(mut val: usize) -> String {
groups.join("_")
}

pub fn record_time<T, F>(accu: &Cell<Duration>, f: F) -> T where
pub fn record_time<T, F>(accu: &LockCell<Duration>, f: F) -> T where
F: FnOnce() -> T,
{
let start = Instant::now();
@@ -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();
let _guard = tcx.mir_validated(owner_def_id).borrow();

// option dance because you can't capture an uninitialized variable
// by mut-ref.
@@ -35,11 +35,11 @@ use self::Level::*;

use emitter::{Emitter, EmitterWriter};

use rustc_data_structures::sync::{Lrc, Lock, LockCell, Send, Sync};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stable_hasher::StableHasher;

use std::borrow::Cow;
use std::cell::{RefCell, Cell};
use std::mem;
use std::{error, fmt};
use std::sync::atomic::AtomicUsize;
@@ -262,20 +262,20 @@ pub struct Handler {
pub flags: HandlerFlags,

err_count: AtomicUsize,
emitter: RefCell<Box<Emitter>>,
continue_after_error: Cell<bool>,
delayed_span_bug: RefCell<Option<Diagnostic>>,
tracked_diagnostics: RefCell<Option<Vec<Diagnostic>>>,
emitter: Lock<Box<Emitter + Send>>,
continue_after_error: LockCell<bool>,
delayed_span_bug: Lock<Option<Diagnostic>>,
tracked_diagnostics: Lock<Option<Vec<Diagnostic>>>,

// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
// emitting the same diagnostic with extended help (`--teach`) twice, which
// would be uneccessary repetition.
tracked_diagnostic_codes: RefCell<FxHashSet<DiagnosticId>>,
tracked_diagnostic_codes: Lock<FxHashSet<DiagnosticId>>,

// This set contains a hash of every diagnostic that has been emitted by
// this handler. These hashes is used to avoid emitting the same error
// twice.
emitted_diagnostics: RefCell<FxHashSet<u128>>,
emitted_diagnostics: Lock<FxHashSet<u128>>,
}

#[derive(Default)]
@@ -326,12 +326,12 @@ impl Handler {
Handler {
flags,
err_count: AtomicUsize::new(0),
emitter: RefCell::new(e),
continue_after_error: Cell::new(true),
delayed_span_bug: RefCell::new(None),
tracked_diagnostics: RefCell::new(None),
tracked_diagnostic_codes: RefCell::new(FxHashSet()),
emitted_diagnostics: RefCell::new(FxHashSet()),
emitter: Lock::new(e),
continue_after_error: LockCell::new(true),
delayed_span_bug: Lock::new(None),
tracked_diagnostics: Lock::new(None),
tracked_diagnostic_codes: Lock::new(FxHashSet()),
emitted_diagnostics: Lock::new(FxHashSet()),
}
}

@@ -345,7 +345,7 @@ impl Handler {
/// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as
/// the overall count of emitted error diagnostics.
pub fn reset_err_count(&self) {
self.emitted_diagnostics.replace(FxHashSet());
*self.emitted_diagnostics.borrow_mut() = FxHashSet();
self.err_count.store(0, SeqCst);
}

@@ -14,6 +14,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob};
use locator::{self, CratePaths};
use native_libs::relevant_lib;
use schema::CrateRoot;
use rustc_data_structures::sync::{Lrc, RwLock, Lock, LockCell};

use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX};
use rustc::hir::svh::Svh;
@@ -29,7 +30,6 @@ use rustc::util::common::record_time;
use rustc::util::nodemap::FxHashSet;
use rustc::hir::map::Definitions;

use std::cell::{RefCell, Cell};
use std::ops::Deref;
use std::path::PathBuf;
use std::{cmp, fs};
@@ -235,7 +235,7 @@ impl<'a> CrateLoader<'a> {

let mut cmeta = cstore::CrateMetadata {
name,
extern_crate: Cell::new(None),
extern_crate: LockCell::new(None),
def_path_table: Lrc::new(def_path_table),
exported_symbols,
trait_impls,
@@ -244,11 +244,11 @@ impl<'a> CrateLoader<'a> {
}),
root: crate_root,
blob: metadata,
cnum_map: RefCell::new(cnum_map),
cnum_map: Lock::new(cnum_map),
cnum,
codemap_import_info: RefCell::new(vec![]),
attribute_cache: RefCell::new([Vec::new(), Vec::new()]),
dep_kind: Cell::new(dep_kind),
codemap_import_info: RwLock::new(vec![]),
attribute_cache: Lock::new([Vec::new(), Vec::new()]),
dep_kind: LockCell::new(dep_kind),
source: cstore::CrateSource {
dylib,
rlib,
@@ -22,7 +22,7 @@ use rustc_back::PanicStrategy;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};

use std::cell::{RefCell, Cell};
use rustc_data_structures::sync::{Sync, Lrc, RwLock, Lock, LockCell};
use syntax::{ast, attr};
use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
@@ -61,13 +61,13 @@ pub struct CrateMetadata {
/// Information about the extern crate that caused this crate to
/// be loaded. If this is `None`, then the crate was injected
/// (e.g., by the allocator)
pub extern_crate: Cell<Option<ExternCrate>>,
pub extern_crate: LockCell<Option<ExternCrate>>,

pub blob: MetadataBlob,
pub cnum_map: RefCell<CrateNumMap>,
pub cnum_map: Lock<CrateNumMap>,
pub cnum: CrateNum,
pub codemap_import_info: RefCell<Vec<ImportedFileMap>>,
pub attribute_cache: RefCell<[Vec<Option<Rc<[ast::Attribute]>>>; 2]>,
pub codemap_import_info: RwLock<Vec<ImportedFileMap>>,
pub attribute_cache: Lock<[Vec<Option<Lrc<[ast::Attribute]>>>; 2]>,

pub root: schema::CrateRoot,

@@ -82,7 +82,7 @@ pub struct CrateMetadata {

pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>,

pub dep_kind: Cell<DepKind>,
pub dep_kind: LockCell<DepKind>,
pub source: CrateSource,

pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>,
@@ -91,17 +91,17 @@ pub struct CrateMetadata {
}

pub struct CStore {
metas: RefCell<IndexVec<CrateNum, Option<Rc<CrateMetadata>>>>,
metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
/// Map from NodeId's of local extern crate statements to crate numbers
extern_mod_crate_map: RefCell<NodeMap<CrateNum>>,
extern_mod_crate_map: Lock<NodeMap<CrateNum>>,
pub metadata_loader: Box<MetadataLoader + Sync>,
}

impl CStore {
pub fn new(metadata_loader: Box<MetadataLoader + Sync>) -> CStore {
CStore {
metas: RefCell::new(IndexVec::new()),
extern_mod_crate_map: RefCell::new(FxHashMap()),
metas: RwLock::new(IndexVec::new()),
extern_mod_crate_map: Lock::new(FxHashMap()),
metadata_loader,
}
}
@@ -13,6 +13,7 @@
use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary};
use schema::*;

use rustc_data_structures::sync::{Lrc, ReadGuard};
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc::hir;
use rustc::middle::cstore::{LinkagePreference, ExternConstBody,
@@ -29,7 +30,6 @@ use rustc::ty::codec::TyDecoder;
use rustc::util::nodemap::DefIdSet;
use rustc::mir::Mir;

use std::cell::Ref;
use std::collections::BTreeMap;
use std::io;
use std::mem;
@@ -1098,7 +1098,7 @@ impl<'a, 'tcx> CrateMetadata {
/// for items inlined from other crates.
pub fn imported_filemaps(&'a self,
local_codemap: &codemap::CodeMap)
-> Ref<'a, Vec<cstore::ImportedFileMap>> {
-> ReadGuard<'a, Vec<cstore::ImportedFileMap>> {
{
let filemaps = self.codemap_import_info.borrow();
if !filemaps.is_empty() {
@@ -1000,7 +1000,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,
@@ -1393,7 +1393,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 mut exported_symbols = FxHashMap();
exported_symbols.insert(LOCAL_CRATE, tcx.exported_symbols(LOCAL_CRATE));
for &cnum in tcx.crates().iter() {
@@ -2270,7 +2270,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,
})));
@@ -21,6 +21,7 @@ use namespace::Namespace;
use rustc::traits::{Obligation, SelectionContext};
use util::nodemap::FxHashSet;

use rustc_data_structures::sync::LockGuard;
use syntax::ast;
use errors::DiagnosticBuilder;
use syntax_pos::Span;
@@ -29,7 +30,6 @@ use rustc::hir;
use rustc::hir::print;
use rustc::infer::type_variable::TypeVariableOrigin;

use std::cell;
use std::cmp::Ordering;

use super::{MethodError, NoMatchData, CandidateSource};
@@ -702,7 +702,7 @@ pub fn all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> AllTraits<'a>
}

pub struct AllTraits<'a> {
borrow: cell::Ref<'a, Option<AllTraitsVec>>,
borrow: LockGuard<'a, Option<AllTraitsVec>>,
idx: usize,
}

@@ -24,7 +24,7 @@ pub use self::ExpnFormat::*;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::StableHasher;
use std::cell::{RefCell, Ref};
use rustc_data_structures::sync::{Lrc, Lock, LockGuard};
use std::cmp;
use std::hash::Hash;
use std::path::{Path, PathBuf};
@@ -125,12 +125,12 @@ impl StableFilemapId {
//

pub struct CodeMap {
pub(super) files: RefCell<Vec<Rc<FileMap>>>,
pub(super) files: Lock<Vec<Lrc<FileMap>>>,
file_loader: Box<FileLoader + Sync + Send>,
// This is used to apply the file path remapping as specified via
// -Zremap-path-prefix to all FileMaps allocated within this CodeMap.
path_mapping: FilePathMapping,
stable_id_to_filemap: RefCell<FxHashMap<StableFilemapId, Rc<FileMap>>>,
stable_id_to_filemap: Lock<FxHashMap<StableFilemapId, Lrc<FileMap>>>,
/// In case we are in a doctest, replace all file names with the PathBuf,
/// and add the given offsets to the line info
doctest_offset: Option<(FileName, isize)>,
@@ -139,10 +139,10 @@ pub struct CodeMap {
impl CodeMap {
pub fn new(path_mapping: FilePathMapping) -> CodeMap {
CodeMap {
files: RefCell::new(Vec::new()),
files: Lock::new(Vec::new()),
file_loader: Box::new(RealFileLoader),
path_mapping,
stable_id_to_filemap: RefCell::new(FxHashMap()),
stable_id_to_filemap: Lock::new(FxHashMap()),
doctest_offset: None,
}
}
@@ -160,10 +160,10 @@ impl CodeMap {
path_mapping: FilePathMapping)
-> CodeMap {
CodeMap {
files: RefCell::new(Vec::new()),
file_loader,
files: Lock::new(Vec::new()),
file_loader: file_loader,
path_mapping,
stable_id_to_filemap: RefCell::new(FxHashMap()),
stable_id_to_filemap: Lock::new(FxHashMap()),
doctest_offset: None,
}
}
@@ -186,7 +186,7 @@ impl CodeMap {
Ok(self.new_filemap(filename, src))
}

pub fn files(&self) -> Ref<Vec<Rc<FileMap>>> {
pub fn files(&self) -> LockGuard<Vec<Lrc<FileMap>>> {
self.files.borrow()
}

@@ -296,12 +296,12 @@ impl CodeMap {
crate_of_origin,
src: None,
src_hash,
external_src: RefCell::new(ExternalSource::AbsentOk),
external_src: Lock::new(ExternalSource::AbsentOk),
start_pos,
end_pos,
lines: RefCell::new(file_local_lines),
multibyte_chars: RefCell::new(file_local_multibyte_chars),
non_narrow_chars: RefCell::new(file_local_non_narrow_chars),
lines: Lock::new(file_local_lines),
multibyte_chars: Lock::new(file_local_multibyte_chars),
non_narrow_chars: Lock::new(file_local_non_narrow_chars),
name_hash,
});

@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use rustc_data_structures::sync::RwLock;

use {ast, attr};
use syntax_pos::{Span, DUMMY_SP};
use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
@@ -26,7 +28,6 @@ use parse::token::Token::*;
use symbol::Symbol;
use tokenstream::{TokenStream, TokenTree};

use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::hash_map::Entry;

@@ -184,7 +185,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
// Holy self-referential!

/// Converts a `macro_rules!` invocation into a syntax extension.
pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item) -> SyntaxExtension {
pub fn compile(sess: &ParseSess, features: &RwLock<Features>, def: &ast::Item) -> SyntaxExtension {
let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs"));
let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs"));

@@ -294,7 +295,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
}

fn check_lhs_nt_follows(sess: &ParseSess,
features: &RefCell<Features>,
features: &RwLock<Features>,
attrs: &[ast::Attribute],
lhs: &quoted::TokenTree) -> bool {
// lhs is going to be like TokenTree::Delimited(...), where the
@@ -351,7 +352,7 @@ fn check_rhs(sess: &ParseSess, rhs: &quoted::TokenTree) -> bool {
}

fn check_matcher(sess: &ParseSess,
features: &RefCell<Features>,
features: &RwLock<Features>,
attrs: &[ast::Attribute],
matcher: &[quoted::TokenTree]) -> bool {
let first_sets = FirstSets::new(matcher);
@@ -599,7 +600,7 @@ impl TokenSet {
// Requires that `first_sets` is pre-computed for `matcher`;
// see `FirstSets::new`.
fn check_matcher_core(sess: &ParseSess,
features: &RefCell<Features>,
features: &RwLock<Features>,
attrs: &[ast::Attribute],
first_sets: &FirstSets,
matcher: &[quoted::TokenTree],
@@ -867,7 +868,7 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> Result<bool, (String, &'
}

fn has_legal_fragment_specifier(sess: &ParseSess,
features: &RefCell<Features>,
features: &RwLock<Features>,
attrs: &[ast::Attribute],
tok: &quoted::TokenTree) -> Result<(), String> {
debug!("has_legal_fragment_specifier({:?})", tok);
@@ -882,7 +883,7 @@ fn has_legal_fragment_specifier(sess: &ParseSess,
}

fn is_legal_fragment_specifier(sess: &ParseSess,
features: &RefCell<Features>,
features: &RwLock<Features>,
attrs: &[ast::Attribute],
frag_name: &str,
frag_span: Span) -> bool {
@@ -1743,10 +1743,10 @@ 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;
use rustc_data_structures::sync::{Lrc, Lock};
fn mk_sess(cm: Lrc<CodeMap>) -> ParseSess {
let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()),
Some(cm.clone()),
@@ -1756,10 +1756,10 @@ 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()),
non_modrs_mods: RefCell::new(vec![]),
missing_fragment_specifiers: Lock::new(HashSet::new()),
non_modrs_mods: Lock::new(vec![]),
}
}

@@ -10,6 +10,7 @@

//! The main parser interface

use rustc_data_structures::sync::{Lrc, Lock};
use ast::{self, CrateConfig};
use codemap::{CodeMap, FilePathMapping};
use syntax_pos::{self, Span, FileMap, NO_EXPANSION, FileName};
@@ -21,7 +22,6 @@ use str::char_at;
use symbol::Symbol;
use tokenstream::{TokenStream, TokenTree};

use std::cell::RefCell;
use std::collections::HashSet;
use std::iter;
use std::path::{Path, PathBuf};
@@ -45,12 +45,12 @@ 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>>,
// 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>,
}

@@ -69,10 +69,10 @@ impl ParseSess {
span_diagnostic: handler,
unstable_features: UnstableFeatures::from_environment(),
config: HashSet::new(),
missing_fragment_specifiers: RefCell::new(HashSet::new()),
included_mod_stack: RefCell::new(vec![]),
missing_fragment_specifiers: Lock::new(HashSet::new()),
included_mod_stack: Lock::new(vec![]),
code_map,
non_modrs_mods: RefCell::new(vec![]),
non_modrs_mods: Lock::new(vec![]),
}
}

@@ -25,8 +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, LockCell};

#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
pub enum BinOpToken {
@@ -578,13 +578,13 @@ pub fn is_op(tok: &Token) -> bool {
}
}

pub struct LazyTokenStream(Cell<Option<TokenStream>>);
pub struct LazyTokenStream(LockCell<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))
LazyTokenStream(LockCell::new(opt_stream))
}
}

@@ -603,7 +603,7 @@ impl fmt::Debug for LazyTokenStream {

impl LazyTokenStream {
pub fn new() -> Self {
LazyTokenStream(Cell::new(None))
LazyTokenStream(LockCell::new(None))
}

pub fn force<F: FnOnce() -> TokenStream>(&self, f: F) -> TokenStream {
@@ -27,14 +27,15 @@
#![feature(specialization)]

use std::borrow::Cow;
use std::cell::{Cell, RefCell};
use std::cell::Cell;
use std::cmp::{self, Ordering};
use std::fmt;
use std::hash::{Hasher, Hash};
use std::ops::{Add, Sub};
use std::path::PathBuf;

use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::{Lrc, Lock};

#[macro_use]
extern crate rustc_data_structures;
@@ -677,17 +678,17 @@ pub struct FileMap {
pub src_hash: u128,
/// The external source code (used for external crates, which will have a `None`
/// value as `self.src`.
pub external_src: RefCell<ExternalSource>,
pub external_src: Lock<ExternalSource>,
/// The start position of this source in the CodeMap
pub start_pos: BytePos,
/// The end position of this source in the CodeMap
pub end_pos: BytePos,
/// Locations of lines beginnings in the source code
pub lines: RefCell<Vec<BytePos>>,
pub lines: Lock<Vec<BytePos>>,
/// Locations of multi-byte characters in the source code
pub multibyte_chars: RefCell<Vec<MultiByteChar>>,
pub multibyte_chars: Lock<Vec<MultiByteChar>>,
/// Width of characters that are not narrow in the source code
pub non_narrow_chars: RefCell<Vec<NonNarrowChar>>,
pub non_narrow_chars: Lock<Vec<NonNarrowChar>>,
/// A hash of the filename, used for speeding up the incr. comp. hashing.
pub name_hash: u128,
}
@@ -817,10 +818,10 @@ impl Decodable for FileMap {
end_pos,
src: None,
src_hash,
external_src: RefCell::new(ExternalSource::AbsentOk),
lines: RefCell::new(lines),
multibyte_chars: RefCell::new(multibyte_chars),
non_narrow_chars: RefCell::new(non_narrow_chars),
external_src: Lock::new(ExternalSource::AbsentOk),
lines: Lock::new(lines),
multibyte_chars: Lock::new(multibyte_chars),
non_narrow_chars: Lock::new(non_narrow_chars),
name_hash,
})
})
@@ -860,12 +861,12 @@ impl FileMap {
crate_of_origin: 0,
src: Some(Lrc::new(src)),
src_hash,
external_src: RefCell::new(ExternalSource::Unneeded),
external_src: Lock::new(ExternalSource::Unneeded),
start_pos,
end_pos: Pos::from_usize(end_pos),
lines: RefCell::new(Vec::new()),
multibyte_chars: RefCell::new(Vec::new()),
non_narrow_chars: RefCell::new(Vec::new()),
lines: Lock::new(Vec::new()),
multibyte_chars: Lock::new(Vec::new()),
non_narrow_chars: Lock::new(Vec::new()),
name_hash,
}
}