/// A mutable memory location.
///
+/// # Examples
+///
+/// Here you can see how using `Cell<T>` allows to use mutable field inside
+/// immutable struct (which is also called 'interior mutability').
+///
+/// ```
+/// use std::cell::Cell;
+///
+/// struct SomeStruct {
+/// regular_field: u8,
+/// special_field: Cell<u8>,
+/// }
+///
+/// let my_struct = SomeStruct {
+/// regular_field: 0,
+/// special_field: Cell::new(1),
+/// };
+///
+/// let new_value = 100;
+///
+/// // ERROR, because my_struct is immutable
+/// // my_struct.regular_field = new_value;
+///
+/// // WORKS, although `my_struct` is immutable, field `special_field` is mutable because it is Cell
+/// my_struct.special_field.set(new_value);
+/// assert_eq!(my_struct.special_field.get(), new_value);
+/// ```
+///
/// See the [module-level documentation](index.html) for more.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Cell<T> {
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace,
CRATE_DEF_INDEX};
use ich::Fingerprint;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::stable_hasher::StableHasher;
use serialize::{Encodable, Decodable, Encoder, Decoder};
pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
macro_def_scopes: FxHashMap<Mark, DefId>,
expansions: FxHashMap<DefIndex, Mark>,
- keys_created: FxHashSet<DefKey>,
+ next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
}
// Unfortunately we have to provide a manual impl of Clone because of the
node_to_hir_id: self.node_to_hir_id.clone(),
macro_def_scopes: self.macro_def_scopes.clone(),
expansions: self.expansions.clone(),
- keys_created: self.keys_created.clone(),
+ next_disambiguator: self.next_disambiguator.clone(),
}
}
}
node_to_hir_id: IndexVec::new(),
macro_def_scopes: FxHashMap(),
expansions: FxHashMap(),
- keys_created: FxHashSet(),
+ next_disambiguator: FxHashMap(),
}
}
// The root node must be created with create_root_def()
assert!(data != DefPathData::CrateRoot);
- // Find a unique DefKey. This basically means incrementing the disambiguator
- // until we get no match.
- let mut key = DefKey {
+ // Find the next free disambiguator for this key.
+ let disambiguator = {
+ let next_disamb = self.next_disambiguator.entry((parent, data.clone())).or_insert(0);
+ let disambiguator = *next_disamb;
+ *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow");
+ disambiguator
+ };
+
+ let key = DefKey {
parent: Some(parent),
disambiguated_data: DisambiguatedDefPathData {
- data,
- disambiguator: 0
+ data, disambiguator
}
};
- while self.keys_created.contains(&key) {
- key.disambiguated_data.disambiguator += 1;
- }
- self.keys_created.insert(key.clone());
-
let parent_hash = self.table.def_path_hash(parent);
let def_path_hash = key.compute_stable_hash(parent_hash);
pub method_has_self_argument: bool,
}
-#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, RustcEncodable, RustcDecodable)]
pub enum AssociatedKind {
Const,
Method,
pub struct Union;
impl BitwiseOperator for Union {
+ #[inline]
fn join(&self, a: usize, b: usize) -> usize { a | b }
}
pub struct Subtract;
impl BitwiseOperator for Subtract {
+ #[inline]
fn join(&self, a: usize, b: usize) -> usize { a & !b }
}
///
/// If this archive is used with a mutable method, then an error will be
/// raised.
- pub fn open(dst: &Path) -> Option<ArchiveRO> {
+ pub fn open(dst: &Path) -> Result<ArchiveRO, String> {
return unsafe {
let s = path2cstr(dst);
let ar = ::LLVMRustOpenArchive(s.as_ptr());
if ar.is_null() {
- None
+ Err(::last_error().unwrap_or("failed to open archive".to_string()))
} else {
- Some(ArchiveRO { ptr: ar })
+ Ok(ArchiveRO { ptr: ar })
}
};
Some(ref src) => src,
None => return None,
};
- self.src_archive = Some(ArchiveRO::open(src));
+ self.src_archive = Some(ArchiveRO::open(src).ok());
self.src_archive.as_ref().unwrap().as_ref()
}
where F: FnMut(&str) -> bool + 'static
{
let archive = match ArchiveRO::open(archive) {
- Some(ar) => ar,
- None => return Err(io::Error::new(io::ErrorKind::Other,
- "failed to open archive")),
+ Ok(ar) => ar,
+ Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)),
};
self.additions.push(Addition::Archive {
archive: archive,
let cgu_name = String::from(cgu.name());
let cgu_id = cgu.work_product_id();
- let symbol_name_hash = cgu.compute_symbol_name_hash(scx, &exported_symbols);
+ let symbol_name_hash = cgu.compute_symbol_name_hash(scx);
// Check whether there is a previous work-product we can
// re-use. Not only must the file exist, and the inputs not
// just keeping the archive along while the metadata is in use.
let archive = ArchiveRO::open(filename)
.map(|ar| OwningRef::new(box ar))
- .ok_or_else(|| {
- debug!("llvm didn't like `{}`", filename.display());
- format!("failed to read rlib metadata: '{}'", filename.display())
- })?;
+ .map_err(|e| {
+ debug!("llvm didn't like `{}`: {}", filename.display(), e);
+ format!("failed to read rlib metadata in '{}': {}", filename.display(), e)
+ })?;
let buf: OwningRef<_, [u8]> = archive
.try_map(|ar| {
ar.iter()
.find(|sect| sect.name() == Some(METADATA_FILENAME))
.map(|s| s.data())
.ok_or_else(|| {
- debug!("didn't find '{}' in the archive", METADATA_FILENAME);
- format!("failed to read rlib metadata: '{}'",
- filename.display())
- })
+ debug!("didn't find '{}' in the archive", METADATA_FILENAME);
+ format!("failed to read rlib metadata: '{}'",
+ filename.display())
+ })
})?;
Ok(buf.erase_owner())
}
}
pub fn compute_symbol_name_hash<'a>(&self,
- scx: &SharedCrateContext<'a, 'tcx>,
- exported_symbols: &ExportedSymbols)
+ scx: &SharedCrateContext<'a, 'tcx>)
-> u64 {
let mut state = IchHasher::new();
- let exported_symbols = exported_symbols.local_exports();
let all_items = self.items_in_deterministic_order(scx.tcx());
- for (item, _) in all_items {
+ for (item, (linkage, visibility)) in all_items {
let symbol_name = item.symbol_name(scx.tcx());
symbol_name.len().hash(&mut state);
symbol_name.hash(&mut state);
- let exported = match item {
- TransItem::Fn(ref instance) => {
- let node_id =
- scx.tcx().hir.as_local_node_id(instance.def_id());
- node_id.map(|node_id| exported_symbols.contains(&node_id))
- .unwrap_or(false)
- }
- TransItem::Static(node_id) => {
- exported_symbols.contains(&node_id)
- }
- TransItem::GlobalAsm(..) => true,
- };
- exported.hash(&mut state);
+ linkage.hash(&mut state);
+ visibility.hash(&mut state);
}
state.finish().to_smaller_hash()
}
border-bottom: 1px solid;
}
-.docblock h1 { font-size: 1.3em; }
-.docblock h2 { font-size: 1.15em; }
-.docblock h3, .docblock h4, .docblock h5 { font-size: 1em; }
+#main > .docblock h1 { font-size: 1.3em; }
+#main > .docblock h2 { font-size: 1.15em; }
+#main > .docblock h3, #main > .docblock h4, #main > .docblock h5 { font-size: 1em; }
+
+.docblock h1 { font-size: 1em; }
+.docblock h2 { font-size: 0.95em; }
+.docblock h3, .docblock h4, .docblock h5 { font-size: 0.9em; }
.docblock {
margin-left: 24px;
}
impl<T: Hash + Eq> HashSet<T, RandomState> {
- /// Creates an empty HashSet.
+ /// Creates an empty `HashSet`.
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
- /// let mut set: HashSet<i32> = HashSet::new();
+ /// let set: HashSet<i32> = HashSet::new();
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
///
/// ```
/// use std::collections::HashSet;
- /// let mut set: HashSet<i32> = HashSet::with_capacity(10);
+ /// let set: HashSet<i32> = HashSet::with_capacity(10);
+ /// assert!(set.capacity() >= 10);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
/// Returns a reference to the set's [`BuildHasher`].
///
/// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// use std::collections::hash_map::RandomState;
+ ///
+ /// let hasher = RandomState::new();
+ /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
+ /// let hasher: &RandomState = set.hasher();
+ /// ```
#[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
pub fn hasher(&self) -> &S {
self.map.hasher()
/// use std::collections::HashSet;
/// let mut set: HashSet<i32> = HashSet::new();
/// set.reserve(10);
+ /// assert!(set.capacity() >= 10);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn reserve(&mut self, additional: usize) {
/// println!("{}", x); // Print 1
/// }
///
- /// let diff: HashSet<_> = a.difference(&b).cloned().collect();
- /// assert_eq!(diff, [1].iter().cloned().collect());
+ /// let diff: HashSet<_> = a.difference(&b).collect();
+ /// assert_eq!(diff, [1].iter().collect());
///
/// // Note that difference is not symmetric,
/// // and `b - a` means something else:
- /// let diff: HashSet<_> = b.difference(&a).cloned().collect();
- /// assert_eq!(diff, [4].iter().cloned().collect());
+ /// let diff: HashSet<_> = b.difference(&a).collect();
+ /// assert_eq!(diff, [4].iter().collect());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> {
/// println!("{}", x);
/// }
///
- /// let diff1: HashSet<_> = a.symmetric_difference(&b).cloned().collect();
- /// let diff2: HashSet<_> = b.symmetric_difference(&a).cloned().collect();
+ /// let diff1: HashSet<_> = a.symmetric_difference(&b).collect();
+ /// let diff2: HashSet<_> = b.symmetric_difference(&a).collect();
///
/// assert_eq!(diff1, diff2);
- /// assert_eq!(diff1, [1, 4].iter().cloned().collect());
+ /// assert_eq!(diff1, [1, 4].iter().collect());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn symmetric_difference<'a>(&'a self,
/// println!("{}", x);
/// }
///
- /// let intersection: HashSet<_> = a.intersection(&b).cloned().collect();
- /// assert_eq!(intersection, [2, 3].iter().cloned().collect());
+ /// let intersection: HashSet<_> = a.intersection(&b).collect();
+ /// assert_eq!(intersection, [2, 3].iter().collect());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> {
/// println!("{}", x);
/// }
///
- /// let union: HashSet<_> = a.union(&b).cloned().collect();
- /// assert_eq!(union, [1, 2, 3, 4].iter().cloned().collect());
+ /// let union: HashSet<_> = a.union(&b).collect();
+ /// assert_eq!(union, [1, 2, 3, 4].iter().collect());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
}
/// Clears the set, returning all elements in an iterator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let mut set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// assert!(!set.is_empty());
+ ///
+ /// // print 1, 2, 3 in an arbitrary order
+ /// for i in set.drain() {
+ /// println!("{}", i);
+ /// }
+ ///
+ /// assert!(set.is_empty());
+ /// ```
#[inline]
#[stable(feature = "drain", since = "1.6.0")]
pub fn drain(&mut self) -> Drain<T> {
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
#[stable(feature = "pthread_t", since = "1.8.0")]
-pub type pthread_t = usize;
+pub type pthread_t = u32;
#[repr(C)]
#[derive(Clone)]
sp
}
fn ensure_filemap_source_present(&self, file_map: Rc<FileMap>) -> bool {
- let src = self.file_loader.read_file(Path::new(&file_map.name)).ok();
- return file_map.add_external_src(src)
+ file_map.add_external_src(
+ || self.file_loader.read_file(Path::new(&file_map.name)).ok()
+ )
}
}
/// If the hash of the input doesn't match or no input is supplied via None,
/// it is interpreted as an error and the corresponding enum variant is set.
/// The return value signifies whether some kind of source is present.
- pub fn add_external_src(&self, src: Option<String>) -> bool {
+ pub fn add_external_src<F>(&self, get_src: F) -> bool
+ where F: FnOnce() -> Option<String>
+ {
if *self.external_src.borrow() == ExternalSource::AbsentOk {
+ let src = get_src();
let mut external_src = self.external_src.borrow_mut();
if let Some(src) = src {
let mut hasher: StableHasher<u128> = StableHasher::new();
extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
const char *Feature) {
+#if LLVM_RUSTLLVM
TargetMachine *Target = unwrap(TM);
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
const FeatureBitset &Bits = MCInfo->getFeatureBits();
-#if LLVM_VERSION_GE(4, 0)
const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
for (auto &FeatureEntry : FeatTable)