use locator::{self, CratePaths};
use native_libs::relevant_lib;
use schema::CrateRoot;
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{Lrc, RwLock, Lock};
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX};
use rustc::hir::svh::Svh;
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};
info!(" name: {}", data.name());
info!(" cnum: {}", data.cnum);
info!(" hash: {}", data.hash());
- info!(" reqd: {:?}", data.dep_kind.get());
+ info!(" reqd: {:?}", *data.dep_kind.lock());
let CrateSource { dylib, rlib, rmeta } = data.source.clone();
dylib.map(|dl| info!(" dylib: {}", dl.0.display()));
rlib.map(|rl| info!(" rlib: {}", rl.0.display()));
let mut cmeta = cstore::CrateMetadata {
name,
- extern_crate: Cell::new(None),
+ extern_crate: Lock::new(None),
def_path_table: Lrc::new(def_path_table),
trait_impls,
proc_macros: crate_root.macro_derive_registrar.map(|_| {
}),
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: Lock::new(dep_kind),
source: cstore::CrateSource {
dylib,
rlib,
if data.root.macro_derive_registrar.is_some() {
dep_kind = DepKind::UnexportedMacrosOnly;
}
- data.dep_kind.set(cmp::max(data.dep_kind.get(), dep_kind));
+ data.dep_kind.with_lock(|data_dep_kind| {
+ *data_dep_kind = cmp::max(*data_dep_kind, dep_kind);
+ });
(cnum, data)
}
LoadResult::Loaded(library) => {
if !visited.insert((cnum, extern_crate.direct)) { return }
let cmeta = self.cstore.get_crate_data(cnum);
- let old_extern_crate = cmeta.extern_crate.get();
+ let mut old_extern_crate = cmeta.extern_crate.borrow_mut();
// Prefer:
// - something over nothing (tuple.0);
// - direct extern crate to indirect (tuple.1);
// - shorter paths to longer (tuple.2).
let new_rank = (true, extern_crate.direct, !extern_crate.path_len);
- let old_rank = match old_extern_crate {
+ let old_rank = match *old_extern_crate {
None => (false, false, !0),
Some(ref c) => (true, c.direct, !c.path_len),
};
return; // no change needed
}
- cmeta.extern_crate.set(Some(extern_crate));
+ *old_extern_crate = Some(extern_crate);
+ drop(old_extern_crate);
+
// Propagate the extern crate info to dependencies.
extern_crate.direct = false;
for &dep_cnum in cmeta.cnum_map.borrow().iter() {
// #![panic_runtime] crate.
self.inject_dependency_if(cnum, "a panic runtime",
&|data| data.needs_panic_runtime(sess));
- runtime_found = runtime_found || data.dep_kind.get() == DepKind::Explicit;
+ runtime_found = runtime_found || *data.dep_kind.lock() == DepKind::Explicit;
}
});
use rustc_data_structures::indexed_vec::IndexVec;
use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap};
-use std::cell::{RefCell, Cell};
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{Lrc, RwLock, Lock};
use syntax::{ast, attr};
use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
/// 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: Lock<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<Lrc<[ast::Attribute]>>>; 2]>,
+ pub codemap_import_info: RwLock<Vec<ImportedFileMap>>,
+ pub attribute_cache: Lock<[Vec<Option<Lrc<[ast::Attribute]>>>; 2]>,
pub root: schema::CrateRoot,
pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>,
- pub dep_kind: Cell<DepKind>,
+ pub dep_kind: Lock<DepKind>,
pub source: CrateSource,
pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>,
is_sanitizer_runtime => { cdata.is_sanitizer_runtime(tcx.sess) }
is_profiler_runtime => { cdata.is_profiler_runtime(tcx.sess) }
panic_strategy => { cdata.panic_strategy() }
- extern_crate => { Lrc::new(cdata.extern_crate.get()) }
+ extern_crate => {
+ let r = Lrc::new(*cdata.extern_crate.lock());
+ r
+ }
is_no_builtins => { cdata.is_no_builtins(tcx.sess) }
impl_defaultness => { cdata.get_impl_defaultness(def_id.index) }
reachable_non_generics => {
cdata.is_dllimport_foreign_item(def_id.index)
}
visibility => { cdata.get_visibility(def_id.index) }
- dep_kind => { cdata.dep_kind.get() }
+ dep_kind => {
+ let r = *cdata.dep_kind.lock();
+ r
+ }
crate_name => { cdata.name }
item_children => {
let mut result = vec![];
}
missing_extern_crate_item => {
- match cdata.extern_crate.get() {
+ let r = match *cdata.extern_crate.borrow() {
Some(extern_crate) if !extern_crate.direct => true,
_ => false,
- }
+ };
+ r
}
used_crate_source => { Lrc::new(cdata.source.clone()) }
fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind
{
- self.get_crate_data(cnum).dep_kind.get()
+ let data = self.get_crate_data(cnum);
+ let r = *data.dep_kind.lock();
+ r
}
fn export_macros_untracked(&self, cnum: CrateNum) {
let data = self.get_crate_data(cnum);
- if data.dep_kind.get() == DepKind::UnexportedMacrosOnly {
- data.dep_kind.set(DepKind::MacrosOnly)
+ let mut dep_kind = data.dep_kind.lock();
+ if *dep_kind == DepKind::UnexportedMacrosOnly {
+ *dep_kind = DepKind::MacrosOnly;
}
}
use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary};
use schema::*;
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{Lrc, ReadGuard};
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc::hir;
use rustc::middle::cstore::{LinkagePreference, ExternConstBody,
use rustc::mir::Mir;
use rustc::util::nodemap::FxHashMap;
-use std::cell::Ref;
use std::collections::BTreeMap;
use std::io;
use std::mem;
};
// Iterate over all children.
- let macros_only = self.dep_kind.get().macros_only();
+ let macros_only = self.dep_kind.lock().macros_only();
for child_index in item.children.decode((self, sess)) {
if macros_only {
continue
if vec_.len() < node_index + 1 {
vec_.resize(node_index + 1, None);
}
+ // This can overwrite the result produced by another thread, but the value
+ // written should be the same
vec_[node_index] = Some(result.clone());
result
}
/// 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() {
}
}
+ // Lock the codemap_import_info to ensure this only happens once
+ let mut codemap_import_info = self.codemap_import_info.borrow_mut();
+
+ if !codemap_import_info.is_empty() {
+ drop(codemap_import_info);
+ return self.codemap_import_info.borrow();
+ }
+
let external_codemap = self.root.codemap.decode(self);
let imported_filemaps = external_codemap.map(|filemap_to_import| {
}
}).collect();
+ *codemap_import_info = imported_filemaps;
+ drop(codemap_import_info);
+
// This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref.
- *self.codemap_import_info.borrow_mut() = imported_filemaps;
self.codemap_import_info.borrow()
}
}