diff options
| author | bors <bors@rust-lang.org> | 2015-01-08 05:35:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-01-08 05:35:51 +0000 |
| commit | 5b3cd3900ceda838f5798c30ab96ceb41f962534 (patch) | |
| tree | 7593bacffb7c8111eee7fa2a0a05d0357ccba763 /src/libstd | |
| parent | 9f1ead8fadc56bad30dc74f5cc50d78af4fbc972 (diff) | |
| parent | 0abf4583486071a958aa1bd14ab8c5b8870fb74d (diff) | |
| download | rust-5b3cd3900ceda838f5798c30ab96ceb41f962534.tar.gz rust-5b3cd3900ceda838f5798c30ab96ceb41f962534.zip | |
auto merge of #20733 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libstd')
44 files changed, 627 insertions, 501 deletions
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index 5764962b51b..8dc41368e7f 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -273,7 +273,7 @@ macro_rules! bitflags { #[cfg(test)] #[allow(non_upper_case_globals)] mod tests { - use hash; + use hash::{self, SipHasher}; use option::Option::{Some, None}; bitflags! { @@ -467,9 +467,9 @@ mod tests { fn test_hash() { let mut x = Flags::empty(); let mut y = Flags::empty(); - assert!(hash::hash(&x) == hash::hash(&y)); + assert!(hash::hash::<Flags, SipHasher>(&x) == hash::hash::<Flags, SipHasher>(&y)); x = Flags::all(); y = FlagABC; - assert!(hash::hash(&x) == hash::hash(&y)); + assert!(hash::hash::<Flags, SipHasher>(&x) == hash::hash::<Flags, SipHasher>(&y)); } } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index c3381d5cd64..c3bdfbb12d8 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -19,16 +19,15 @@ use clone::Clone; use cmp::{max, Eq, PartialEq}; use default::Default; use fmt::{self, Show}; -use hash::{Hash, Hasher, RandomSipHasher}; +use hash::{self, Hash, SipHasher}; use iter::{self, Iterator, IteratorExt, FromIterator, Extend, Map}; use marker::Sized; use mem::{self, replace}; use num::{Int, UnsignedInt}; use ops::{Deref, FnMut, Index, IndexMut}; -use option::Option; -use option::Option::{Some, None}; -use result::Result; -use result::Result::{Ok, Err}; +use option::Option::{self, Some, None}; +use rand::{self, Rng}; +use result::Result::{self, Ok, Err}; use super::table::{ self, @@ -44,6 +43,7 @@ use super::table::BucketState::{ Empty, Full, }; +use super::state::HashState; const INITIAL_LOG2_CAP: uint = 5; pub const INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5 @@ -297,9 +297,9 @@ fn test_resize_policy() { /// ``` #[derive(Clone)] #[stable] -pub struct HashMap<K, V, H = RandomSipHasher> { +pub struct HashMap<K, V, S = RandomState> { // All hashes are keyed on these values, to prevent hash collision attacks. - hasher: H, + hash_state: S, table: RawTable<K, V>, @@ -439,17 +439,20 @@ impl<K, V, M> SearchResult<K, V, M> { } } -#[old_impl_check] -impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { - fn make_hash<X: ?Sized + Hash<S>>(&self, x: &X) -> SafeHash { - table::make_hash(&self.hasher, x) +impl<K, V, S, H> HashMap<K, V, S> + where K: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{ + fn make_hash<X: ?Sized>(&self, x: &X) -> SafeHash where X: Hash<H> { + table::make_hash(&self.hash_state, x) } /// Search for a key, yielding the index if it's found in the hashtable. /// If you already have the hash for the key lying around, use /// search_hashed. fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>> - where Q: BorrowFrom<K> + Eq + Hash<S> + where Q: BorrowFrom<K> + Eq + Hash<H> { let hash = self.make_hash(q); search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) @@ -457,7 +460,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { } fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>> - where Q: BorrowFrom<K> + Eq + Hash<S> + where Q: BorrowFrom<K> + Eq + Hash<H> { let hash = self.make_hash(q); search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k))) @@ -486,7 +489,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { } } -impl<K: Hash + Eq, V> HashMap<K, V, RandomSipHasher> { +impl<K: Hash<Hasher> + Eq, V> HashMap<K, V, RandomState> { /// Create an empty HashMap. /// /// # Example @@ -497,9 +500,8 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomSipHasher> { /// ``` #[inline] #[stable] - pub fn new() -> HashMap<K, V, RandomSipHasher> { - let hasher = RandomSipHasher::new(); - HashMap::with_hasher(hasher) + pub fn new() -> HashMap<K, V, RandomState> { + Default::default() } /// Creates an empty hash map with the given initial capacity. @@ -512,14 +514,16 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomSipHasher> { /// ``` #[inline] #[stable] - pub fn with_capacity(capacity: uint) -> HashMap<K, V, RandomSipHasher> { - let hasher = RandomSipHasher::new(); - HashMap::with_capacity_and_hasher(capacity, hasher) + pub fn with_capacity(capacity: uint) -> HashMap<K, V, RandomState> { + HashMap::with_capacity_and_hash_state(capacity, Default::default()) } } -#[old_impl_check] -impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { +impl<K, V, S, H> HashMap<K, V, S> + where K: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{ /// Creates an empty hashmap which will use the given hasher to hash keys. /// /// The creates map has the default initial capacity. @@ -528,17 +532,17 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { /// /// ``` /// use std::collections::HashMap; - /// use std::hash::sip::SipHasher; + /// use std::collections::hash_map::RandomState; /// - /// let h = SipHasher::new(); - /// let mut map = HashMap::with_hasher(h); + /// let s = RandomState::new(); + /// let mut map = HashMap::with_hash_state(s); /// map.insert(1i, 2u); /// ``` #[inline] #[unstable = "hasher stuff is unclear"] - pub fn with_hasher(hasher: H) -> HashMap<K, V, H> { + pub fn with_hash_state(hash_state: S) -> HashMap<K, V, S> { HashMap { - hasher: hasher, + hash_state: hash_state, resize_policy: DefaultResizePolicy::new(), table: RawTable::new(0), } @@ -556,21 +560,22 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { /// /// ``` /// use std::collections::HashMap; - /// use std::hash::sip::SipHasher; + /// use std::collections::hash_map::RandomState; /// - /// let h = SipHasher::new(); - /// let mut map = HashMap::with_capacity_and_hasher(10, h); + /// let s = RandomState::new(); + /// let mut map = HashMap::with_capacity_and_hash_state(10, s); /// map.insert(1i, 2u); /// ``` #[inline] #[unstable = "hasher stuff is unclear"] - pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap<K, V, H> { + pub fn with_capacity_and_hash_state(capacity: uint, hash_state: S) + -> HashMap<K, V, S> { let resize_policy = DefaultResizePolicy::new(); let min_cap = max(INITIAL_CAPACITY, resize_policy.min_capacity(capacity)); let internal_cap = min_cap.checked_next_power_of_two().expect("capacity overflow"); assert!(internal_cap >= capacity, "capacity overflow"); HashMap { - hasher: hasher, + hash_state: hash_state, resize_policy: resize_policy, table: RawTable::new(internal_cap), } @@ -1031,7 +1036,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { /// ``` #[stable] pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> - where Q: Hash<S> + Eq + BorrowFrom<K> + where Q: Hash<H> + Eq + BorrowFrom<K> { self.search(k).map(|bucket| bucket.into_refs().1) } @@ -1054,7 +1059,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { /// ``` #[stable] pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool - where Q: Hash<S> + Eq + BorrowFrom<K> + where Q: Hash<H> + Eq + BorrowFrom<K> { self.search(k).is_some() } @@ -1080,7 +1085,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { /// ``` #[stable] pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> - where Q: Hash<S> + Eq + BorrowFrom<K> + where Q: Hash<H> + Eq + BorrowFrom<K> { self.search_mut(k).map(|bucket| bucket.into_mut_refs().1) } @@ -1132,7 +1137,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> { /// ``` #[stable] pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V> - where Q: Hash<S> + Eq + BorrowFrom<K> + where Q: Hash<H> + Eq + BorrowFrom<K> { if self.table.size() == 0 { return None @@ -1189,10 +1194,12 @@ fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHas } } -#[stable] -#[old_impl_check] -impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> { - fn eq(&self, other: &HashMap<K, V, H>) -> bool { +impl<K, V, S, H> PartialEq for HashMap<K, V, S> + where K: Eq + Hash<H>, V: PartialEq, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{ + fn eq(&self, other: &HashMap<K, V, S>) -> bool { if self.len() != other.len() { return false; } self.iter().all(|(key, value)| @@ -1202,12 +1209,18 @@ impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, } #[stable] -#[old_impl_check] -impl<K: Eq + Hash<S>, V: Eq, S, H: Hasher<S>> Eq for HashMap<K, V, H> {} +impl<K, V, S, H> Eq for HashMap<K, V, S> + where K: Eq + Hash<H>, V: Eq, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{} #[stable] -#[old_impl_check] -impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> { +impl<K, V, S, H> Show for HashMap<K, V, S> + where K: Eq + Hash<H> + Show, V: Show, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "HashMap {{")); @@ -1221,18 +1234,22 @@ impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> } #[stable] -#[old_impl_check] -impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> { - #[stable] - fn default() -> HashMap<K, V, H> { - HashMap::with_hasher(Default::default()) +impl<K, V, S, H> Default for HashMap<K, V, S> + where K: Eq + Hash<H>, + S: HashState<Hasher=H> + Default, + H: hash::Hasher<Output=u64> +{ + fn default() -> HashMap<K, V, S> { + HashMap::with_hash_state(Default::default()) } } #[stable] -#[old_impl_check] -impl<K: Hash<S> + Eq, Q: ?Sized, V, S, H: Hasher<S>> Index<Q> for HashMap<K, V, H> - where Q: BorrowFrom<K> + Hash<S> + Eq +impl<K, Q: ?Sized, V, S, H> Index<Q> for HashMap<K, V, S> + where K: Eq + Hash<H>, + Q: Eq + Hash<H> + BorrowFrom<K>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> { type Output = V; @@ -1243,9 +1260,11 @@ impl<K: Hash<S> + Eq, Q: ?Sized, V, S, H: Hasher<S>> Index<Q> for HashMap<K, V, } #[stable] -#[old_impl_check] -impl<K: Hash<S> + Eq, Q: ?Sized, V, S, H: Hasher<S>> IndexMut<Q> for HashMap<K, V, H> - where Q: BorrowFrom<K> + Hash<S> + Eq +impl<K, V, S, H, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S> + where K: Eq + Hash<H>, + Q: Eq + Hash<H> + BorrowFrom<K>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> { type Output = V; @@ -1473,19 +1492,26 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { } #[stable] -#[old_impl_check] -impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> { - fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> HashMap<K, V, H> { +impl<K, V, S, H> FromIterator<(K, V)> for HashMap<K, V, S> + where K: Eq + Hash<H>, + S: HashState<Hasher=H> + Default, + H: hash::Hasher<Output=u64> +{ + fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> HashMap<K, V, S> { let lower = iter.size_hint().0; - let mut map = HashMap::with_capacity_and_hasher(lower, Default::default()); + let mut map = HashMap::with_capacity_and_hash_state(lower, + Default::default()); map.extend(iter); map } } #[stable] -#[old_impl_check] -impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Extend<(K, V)> for HashMap<K, V, H> { +impl<K, V, S, H> Extend<(K, V)> for HashMap<K, V, S> + where K: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{ fn extend<T: Iterator<Item=(K, V)>>(&mut self, mut iter: T) { for (k, v) in iter { self.insert(k, v); @@ -1493,6 +1519,64 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Extend<(K, V)> for HashMap<K, V, H> { } } + +/// `RandomState` is the default state for `HashMap` types. +/// +/// A particular instance `RandomState` will create the same instances of +/// `Hasher`, but the hashers created by two different `RandomState` +/// instances are unlikely to produce the same result for the same values. +#[derive(Clone)] +#[allow(missing_copy_implementations)] +#[unstable = "hashing an hash maps may be altered"] +pub struct RandomState { + k0: u64, + k1: u64, +} + +#[unstable = "hashing an hash maps may be altered"] +impl RandomState { + /// Construct a new `RandomState` that is initialized with random keys. + #[inline] + pub fn new() -> RandomState { + let mut r = rand::thread_rng(); + RandomState { k0: r.gen(), k1: r.gen() } + } +} + +#[unstable = "hashing an hash maps may be altered"] +impl HashState for RandomState { + type Hasher = Hasher; + fn hasher(&self) -> Hasher { + Hasher { inner: SipHasher::new_with_keys(self.k0, self.k1) } + } +} + +#[unstable = "hashing an hash maps may be altered"] +impl Default for RandomState { + #[inline] + fn default() -> RandomState { + RandomState::new() + } +} + +/// A hasher implementation which is generated from `RandomState` instances. +/// +/// This is the default hasher used in a `HashMap` to hash keys. Types do not +/// typically declare an ability to explicitly hash into this particular type, +/// but rather in a `H: hash::Writer` type parameter. +#[allow(missing_copy_implementations)] +pub struct Hasher { inner: SipHasher } + +impl hash::Writer for Hasher { + fn write(&mut self, data: &[u8]) { self.inner.write(data) } +} + +impl hash::Hasher for Hasher { + type Output = u64; + fn reset(&mut self) { self.inner.reset() } + fn finish(&self) -> u64 { self.inner.finish() } +} + #[cfg(test)] mod test_map { use prelude::v1::*; diff --git a/src/libstd/collections/hash/mod.rs b/src/libstd/collections/hash/mod.rs index ee3fc1e6ac3..47e300af269 100644 --- a/src/libstd/collections/hash/mod.rs +++ b/src/libstd/collections/hash/mod.rs @@ -11,6 +11,7 @@ //! Unordered containers, implemented as hash-tables mod bench; +mod table; pub mod map; pub mod set; -mod table; +pub mod state; diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index f66e5384942..4003d3addf1 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -17,12 +17,13 @@ use core::marker::Sized; use default::Default; use fmt::Show; use fmt; -use hash::{Hash, Hasher, RandomSipHasher}; +use hash::{self, Hash}; use iter::{Iterator, IteratorExt, FromIterator, Map, Chain, Extend}; use ops::{BitOr, BitAnd, BitXor, Sub}; use option::Option::{Some, None, self}; -use super::map::{self, HashMap, Keys, INITIAL_CAPACITY}; +use super::map::{self, HashMap, Keys, INITIAL_CAPACITY, RandomState, Hasher}; +use super::state::HashState; // Future Optimization (FIXME!) // ============================= @@ -90,11 +91,11 @@ use super::map::{self, HashMap, Keys, INITIAL_CAPACITY}; /// ``` #[derive(Clone)] #[stable] -pub struct HashSet<T, H = RandomSipHasher> { - map: HashMap<T, (), H> +pub struct HashSet<T, S = RandomState> { + map: HashMap<T, (), S> } -impl<T: Hash + Eq> HashSet<T, RandomSipHasher> { +impl<T: Hash<Hasher> + Eq> HashSet<T, RandomState> { /// Create an empty HashSet. /// /// # Example @@ -105,7 +106,7 @@ impl<T: Hash + Eq> HashSet<T, RandomSipHasher> { /// ``` #[inline] #[stable] - pub fn new() -> HashSet<T, RandomSipHasher> { + pub fn new() -> HashSet<T, RandomState> { HashSet::with_capacity(INITIAL_CAPACITY) } @@ -120,13 +121,16 @@ impl<T: Hash + Eq> HashSet<T, RandomSipHasher> { /// ``` #[inline] #[stable] - pub fn with_capacity(capacity: uint) -> HashSet<T, RandomSipHasher> { + pub fn with_capacity(capacity: uint) -> HashSet<T, RandomState> { HashSet { map: HashMap::with_capacity(capacity) } } } -#[old_impl_check] -impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { +impl<T, S, H> HashSet<T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{ /// Creates a new empty hash set which will use the given hasher to hash /// keys. /// @@ -136,16 +140,16 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// /// ``` /// use std::collections::HashSet; - /// use std::hash::sip::SipHasher; + /// use std::collections::hash_map::RandomState; /// - /// let h = SipHasher::new(); - /// let mut set = HashSet::with_hasher(h); + /// let s = RandomState::new(); + /// let mut set = HashSet::with_hash_state(s); /// set.insert(2u); /// ``` #[inline] #[unstable = "hasher stuff is unclear"] - pub fn with_hasher(hasher: H) -> HashSet<T, H> { - HashSet::with_capacity_and_hasher(INITIAL_CAPACITY, hasher) + pub fn with_hash_state(hash_state: S) -> HashSet<T, S> { + HashSet::with_capacity_and_hash_state(INITIAL_CAPACITY, hash_state) } /// Create an empty HashSet with space for at least `capacity` @@ -160,16 +164,19 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// /// ``` /// use std::collections::HashSet; - /// use std::hash::sip::SipHasher; + /// use std::collections::hash_map::RandomState; /// - /// let h = SipHasher::new(); - /// let mut set = HashSet::with_capacity_and_hasher(10u, h); + /// let s = RandomState::new(); + /// let mut set = HashSet::with_capacity_and_hash_state(10u, s); /// set.insert(1i); /// ``` #[inline] #[unstable = "hasher stuff is unclear"] - pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashSet<T, H> { - HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) } + pub fn with_capacity_and_hash_state(capacity: uint, hash_state: S) + -> HashSet<T, S> { + HashSet { + map: HashMap::with_capacity_and_hash_state(capacity, hash_state), + } } /// Returns the number of elements the set can hold without reallocating. @@ -300,7 +307,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// assert_eq!(diff, [4i].iter().map(|&x| x).collect()); /// ``` #[stable] - pub fn difference<'a>(&'a self, other: &'a HashSet<T, H>) -> Difference<'a, T, H> { + pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> { Difference { iter: self.iter(), other: other, @@ -328,8 +335,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// assert_eq!(diff1, [1i, 4].iter().map(|&x| x).collect()); /// ``` #[stable] - pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, H>) - -> SymmetricDifference<'a, T, H> { + pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, S>) + -> SymmetricDifference<'a, T, S> { SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } } @@ -351,7 +358,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect()); /// ``` #[stable] - pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>) -> Intersection<'a, T, H> { + pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> { Intersection { iter: self.iter(), other: other, @@ -376,7 +383,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect()); /// ``` #[stable] - pub fn union<'a>(&'a self, other: &'a HashSet<T, H>) -> Union<'a, T, H> { + pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> { Union { iter: self.iter().chain(other.difference(self)) } } @@ -452,7 +459,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// ``` #[stable] pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool - where Q: BorrowFrom<T> + Hash<S> + Eq + where Q: BorrowFrom<T> + Hash<H> + Eq { self.map.contains_key(value) } @@ -475,7 +482,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// assert_eq!(a.is_disjoint(&b), false); /// ``` #[stable] - pub fn is_disjoint(&self, other: &HashSet<T, H>) -> bool { + pub fn is_disjoint(&self, other: &HashSet<T, S>) -> bool { self.iter().all(|v| !other.contains(v)) } @@ -496,7 +503,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// assert_eq!(set.is_subset(&sup), false); /// ``` #[stable] - pub fn is_subset(&self, other: &HashSet<T, H>) -> bool { + pub fn is_subset(&self, other: &HashSet<T, S>) -> bool { self.iter().all(|v| other.contains(v)) } @@ -521,7 +528,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// ``` #[inline] #[stable] - pub fn is_superset(&self, other: &HashSet<T, H>) -> bool { + pub fn is_superset(&self, other: &HashSet<T, S>) -> bool { other.is_subset(self) } @@ -562,16 +569,19 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> { /// ``` #[stable] pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool - where Q: BorrowFrom<T> + Hash<S> + Eq + where Q: BorrowFrom<T> + Hash<H> + Eq { self.map.remove(value).is_some() } } #[stable] -#[old_impl_check] -impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> { - fn eq(&self, other: &HashSet<T, H>) -> bool { +impl<T, S, H> PartialEq for HashSet<T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{ + fn eq(&self, other: &HashSet<T, S>) -> bool { if self.len() != other.len() { return false; } self.iter().all(|key| other.contains(key)) @@ -579,12 +589,18 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> { } #[stable] -#[old_impl_check] -impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {} +impl<T, S, H> Eq for HashSet<T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{} #[stable] -#[old_impl_check] -impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> { +impl<T, S, H> fmt::Show for HashSet<T, S> + where T: Eq + Hash<H> + fmt::Show, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "HashSet {{")); @@ -598,19 +614,25 @@ impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> { } #[stable] -#[old_impl_check] -impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> { - fn from_iter<I: Iterator<Item=T>>(iter: I) -> HashSet<T, H> { +impl<T, S, H> FromIterator<T> for HashSet<T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H> + Default, + H: hash::Hasher<Output=u64> +{ + fn from_iter<I: Iterator<Item=T>>(iter: I) -> HashSet<T, S> { let lower = iter.size_hint().0; - let mut set = HashSet::with_capacity_and_hasher(lower, Default::default()); + let mut set = HashSet::with_capacity_and_hash_state(lower, Default::default()); set.extend(iter); set } } #[stable] -#[old_impl_check] -impl<T: Eq + Hash<S>, S, H: Hasher<S>> Extend<T> for HashSet<T, H> { +impl<T, S, H> Extend<T> for HashSet<T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> +{ fn extend<I: Iterator<Item=T>>(&mut self, mut iter: I) { for k in iter { self.insert(k); @@ -619,21 +641,26 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> Extend<T> for HashSet<T, H> { } #[stable] -#[old_impl_check] -impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Default for HashSet<T, H> { +impl<T, S, H> Default for HashSet<T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H> + Default, + H: hash::Hasher<Output=u64> +{ #[stable] - fn default() -> HashSet<T, H> { - HashSet::with_hasher(Default::default()) + fn default() -> HashSet<T, S> { + HashSet::with_hash_state(Default::default()) } } #[stable] -#[old_impl_check] -impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default> -BitOr<&'b HashSet<T, H>> for &'a HashSet<T, H> { - type Output = HashSet<T, H>; +impl<'a, 'b, T, S, H> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S> + where T: Eq + Hash<H> + Clone, + S: HashState<Hasher=H> + Default, + H: hash::Hasher<Output=u64> +{ + type Output = HashSet<T, S>; - /// Returns the union of `self` and `rhs` as a new `HashSet<T, H>`. + /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`. /// /// # Examples /// @@ -653,18 +680,20 @@ BitOr<&'b HashSet<T, H>> for &'a HashSet<T, H> { /// } /// assert_eq!(i, expected.len()); /// ``` - fn bitor(self, rhs: &HashSet<T, H>) -> HashSet<T, H> { + fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> { self.union(rhs).cloned().collect() } } #[stable] -#[old_impl_check] -impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default> -BitAnd<&'b HashSet<T, H>> for &'a HashSet<T, H> { - type Output = HashSet<T, H>; +impl<'a, 'b, T, S, H> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S> + where T: Eq + Hash<H> + Clone, + S: HashState<Hasher=H> + Default, + H: hash::Hasher<Output=u64> +{ + type Output = HashSet<T, S>; - /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, H>`. + /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`. /// /// # Examples /// @@ -684,18 +713,20 @@ BitAnd<&'b HashSet<T, H>> for &'a HashSet<T, H> { /// } /// assert_eq!(i, expected.len()); /// ``` - fn bitand(self, rhs: &HashSet<T, H>) -> HashSet<T, H> { + fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> { self.intersection(rhs).cloned().collect() } } #[stable] -#[old_impl_check] -impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default> -BitXor<&'b HashSet<T, H>> for &'a HashSet<T, H> { - type Output = HashSet<T, H>; +impl<'a, 'b, T, S, H> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S> + where T: Eq + Hash<H> + Clone, + S: HashState<Hasher=H> + Default, + H: hash::Hasher<Output=u64> +{ + type Output = HashSet<T, S>; - /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, H>`. + /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`. /// /// # Examples /// @@ -715,18 +746,20 @@ BitXor<&'b HashSet<T, H>> for &'a HashSet<T, H> { /// } /// assert_eq!(i, expected.len()); /// ``` - fn bitxor(self, rhs: &HashSet<T, H>) -> HashSet<T, H> { + fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> { self.symmetric_difference(rhs).cloned().collect() } } #[stable] -#[old_impl_check] -impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default> -Sub<&'b HashSet<T, H>> for &'a HashSet<T, H> { - type Output = HashSet<T, H>; +impl<'a, 'b, T, S, H> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S> + where T: Eq + Hash<H> + Clone, + S: HashState<Hasher=H> + Default, + H: hash::Hasher<Output=u64> +{ + type Output = HashSet<T, S>; - /// Returns the difference of `self` and `rhs` as a new `HashSet<T, H>`. + /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`. /// /// # Examples /// @@ -746,7 +779,7 @@ Sub<&'b HashSet<T, H>> for &'a HashSet<T, H> { /// } /// assert_eq!(i, expected.len()); /// ``` - fn sub(self, rhs: &HashSet<T, H>) -> HashSet<T, H> { + fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> { self.difference(rhs).cloned().collect() } } @@ -771,32 +804,32 @@ pub struct Drain<'a, K: 'a> { /// Intersection iterator #[stable] -pub struct Intersection<'a, T: 'a, H: 'a> { +pub struct Intersection<'a, T: 'a, S: 'a> { // iterator of the first set iter: Iter<'a, T>, // the second set - other: &'a HashSet<T, H>, + other: &'a HashSet<T, S>, } /// Difference iterator #[stable] -pub struct Difference<'a, T: 'a, H: 'a> { +pub struct Difference<'a, T: 'a, S: 'a> { // iterator of the first set iter: Iter<'a, T>, // the second set - other: &'a HashSet<T, H>, + other: &'a HashSet<T, S>, } /// Symmetric difference iterator. #[stable] -pub struct SymmetricDifference<'a, T: 'a, H: 'a> { - iter: Chain<Difference<'a, T, H>, Difference<'a, T, H>> +pub struct SymmetricDifference<'a, T: 'a, S: 'a> { + iter: Chain<Difference<'a, T, S>, Difference<'a, T, S>> } /// Set union iterator. #[stable] -pub struct Union<'a, T: 'a, H: 'a> { - iter: Chain<Iter<'a, T>, Difference<'a, T, H>> +pub struct Union<'a, T: 'a, S: 'a> { + iter: Chain<Iter<'a, T>, Difference<'a, T, S>> } #[stable] @@ -824,9 +857,10 @@ impl<'a, K: 'a> Iterator for Drain<'a, K> { } #[stable] -#[old_impl_check] -impl<'a, T, S, H> Iterator for Intersection<'a, T, H> - where T: Eq + Hash<S>, H: Hasher<S> +impl<'a, T, S, H> Iterator for Intersection<'a, T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> { type Item = &'a T; @@ -848,9 +882,10 @@ impl<'a, T, S, H> Iterator for Intersection<'a, T, H> } #[stable] -#[old_impl_check] -impl<'a, T, S, H> Iterator for Difference<'a, T, H> - where T: Eq + Hash<S>, H: Hasher<S> +impl<'a, T, S, H> Iterator for Difference<'a, T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> { type Item = &'a T; @@ -872,9 +907,10 @@ impl<'a, T, S, H> Iterator for Difference<'a, T, H> } #[stable] -#[old_impl_check] -impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, H> - where T: Eq + Hash<S>, H: Hasher<S> +impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> { type Item = &'a T; @@ -883,9 +919,10 @@ impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, H> } #[stable] -#[old_impl_check] -impl<'a, T, S, H> Iterator for Union<'a, T, H> - where T: Eq + Hash<S>, H: Hasher<S> +impl<'a, T, S, H> Iterator for Union<'a, T, S> + where T: Eq + Hash<H>, + S: HashState<Hasher=H>, + H: hash::Hasher<Output=u64> { type Item = &'a T; diff --git a/src/libstd/collections/hash/state.rs b/src/libstd/collections/hash/state.rs new file mode 100644 index 00000000000..ffbc958f179 --- /dev/null +++ b/src/libstd/collections/hash/state.rs @@ -0,0 +1,51 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use clone::Clone; +use default::Default; +use hash; + +/// A trait representing stateful hashes which can be used to hash keys in a +/// `HashMap`. +/// +/// A HashState is used as a factory for instances of `Hasher` which a `HashMap` +/// can then use to hash keys independently. A `HashMap` by default uses a state +/// which will create instances of a `SipHasher`, but a custom state factory can +/// be provided to the `with_hash_state` function. +/// +/// If a hashing algorithm has no initial state, then the `Hasher` type for that +/// algorithm can implement the `Default` trait and create hash maps with the +/// `DefaultState` structure. This state is 0-sized and will simply delegate +/// to `Default` when asked to create a hasher. +pub trait HashState { + type Hasher: hash::Hasher; + + /// Creates a new hasher based on the given state of this object. + fn hasher(&self) -> Self::Hasher; +} + +/// A structure which is a factory for instances of `Hasher` which implement the +/// default trait. +/// +/// This struct has is 0-sized and does not need construction. +pub struct DefaultState<H>; + +impl<H: Default + hash::Hasher> HashState for DefaultState<H> { + type Hasher = H; + fn hasher(&self) -> H { Default::default() } +} + +impl<H> Clone for DefaultState<H> { + fn clone(&self) -> DefaultState<H> { DefaultState } +} + +impl<H> Default for DefaultState<H> { + fn default() -> DefaultState<H> { DefaultState } +} diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 6eb98da4da4..e43cc053ba0 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -26,6 +26,7 @@ use option::Option::{Some, None}; use ptr::{Unique, PtrExt, copy_nonoverlapping_memory, zero_memory}; use ptr; use rt::heap::{allocate, deallocate}; +use collections::hash_state::HashState; const EMPTY_BUCKET: u64 = 0u64; @@ -138,12 +139,18 @@ impl SafeHash { /// We need to remove hashes of 0. That's reserved for empty buckets. /// This function wraps up `hash_keyed` to be the only way outside this /// module to generate a SafeHash. -pub fn make_hash<T: ?Sized + Hash<S>, S, H: Hasher<S>>(hasher: &H, t: &T) -> SafeHash { +pub fn make_hash<T: ?Sized, S, H>(hash_state: &S, t: &T) -> SafeHash + where T: Hash<H>, + S: HashState<Hasher=H>, + H: Hasher<Output=u64> +{ + let mut state = hash_state.hasher(); + t.hash(&mut state); // We need to avoid 0u64 in order to prevent collisions with // EMPTY_HASH. We can maintain our precious uniform distribution // of initial indexes by unconditionally setting the MSB, // effectively reducing 64-bits hashes to 63 bits. - SafeHash { hash: 0x8000_0000_0000_0000 | hasher.hash(t) } + SafeHash { hash: 0x8000_0000_0000_0000 | state.finish() } } // `replace` casts a `*u64` to a `*SafeHash`. Since we statically diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index 9b2a4926bcb..71ab89027ff 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -333,3 +333,10 @@ pub mod hash_set { //! A hashset pub use super::hash::set::*; } + +/// Experimental support for providing custom hash algorithms to a HashMap and +/// HashSet. +#[unstable = "module was recently added"] +pub mod hash_state { + pub use super::hash::state::*; +} diff --git a/src/libstd/failure.rs b/src/libstd/failure.rs index 50538d3e43d..dbc88ddf0a0 100644 --- a/src/libstd/failure.rs +++ b/src/libstd/failure.rs @@ -37,7 +37,7 @@ pub fn on_fail(obj: &(Any+Send), file: &'static str, line: uint) { let msg = match obj.downcast_ref::<&'static str>() { Some(s) => *s, None => match obj.downcast_ref::<String>() { - Some(s) => s.index(&FullRange), + Some(s) => &s[], None => "Box<Any>", } }; diff --git a/src/libstd/fmt.rs b/src/libstd/fmt.rs index 1623b6452b7..96fff64d221 100644 --- a/src/libstd/fmt.rs +++ b/src/libstd/fmt.rs @@ -175,7 +175,7 @@ //! use std::f64; //! use std::num::Float; //! -//! #[deriving(Show)] +//! #[derive(Show)] //! struct Vector2D { //! x: int, //! y: int, diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs deleted file mode 100644 index 69e7e429d07..00000000000 --- a/src/libstd/hash.rs +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Generic hashing support. -//! -//! This module provides a generic way to compute the hash of a value. The -//! simplest way to make a type hashable is to use `#[derive(Hash)]`: -//! -//! # Example -//! -//! ```rust -//! use std::hash; -//! use std::hash::Hash; -//! -//! #[derive(Hash)] -//! struct Person { -//! id: uint, -//! name: String, -//! phone: u64, -//! } -//! -//! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 }; -//! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 }; -//! -//! assert!(hash::hash(&person1) != hash::hash(&person2)); -//! ``` -//! -//! If you need more control over how a value is hashed, you need to implement -//! the trait `Hash`: -//! -//! ```rust -//! use std::hash; -//! use std::hash::Hash; -//! use std::hash::sip::SipState; -//! -//! struct Person { -//! id: uint, -//! name: String, -//! phone: u64, -//! } -//! -//! impl Hash for Person { -//! fn hash(&self, state: &mut SipState) { -//! self.id.hash(state); -//! self.phone.hash(state); -//! } -//! } -//! -//! let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 }; -//! let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 }; -//! -//! assert!(hash::hash(&person1) == hash::hash(&person2)); -//! ``` - -#![experimental] - -pub use core::hash::{Hash, Hasher, Writer, hash, sip}; - -use core::marker::Sized; -use default::Default; -use rand::Rng; -use rand; - -/// `RandomSipHasher` computes the SipHash algorithm from a stream of bytes -/// initialized with random keys. -#[derive(Clone)] -pub struct RandomSipHasher { - hasher: sip::SipHasher, -} - -impl RandomSipHasher { - /// Construct a new `RandomSipHasher` that is initialized with random keys. - #[inline] - pub fn new() -> RandomSipHasher { - let mut r = rand::thread_rng(); - let r0 = r.gen(); - let r1 = r.gen(); - RandomSipHasher { - hasher: sip::SipHasher::new_with_keys(r0, r1), - } - } -} - -impl Hasher<sip::SipState> for RandomSipHasher { - #[inline] - fn hash<T: ?Sized + Hash<sip::SipState>>(&self, value: &T) -> u64 { - self.hasher.hash(value) - } -} - -#[stable] -impl Default for RandomSipHasher { - #[stable] - #[inline] - fn default() -> RandomSipHasher { - RandomSipHasher::new() - } -} diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 74c503e6f2b..ba13bd05dc5 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -15,7 +15,7 @@ use cmp; use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult}; use iter::{IteratorExt, ExactSizeIterator}; -use ops::{Drop, Index}; +use ops::Drop; use option::Option; use option::Option::{Some, None}; use result::Result::Ok; @@ -97,7 +97,7 @@ impl<R: Reader> Buffer for BufferedReader<R> { self.cap = try!(self.inner.read(self.buf.as_mut_slice())); self.pos = 0; } - Ok(self.buf.index(&(self.pos..self.cap))) + Ok(&self.buf[self.pos..self.cap]) } fn consume(&mut self, amt: uint) { @@ -114,7 +114,7 @@ impl<R: Reader> Reader for BufferedReader<R> { let nread = { let available = try!(self.fill_buf()); let nread = cmp::min(available.len(), buf.len()); - slice::bytes::copy_memory(buf, available.index(&(0..nread))); + slice::bytes::copy_memory(buf, &available[0..nread]); nread }; self.pos += nread; @@ -168,7 +168,7 @@ impl<W: Writer> BufferedWriter<W> { fn flush_buf(&mut self) -> IoResult<()> { if self.pos != 0 { - let ret = self.inner.as_mut().unwrap().write(self.buf.index(&(0..self.pos))); + let ret = self.inner.as_mut().unwrap().write(&self.buf[0..self.pos]); self.pos = 0; ret } else { @@ -260,9 +260,9 @@ impl<W: Writer> Writer for LineBufferedWriter<W> { fn write(&mut self, buf: &[u8]) -> IoResult<()> { match buf.iter().rposition(|&b| b == b'\n') { Some(i) => { - try!(self.inner.write(buf.index(&(0..(i + 1))))); + try!(self.inner.write(&buf[0..(i + 1)])); try!(self.inner.flush()); - try!(self.inner.write(buf.index(&((i + 1)..)))); + try!(self.inner.write(&buf[(i + 1)..])); Ok(()) } None => self.inner.write(buf), @@ -510,7 +510,7 @@ mod test { assert_eq!(a, &w.get_ref()[]); let w = w.into_inner(); let a: &[_] = &[0, 1]; - assert_eq!(a, w.index(&FullRange)); + assert_eq!(a, &w[]); } // This is just here to make sure that we don't infinite loop in the @@ -607,14 +607,14 @@ mod test { #[test] fn read_char_buffered() { let buf = [195u8, 159u8]; - let mut reader = BufferedReader::with_capacity(1, buf.index(&FullRange)); + let mut reader = BufferedReader::with_capacity(1, &buf[]); assert_eq!(reader.read_char(), Ok('ß')); } #[test] fn test_chars() { let buf = [195u8, 159u8, b'a']; - let mut reader = BufferedReader::with_capacity(1, buf.index(&FullRange)); + let mut reader = BufferedReader::with_capacity(1, &buf[]); let mut it = reader.chars(); assert_eq!(it.next(), Some(Ok('ß'))); assert_eq!(it.next(), Some(Ok('a'))); diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index bce097e17ef..b578f4d5adc 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -13,7 +13,6 @@ use cmp; use sync::mpsc::{Sender, Receiver}; use io; use option::Option::{None, Some}; -use ops::Index; use result::Result::{Ok, Err}; use slice::{bytes, SliceExt}; use super::{Buffer, Reader, Writer, IoResult}; @@ -91,7 +90,7 @@ impl Reader for ChanReader { Some(src) => { let dst = buf.slice_from_mut(num_read); let count = cmp::min(src.len(), dst.len()); - bytes::copy_memory(dst, src.index(&(0..count))); + bytes::copy_memory(dst, &src[0..count]); count }, None => 0, diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index eadca8e42e5..dbccc81c4cc 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -889,7 +889,7 @@ mod test { let mut read_buf = [0; 1028]; let read_str = match check!(read_stream.read(&mut read_buf)) { -1|0 => panic!("shouldn't happen"), - n => str::from_utf8(read_buf.index(&(0..n))).unwrap().to_string() + n => str::from_utf8(&read_buf[0..n]).unwrap().to_string() }; assert_eq!(read_str.as_slice(), message); } diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index 9a6ad04fdbc..c5e289398e0 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -13,7 +13,6 @@ //! Readers and Writers for in-memory buffers use cmp::min; -use ops::Index; use option::Option::None; use result::Result::{Err, Ok}; use io; @@ -160,7 +159,7 @@ impl Reader for MemReader { let write_len = min(buf.len(), self.buf.len() - self.pos); { - let input = self.buf.index(&(self.pos.. (self.pos + write_len))); + let input = &self.buf[self.pos.. (self.pos + write_len)]; let output = buf.slice_to_mut(write_len); assert_eq!(input.len(), output.len()); slice::bytes::copy_memory(output, input); @@ -188,7 +187,7 @@ impl Buffer for MemReader { #[inline] fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { if self.pos < self.buf.len() { - Ok(self.buf.index(&(self.pos..))) + Ok(&self.buf[self.pos..]) } else { Err(io::standard_error(io::EndOfFile)) } @@ -205,7 +204,7 @@ impl<'a> Reader for &'a [u8] { let write_len = min(buf.len(), self.len()); { - let input = self.index(&(0..write_len)); + let input = &self[0..write_len]; let output = buf.slice_to_mut(write_len); slice::bytes::copy_memory(output, input); } @@ -228,7 +227,7 @@ impl<'a> Buffer for &'a [u8] { #[inline] fn consume(&mut self, amt: uint) { - *self = self.index(&(amt..)); + *self = &self[amt..]; } } @@ -287,7 +286,7 @@ impl<'a> Writer for BufWriter<'a> { Ok(()) } else { - slice::bytes::copy_memory(dst, src.index(&(0..dst_len))); + slice::bytes::copy_memory(dst, &src[0..dst_len]); self.pos += dst_len; @@ -350,7 +349,7 @@ impl<'a> Reader for BufReader<'a> { let write_len = min(buf.len(), self.buf.len() - self.pos); { - let input = self.buf.index(&(self.pos.. (self.pos + write_len))); + let input = &self.buf[self.pos.. (self.pos + write_len)]; let output = buf.slice_to_mut(write_len); assert_eq!(input.len(), output.len()); slice::bytes::copy_memory(output, input); @@ -378,7 +377,7 @@ impl<'a> Buffer for BufReader<'a> { #[inline] fn fill_buf(&mut self) -> IoResult<&[u8]> { if self.pos < self.buf.len() { - Ok(self.buf.index(&(self.pos..))) + Ok(&self.buf[self.pos..]) } else { Err(io::standard_error(io::EndOfFile)) } @@ -393,7 +392,7 @@ mod test { extern crate "test" as test_crate; use io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek}; use prelude::v1::{Ok, Err, range, Vec, Buffer, AsSlice, SliceExt}; - use prelude::v1::{IteratorExt, Index}; + use prelude::v1::IteratorExt; use io; use iter::repeat; use self::test_crate::Bencher; @@ -499,7 +498,7 @@ mod test { assert_eq!(buf, b); assert_eq!(reader.read(&mut buf), Ok(3)); let b: &[_] = &[5, 6, 7]; - assert_eq!(buf.index(&(0..3)), b); + assert_eq!(&buf[0..3], b); assert!(reader.read(&mut buf).is_err()); let mut reader = MemReader::new(vec!(0, 1, 2, 3, 4, 5, 6, 7)); assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3)); @@ -525,7 +524,7 @@ mod test { assert_eq!(buf.as_slice(), b); assert_eq!(reader.read(&mut buf), Ok(3)); let b: &[_] = &[5, 6, 7]; - assert_eq!(buf.index(&(0..3)), b); + assert_eq!(&buf[0..3], b); assert!(reader.read(&mut buf).is_err()); let mut reader = &mut in_buf.as_slice(); assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3)); @@ -552,7 +551,7 @@ mod test { assert_eq!(buf, b); assert_eq!(reader.read(&mut buf), Ok(3)); let b: &[_] = &[5, 6, 7]; - assert_eq!(buf.index(&(0..3)), b); + assert_eq!(&buf[0..3], b); assert!(reader.read(&mut buf).is_err()); let mut reader = BufReader::new(in_buf.as_slice()); assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3)); diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 9ef9081bc3c..1c48b20c444 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -236,7 +236,7 @@ use int; use iter::{Iterator, IteratorExt}; use marker::Sized; use mem::transmute; -use ops::{FnOnce, Index}; +use ops::FnOnce; use option::Option; use option::Option::{Some, None}; use os; @@ -1069,7 +1069,7 @@ pub trait Writer { fn write_char(&mut self, c: char) -> IoResult<()> { let mut buf = [0u8; 4]; let n = c.encode_utf8(buf.as_mut_slice()).unwrap_or(0); - self.write(buf.index(&(0..n))) + self.write(&buf[0..n]) } /// Write the result of passing n through `int::to_str_bytes`. @@ -1284,7 +1284,7 @@ impl<'a> Writer for &'a mut (Writer+'a) { /// process_input(tee); /// } /// -/// println!("input processed: {}", output); +/// println!("input processed: {:?}", output); /// # } /// ``` pub struct RefWriter<'a, W:'a> { @@ -1454,7 +1454,7 @@ pub trait Buffer: Reader { }; match available.iter().position(|&b| b == byte) { Some(i) => { - res.push_all(available.index(&(0..(i + 1)))); + res.push_all(&available[0..(i + 1)]); used = i + 1; break } @@ -1493,7 +1493,7 @@ pub trait Buffer: Reader { } } } - match str::from_utf8(buf.index(&(0..width))).ok() { + match str::from_utf8(&buf[0..width]).ok() { Some(s) => Ok(s.char_at(0)), None => Err(standard_error(InvalidInput)) } @@ -1783,9 +1783,8 @@ pub struct UnstableFileStat { } -// NOTE(stage0): change this one last #[doc=..] to /// after the next snapshot bitflags! { - #[doc = "A set of permissions for a file or directory is represented by a set of"] + /// A set of permissions for a file or directory is represented by a set of /// flags which are or'd together. flags FilePermission: u32 { const USER_READ = 0o400, diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index b9f653f86c2..d09afea94dc 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -22,7 +22,7 @@ use fmt; use io::{self, IoResult, IoError}; use io::net; use iter::{Iterator, IteratorExt}; -use ops::{FnOnce, FnMut, Index}; +use ops::{FnOnce, FnMut}; use option::Option; use option::Option::{None, Some}; use result::Result::{Ok, Err}; @@ -313,7 +313,7 @@ impl<'a> Parser<'a> { let mut tail = [0u16; 8]; let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size); - Some(ipv6_addr_from_head_tail(head.index(&(0..head_size)), tail.index(&(0..tail_size)))) + Some(ipv6_addr_from_head_tail(&head[0..head_size], &tail[0..tail_size])) } fn read_ipv6_addr(&mut self) -> Option<IpAddr> { diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index 55df6330dd3..f824d821601 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -34,7 +34,7 @@ use sys::process::Process as ProcessImp; use sys; use thread::Thread; -#[cfg(windows)] use std::hash::sip::SipState; +#[cfg(windows)] use hash; #[cfg(windows)] use str; /// Signal a process to exit, without forcibly killing it. Corresponds to @@ -98,7 +98,7 @@ pub struct Process { /// A representation of environment variable name /// It compares case-insensitive on Windows and case-sensitive everywhere else. #[cfg(not(windows))] -#[derive(PartialEq, Eq, Hash, Clone, Show)] +#[derive(Hash, PartialEq, Eq, Clone, Show)] struct EnvKey(CString); #[doc(hidden)] @@ -107,8 +107,8 @@ struct EnvKey(CString); struct EnvKey(CString); #[cfg(windows)] -impl Hash for EnvKey { - fn hash(&self, state: &mut SipState) { +impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for EnvKey { + fn hash(&self, state: &mut H) { let &EnvKey(ref x) = self; match str::from_utf8(x.as_bytes()) { Ok(s) => for ch in s.chars() { @@ -395,13 +395,6 @@ impl Command { } } -#[cfg(stage0)] -impl fmt::Show for Command { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::String::fmt(self, f) - } -} - impl fmt::String for Command { /// Format the program and arguments of a Command for display. Any /// non-utf8 data is lossily converted using the utf8 replacement diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index c0254a3e7a2..5a7219495f5 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -59,7 +59,7 @@ impl<R: Reader> Reader for LimitReader<R> { impl<R: Buffer> Buffer for LimitReader<R> { fn fill_buf<'a>(&'a mut self) -> io::IoResult<&'a [u8]> { let amt = try!(self.inner.fill_buf()); - let buf = amt.index(&(0..cmp::min(amt.len(), self.limit))); + let buf = &amt[0..cmp::min(amt.len(), self.limit)]; if buf.len() == 0 { Err(io::standard_error(io::EndOfFile)) } else { @@ -220,7 +220,7 @@ impl<R: Reader, W: Writer> TeeReader<R, W> { impl<R: Reader, W: Writer> Reader for TeeReader<R, W> { fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> { self.reader.read(buf).and_then(|len| { - self.writer.write(buf.index_mut(&(0..len))).map(|()| len) + self.writer.write(&mut buf[0..len]).map(|()| len) }) } } @@ -234,7 +234,7 @@ pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> { Err(ref e) if e.kind == io::EndOfFile => return Ok(()), Err(e) => return Err(e), }; - try!(w.write(buf.index(&(0..len)))); + try!(w.write(&buf[0..len])); } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index eef5bdb60ee..71221a654e8 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -96,6 +96,7 @@ #![crate_name = "std"] #![stable] +#![staged_api] #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", @@ -107,8 +108,8 @@ #![feature(linkage, thread_local, asm)] #![feature(lang_items, unsafe_destructor)] #![feature(slicing_syntax, unboxed_closures)] +#![feature(box_syntax)] #![feature(old_impl_check)] -#![cfg_attr(stage0, allow(unused_attributes))] // Don't link to std. We are std. #![no_std] @@ -120,8 +121,7 @@ extern crate log; #[macro_use] -#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq, - unreachable, unimplemented, write, writeln)] +#[macro_reexport(write, writeln)] extern crate core; #[macro_use] @@ -150,9 +150,9 @@ pub use core::clone; #[cfg(not(test))] pub use core::cmp; pub use core::default; pub use core::finally; +pub use core::hash; pub use core::intrinsics; pub use core::iter; -#[cfg(stage0)] #[cfg(not(test))] pub use core::marker as kinds; #[cfg(not(test))] pub use core::marker; pub use core::mem; #[cfg(not(test))] pub use core::ops; @@ -176,7 +176,7 @@ pub use unicode::char; /* Exported macros */ #[macro_use] -pub mod macros; +mod macros; #[macro_use] pub mod bitflags; @@ -203,12 +203,14 @@ mod int_macros; mod uint_macros; #[path = "num/int.rs"] pub mod int; +#[path = "num/isize.rs"] pub mod isize; #[path = "num/i8.rs"] pub mod i8; #[path = "num/i16.rs"] pub mod i16; #[path = "num/i32.rs"] pub mod i32; #[path = "num/i64.rs"] pub mod i64; #[path = "num/uint.rs"] pub mod uint; +#[path = "num/usize.rs"] pub mod usize; #[path = "num/u8.rs"] pub mod u8; #[path = "num/u16.rs"] pub mod u16; #[path = "num/u32.rs"] pub mod u32; @@ -242,7 +244,6 @@ pub mod time; /* Common data structures */ pub mod collections; -pub mod hash; /* Threads and communication */ @@ -274,6 +275,7 @@ mod std { pub use clone; pub use cmp; pub use hash; + pub use default; pub use sync; // used for select!() pub use error; // used for try!() @@ -284,8 +286,6 @@ mod std { pub use vec; // used for vec![] pub use cell; // used for tls! pub use thread_local; // used for thread_local! - #[cfg(stage0)] - pub use marker as kinds; pub use marker; // used for tls! pub use ops; // used for bitflags! diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index befdc156094..0594b711ad6 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -36,23 +36,27 @@ /// panic!("this is a {} {message}", "fancy", message = "message"); /// ``` #[macro_export] +#[stable] macro_rules! panic { () => ({ panic!("explicit panic") }); ($msg:expr) => ({ - // static requires less code at runtime, more constant data - static _FILE_LINE: (&'static str, uint) = (file!(), line!()); - ::std::rt::begin_unwind($msg, &_FILE_LINE) + $crate::rt::begin_unwind($msg, { + // static requires less code at runtime, more constant data + static _FILE_LINE: (&'static str, uint) = (file!(), line!()); + &_FILE_LINE + }) }); - ($fmt:expr, $($arg:tt)*) => ({ - // The leading _'s are to avoid dead code warnings if this is - // used inside a dead function. Just `#[allow(dead_code)]` is - // insufficient, since the user may have - // `#[forbid(dead_code)]` and which cannot be overridden. - static _FILE_LINE: (&'static str, uint) = (file!(), line!()); - ::std::rt::begin_unwind_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE) - + ($fmt:expr, $($arg:tt)+) => ({ + $crate::rt::begin_unwind_fmt(format_args!($fmt, $($arg)+), { + // The leading _'s are to avoid dead code warnings if this is + // used inside a dead function. Just `#[allow(dead_code)]` is + // insufficient, since the user may have + // `#[forbid(dead_code)]` and which cannot be overridden. + static _FILE_LINE: (&'static str, uint) = (file!(), line!()); + &_FILE_LINE + }) }); } @@ -77,15 +81,16 @@ macro_rules! panic { /// assert!(a + b == 30, "a = {}, b = {}", a, b); /// ``` #[macro_export] +#[stable] macro_rules! assert { ($cond:expr) => ( if !$cond { panic!(concat!("assertion failed: ", stringify!($cond))) } ); - ($cond:expr, $($arg:expr),+) => ( + ($cond:expr, $($arg:tt)+) => ( if !$cond { - panic!($($arg),+) + panic!($($arg)+) } ); } @@ -103,6 +108,7 @@ macro_rules! assert { /// assert_eq!(a, b); /// ``` #[macro_export] +#[stable] macro_rules! assert_eq { ($left:expr , $right:expr) => ({ match (&($left), &($right)) { @@ -144,6 +150,7 @@ macro_rules! assert_eq { /// debug_assert!(a + b == 30, "a = {}, b = {}", a, b); /// ``` #[macro_export] +#[stable] macro_rules! debug_assert { ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); }) } @@ -210,6 +217,7 @@ macro_rules! debug_assert_eq { /// } /// ``` #[macro_export] +#[unstable = "relationship with panic is unclear"] macro_rules! unreachable { () => ({ panic!("internal error: entered unreachable code") @@ -225,6 +233,7 @@ macro_rules! unreachable { /// A standardised placeholder for marking unfinished code. It panics with the /// message `"not yet implemented"` when executed. #[macro_export] +#[unstable = "relationship with panic is unclear"] macro_rules! unimplemented { () => (panic!("not yet implemented")) } @@ -242,7 +251,7 @@ macro_rules! unimplemented { #[macro_export] #[stable] macro_rules! format { - ($($arg:tt)*) => (::std::fmt::format(format_args!($($arg)*))) + ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*))) } /// Equivalent to the `println!` macro except that a newline is not printed at @@ -250,7 +259,7 @@ macro_rules! format { #[macro_export] #[stable] macro_rules! print { - ($($arg:tt)*) => (::std::io::stdio::print_args(format_args!($($arg)*))) + ($($arg:tt)*) => ($crate::io::stdio::print_args(format_args!($($arg)*))) } /// Macro for printing to a task's stdout handle. @@ -268,20 +277,19 @@ macro_rules! print { #[macro_export] #[stable] macro_rules! println { - ($($arg:tt)*) => (::std::io::stdio::println_args(format_args!($($arg)*))) + ($($arg:tt)*) => ($crate::io::stdio::println_args(format_args!($($arg)*))) } /// Helper macro for unwrapping `Result` values while returning early with an /// error if the value of the expression is `Err`. For more information, see /// `std::io`. #[macro_export] +#[stable] macro_rules! try { - ($expr:expr) => ({ - use $crate::result::Result::{Ok, Err}; - - match $expr { - Ok(val) => val, - Err(err) => return Err($crate::error::FromError::from_error(err)), + ($expr:expr) => (match $expr { + $crate::result::Result::Ok(val) => val, + $crate::result::Result::Err(err) => { + return $crate::result::Result::Err($crate::error::FromError::from_error(err)) } }) } @@ -412,26 +420,6 @@ pub mod builtin { #[macro_export] macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) } - /// Concatenate literals into a static byte slice. - /// - /// This macro takes any number of comma-separated literal expressions, - /// yielding an expression of type `&'static [u8]` which is the - /// concatenation (left to right) of all the literals in their byte format. - /// - /// This extension currently only supports string literals, character - /// literals, and integers less than 256. The byte slice returned is the - /// utf8-encoding of strings and characters. - /// - /// # Example - /// - /// ``` - /// let rust = bytes!("r", 'u', "st", 255); - /// assert_eq!(rust[1], b'u'); - /// assert_eq!(rust[4], 255); - /// ``` - #[macro_export] - macro_rules! bytes { ($($e:expr),*) => ({ /* compiler built-in */ }) } - /// Concatenate identifiers into one identifier. /// /// This macro takes any number of comma-separated identifiers, and @@ -565,10 +553,6 @@ pub mod builtin { #[macro_export] macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) } - /// Deprecated alias for `include_bytes!()`. - #[macro_export] - macro_rules! include_bin { ($file:expr) => ({ /* compiler built-in */}) } - /// Expands to a string that represents the current module path. /// /// The current module path can be thought of as the hierarchy of modules diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs index 9ccb1544fdc..69439f85115 100644 --- a/src/libstd/num/int.rs +++ b/src/libstd/num/int.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Operations and constants for architecture-sized signed integers (`int` type) +//! Deprecated: replaced by `isize`. +//! +//! The rollout of the new type will gradually take place over the +//! alpha cycle along with the development of clearer conventions +//! around integer types. -#![stable] -#![doc(primitive = "int")] +#![deprecated = "replaced by isize"] pub use core::int::{BITS, BYTES, MIN, MAX}; diff --git a/src/libstd/num/isize.rs b/src/libstd/num/isize.rs new file mode 100644 index 00000000000..22395a1c0ff --- /dev/null +++ b/src/libstd/num/isize.rs @@ -0,0 +1,22 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for pointer-sized signed integers (`isize` type) +//! +//! This type was recently added to replace `int`. The rollout of the +//! new type will gradually take place over the alpha cycle along with +//! the development of clearer conventions around integer types. + +#![stable] +#![doc(primitive = "isize")] + +pub use core::isize::{BITS, BYTES, MIN, MAX}; + +int_module! { isize } diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs index f433cd1e664..9c6911cf4d1 100644 --- a/src/libstd/num/mod.rs +++ b/src/libstd/num/mod.rs @@ -424,12 +424,14 @@ mod tests { assert_eq!(int::MIN.to_u32(), None); assert_eq!(int::MIN.to_u64(), None); - #[cfg(target_word_size = "32")] + #[cfg(any(all(stage0, target_word_size = "32"), + all(not(stage0), target_pointer_width = "32")))] fn check_word_size() { assert_eq!(int::MIN.to_i32(), Some(int::MIN as i32)); } - #[cfg(target_word_size = "64")] + #[cfg(any(all(stage0, target_word_size = "64"), + all(not(stage0), target_pointer_width = "64")))] fn check_word_size() { assert_eq!(int::MIN.to_i32(), None); } @@ -492,12 +494,14 @@ mod tests { assert_eq!(i64::MIN.to_u32(), None); assert_eq!(i64::MIN.to_u64(), None); - #[cfg(target_word_size = "32")] + #[cfg(any(all(stage0, target_word_size = "32"), + all(not(stage0), target_pointer_width = "32")))] fn check_word_size() { assert_eq!(i64::MIN.to_int(), None); } - #[cfg(target_word_size = "64")] + #[cfg(any(all(stage0, target_word_size = "64"), + all(not(stage0), target_pointer_width = "64")))] fn check_word_size() { assert_eq!(i64::MIN.to_int(), Some(i64::MIN as int)); } @@ -517,13 +521,15 @@ mod tests { // int::MAX.to_u32() is word-size specific assert_eq!(int::MAX.to_u64(), Some(int::MAX as u64)); - #[cfg(target_word_size = "32")] + #[cfg(any(all(stage0, target_word_size = "32"), + all(not(stage0), target_pointer_width = "32")))] fn check_word_size() { assert_eq!(int::MAX.to_i32(), Some(int::MAX as i32)); assert_eq!(int::MAX.to_u32(), Some(int::MAX as u32)); } - #[cfg(target_word_size = "64")] + #[cfg(any(all(stage0, target_word_size = "64"), + all(not(stage0), target_pointer_width = "64")))] fn check_word_size() { assert_eq!(int::MAX.to_i32(), None); assert_eq!(int::MAX.to_u32(), None); @@ -587,13 +593,15 @@ mod tests { assert_eq!(i64::MAX.to_u32(), None); assert_eq!(i64::MAX.to_u64(), Some(i64::MAX as u64)); - #[cfg(target_word_size = "32")] + #[cfg(any(all(stage0, target_word_size = "32"), + all(not(stage0), target_pointer_width = "32")))] fn check_word_size() { assert_eq!(i64::MAX.to_int(), None); assert_eq!(i64::MAX.to_uint(), None); } - #[cfg(target_word_size = "64")] + #[cfg(any(all(stage0, target_word_size = "64"), + all(not(stage0), target_pointer_width = "64")))] fn check_word_size() { assert_eq!(i64::MAX.to_int(), Some(i64::MAX as int)); assert_eq!(i64::MAX.to_uint(), Some(i64::MAX as uint)); @@ -684,13 +692,15 @@ mod tests { // uint::MAX.to_u32() is word-size specific assert_eq!(uint::MAX.to_u64(), Some(uint::MAX as u64)); - #[cfg(target_word_size = "32")] + #[cfg(any(all(stage0, target_word_size = "32"), + all(not(stage0), target_pointer_width = "32")))] fn check_word_size() { assert_eq!(uint::MAX.to_u32(), Some(uint::MAX as u32)); assert_eq!(uint::MAX.to_i64(), Some(uint::MAX as i64)); } - #[cfg(target_word_size = "64")] + #[cfg(any(all(stage0, target_word_size = "64"), + all(not(stage0), target_pointer_width = "64")))] fn check_word_size() { assert_eq!(uint::MAX.to_u32(), None); assert_eq!(uint::MAX.to_i64(), None); @@ -740,12 +750,14 @@ mod tests { assert_eq!(u32::MAX.to_u32(), Some(u32::MAX as u32)); assert_eq!(u32::MAX.to_u64(), Some(u32::MAX as u64)); - #[cfg(target_word_size = "32")] + #[cfg(any(all(stage0, target_word_size = "32"), + all(not(stage0), target_pointer_width = "32")))] fn check_word_size() { assert_eq!(u32::MAX.to_int(), None); } - #[cfg(target_word_size = "64")] + #[cfg(any(all(stage0, target_word_size = "64"), + all(not(stage0), target_pointer_width = "64")))] fn check_word_size() { assert_eq!(u32::MAX.to_int(), Some(u32::MAX as int)); } @@ -766,12 +778,14 @@ mod tests { assert_eq!(u64::MAX.to_u32(), None); assert_eq!(u64::MAX.to_u64(), Some(u64::MAX as u64)); - #[cfg(target_word_size = "32")] + #[cfg(any(all(stage0, target_word_size = "32"), + all(not(stage0), target_pointer_width = "32")))] fn check_word_size() { assert_eq!(u64::MAX.to_uint(), None); } - #[cfg(target_word_size = "64")] + #[cfg(any(all(stage0, target_word_size = "64"), + all(not(stage0), target_pointer_width = "64")))] fn check_word_size() { assert_eq!(u64::MAX.to_uint(), Some(u64::MAX as uint)); } diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs index 0fbc0953b20..0e12eff205f 100644 --- a/src/libstd/num/uint.rs +++ b/src/libstd/num/uint.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Operations and constants for architecture-sized unsigned integers (`uint` type) +//! Deprecated: replaced by `usize`. +//! +//! The rollout of the new type will gradually take place over the +//! alpha cycle along with the development of clearer conventions +//! around integer types. -#![stable] -#![doc(primitive = "uint")] +#![deprecated = "replaced by usize"] pub use core::uint::{BITS, BYTES, MIN, MAX}; diff --git a/src/libstd/num/usize.rs b/src/libstd/num/usize.rs new file mode 100644 index 00000000000..74dd38e13c5 --- /dev/null +++ b/src/libstd/num/usize.rs @@ -0,0 +1,22 @@ +// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Operations and constants for pointer-sized unsigned integers (`usize` type) +//! +//! This type was recently added to replace `uint`. The rollout of the +//! new type will gradually take place over the alpha cycle along with +//! the development of clearer conventions around integer types. + +#![stable] +#![doc(primitive = "usize")] + +pub use core::usize::{BITS, BYTES, MIN, MAX}; + +uint_module! { usize } diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 581969e98fb..b474ae4e371 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -68,7 +68,7 @@ use fmt; use iter::IteratorExt; use option::Option; use option::Option::{None, Some}; -use ops::{FullRange, Index}; +use ops::FullRange; use str; use str::StrExt; use string::{String, CowString}; @@ -352,7 +352,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { match name.rposition_elem(&dot) { None | Some(0) => name, Some(1) if name == b".." => name, - Some(pos) => name.index(&(0..pos)) + Some(pos) => &name[0..pos] } }) } @@ -399,7 +399,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { match name.rposition_elem(&dot) { None | Some(0) => None, Some(1) if name == b".." => None, - Some(pos) => Some(name.index(&((pos+1)..))) + Some(pos) => Some(&name[(pos+1)..]) } } } @@ -475,7 +475,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { let extlen = extension.container_as_bytes().len(); match (name.rposition_elem(&dot), extlen) { (None, 0) | (Some(0), 0) => None, - (Some(idx), 0) => Some(name.index(&(0..idx)).to_vec()), + (Some(idx), 0) => Some(name[0..idx].to_vec()), (idx, extlen) => { let idx = match idx { None | Some(0) => name.len(), @@ -484,7 +484,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { let mut v; v = Vec::with_capacity(idx + extlen + 1); - v.push_all(name.index(&(0..idx))); + v.push_all(&name[0..idx]); v.push(dot); v.push_all(extension.container_as_bytes()); Some(v) @@ -823,7 +823,6 @@ pub struct Display<'a, P:'a> { filename: bool } -//NOTE(stage0): replace with deriving(Show) after snapshot impl<'a, P: GenericPath> fmt::Show for Display<'a, P> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::String::fmt(self, f) @@ -877,7 +876,7 @@ impl BytesContainer for String { } #[inline] fn container_as_str(&self) -> Option<&str> { - Some(self.index(&FullRange)) + Some(&self[]) } #[inline] fn is_str(_: Option<&String>) -> bool { true } @@ -893,7 +892,7 @@ impl BytesContainer for [u8] { impl BytesContainer for Vec<u8> { #[inline] fn container_as_bytes(&self) -> &[u8] { - self.index(&FullRange) + &self[] } } diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 0b7dc19fcab..293696d5cca 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -17,7 +17,6 @@ use hash; use io::Writer; use iter::{AdditiveIterator, Extend}; use iter::{Iterator, IteratorExt, Map}; -use ops::Index; use marker::Sized; use option::Option::{self, Some, None}; use slice::{AsSlice, Split, SliceExt, SliceConcatExt}; @@ -60,7 +59,7 @@ pub fn is_sep(c: char) -> bool { impl fmt::Show for Path { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Path {{ {} }}", self.display()) + fmt::Show::fmt(&self.display(), f) } } @@ -91,7 +90,7 @@ impl FromStr for Path { } } -impl<S: hash::Writer> hash::Hash<S> for Path { +impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path { #[inline] fn hash(&self, state: &mut S) { self.repr.hash(state) @@ -127,7 +126,7 @@ impl GenericPathUnsafe for Path { None => { self.repr = Path::normalize(filename); } - Some(idx) if self.repr.index(&((idx+1)..)) == b".." => { + Some(idx) if &self.repr[(idx+1)..] == b".." => { let mut v = Vec::with_capacity(self.repr.len() + 1 + filename.len()); v.push_all(self.repr.as_slice()); v.push(SEP_BYTE); @@ -137,7 +136,7 @@ impl GenericPathUnsafe for Path { } Some(idx) => { let mut v = Vec::with_capacity(idx + 1 + filename.len()); - v.push_all(self.repr.index(&(0..(idx+1)))); + v.push_all(&self.repr[0..(idx+1)]); v.push_all(filename); // FIXME: this is slow self.repr = Path::normalize(v.as_slice()); @@ -178,9 +177,9 @@ impl GenericPath for Path { match self.sepidx { None if b".." == self.repr => self.repr.as_slice(), None => dot_static, - Some(0) => self.repr.index(&(0..1)), - Some(idx) if self.repr.index(&((idx+1)..)) == b".." => self.repr.as_slice(), - Some(idx) => self.repr.index(&(0..idx)) + Some(0) => &self.repr[0..1], + Some(idx) if &self.repr[(idx+1)..] == b".." => self.repr.as_slice(), + Some(idx) => &self.repr[0..idx] } } @@ -189,9 +188,9 @@ impl GenericPath for Path { None if b"." == self.repr || b".." == self.repr => None, None => Some(self.repr.as_slice()), - Some(idx) if self.repr.index(&((idx+1)..)) == b".." => None, - Some(0) if self.repr.index(&(1..)).is_empty() => None, - Some(idx) => Some(self.repr.index(&((idx+1)..))) + Some(idx) if &self.repr[(idx+1)..] == b".." => None, + Some(0) if self.repr[1..].is_empty() => None, + Some(idx) => Some(&self.repr[(idx+1)..]) } } @@ -333,7 +332,7 @@ impl Path { // borrowck is being very picky let val = { let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE; - let v_ = if is_abs { v.as_slice().index(&(1..)) } else { v.as_slice() }; + let v_ = if is_abs { &v.as_slice()[1..] } else { v.as_slice() }; let comps = normalize_helper(v_, is_abs); match comps { None => None, @@ -372,7 +371,7 @@ impl Path { /// A path of "/" yields no components. A path of "." yields one component. pub fn components<'a>(&'a self) -> Components<'a> { let v = if self.repr[0] == SEP_BYTE { - self.repr.index(&(1..)) + &self.repr[1..] } else { self.repr.as_slice() }; let is_sep_byte: fn(&u8) -> bool = is_sep_byte; // coerce to fn ptr let mut ret = v.split(is_sep_byte); diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 5c4e7aa9ac2..2a1f1794e49 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -25,7 +25,7 @@ use iter::{AdditiveIterator, Extend}; use iter::{Iterator, IteratorExt, Map, repeat}; use mem; use option::Option::{self, Some, None}; -use ops::{FullRange, Index}; +use ops::FullRange; use slice::{SliceExt, SliceConcatExt}; use str::{SplitTerminator, FromStr, StrExt}; use string::{String, ToString}; @@ -87,7 +87,7 @@ pub struct Path { impl fmt::Show for Path { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Path {{ {} }}", self.display()) + fmt::Show::fmt(&self.display(), f) } } @@ -118,7 +118,7 @@ impl FromStr for Path { } } -impl<S: hash::Writer> hash::Hash<S> for Path { +impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path { #[cfg(not(test))] #[inline] fn hash(&self, state: &mut S) { @@ -173,30 +173,30 @@ impl GenericPathUnsafe for Path { s.push_str(".."); s.push(SEP); s.push_str(filename); - self.update_normalized(s.index(&FullRange)); + self.update_normalized(&s[]); } None => { self.update_normalized(filename); } - Some((_,idxa,end)) if self.repr.index(&(idxa..end)) == ".." => { + Some((_,idxa,end)) if &self.repr[idxa..end] == ".." => { let mut s = String::with_capacity(end + 1 + filename.len()); - s.push_str(self.repr.index(&(0..end))); + s.push_str(&self.repr[0..end]); s.push(SEP); s.push_str(filename); - self.update_normalized(s.index(&FullRange)); + self.update_normalized(&s[]); } Some((idxb,idxa,_)) if self.prefix == Some(DiskPrefix) && idxa == self.prefix_len() => { let mut s = String::with_capacity(idxb + filename.len()); - s.push_str(self.repr.index(&(0..idxb))); + s.push_str(&self.repr[0..idxb]); s.push_str(filename); - self.update_normalized(s.index(&FullRange)); + self.update_normalized(&s[]); } Some((idxb,_,_)) => { let mut s = String::with_capacity(idxb + 1 + filename.len()); - s.push_str(self.repr.index(&(0..idxb))); + s.push_str(&self.repr[0..idxb]); s.push(SEP); s.push_str(filename); - self.update_normalized(s.index(&FullRange)); + self.update_normalized(&s[]); } } } @@ -215,12 +215,12 @@ impl GenericPathUnsafe for Path { let path = path.container_as_str().unwrap(); fn is_vol_abs(path: &str, prefix: Option<PathPrefix>) -> bool { // assume prefix is Some(DiskPrefix) - let rest = path.index(&(prefix_len(prefix)..)); + let rest = &path[prefix_len(prefix)..]; !rest.is_empty() && rest.as_bytes()[0].is_ascii() && is_sep(rest.as_bytes()[0] as char) } fn shares_volume(me: &Path, path: &str) -> bool { // path is assumed to have a prefix of Some(DiskPrefix) - let repr = me.repr.index(&FullRange); + let repr = &me.repr[]; match me.prefix { Some(DiskPrefix) => { repr.as_bytes()[0] == path.as_bytes()[0].to_ascii_uppercase() @@ -252,7 +252,7 @@ impl GenericPathUnsafe for Path { else { None }; let pathlen = path_.as_ref().map_or(path.len(), |p| p.len()); let mut s = String::with_capacity(me.repr.len() + 1 + pathlen); - s.push_str(me.repr.index(&FullRange)); + s.push_str(&me.repr[]); let plen = me.prefix_len(); // if me is "C:" we don't want to add a path separator match me.prefix { @@ -264,9 +264,9 @@ impl GenericPathUnsafe for Path { } match path_ { None => s.push_str(path), - Some(p) => s.push_str(p.index(&FullRange)), + Some(p) => s.push_str(&p[]), }; - me.update_normalized(s.index(&FullRange)) + me.update_normalized(&s[]) } if !path.is_empty() { @@ -274,7 +274,7 @@ impl GenericPathUnsafe for Path { match prefix { Some(DiskPrefix) if !is_vol_abs(path, prefix) && shares_volume(self, path) => { // cwd-relative path, self is on the same volume - append_path(self, path.index(&(prefix_len(prefix)..))); + append_path(self, &path[prefix_len(prefix)..]); } Some(_) => { // absolute path, or cwd-relative and self is not same volume @@ -320,7 +320,7 @@ impl GenericPath for Path { /// Always returns a `Some` value. #[inline] fn as_str<'a>(&'a self) -> Option<&'a str> { - Some(self.repr.index(&FullRange)) + Some(&self.repr[]) } #[inline] @@ -342,21 +342,21 @@ impl GenericPath for Path { /// Always returns a `Some` value. fn dirname_str<'a>(&'a self) -> Option<&'a str> { Some(match self.sepidx_or_prefix_len() { - None if ".." == self.repr => self.repr.index(&FullRange), + None if ".." == self.repr => &self.repr[], None => ".", - Some((_,idxa,end)) if self.repr.index(&(idxa..end)) == ".." => { - self.repr.index(&FullRange) + Some((_,idxa,end)) if &self.repr[idxa..end] == ".." => { + &self.repr[] } - Some((idxb,_,end)) if self.repr.index(&(idxb..end)) == "\\" => { - self.repr.index(&FullRange) + Some((idxb,_,end)) if &self.repr[idxb..end] == "\\" => { + &self.repr[] } - Some((0,idxa,_)) => self.repr.index(&(0..idxa)), + Some((0,idxa,_)) => &self.repr[0..idxa], Some((idxb,idxa,_)) => { match self.prefix { Some(DiskPrefix) | Some(VerbatimDiskPrefix) if idxb == self.prefix_len() => { - self.repr.index(&(0..idxa)) + &self.repr[0..idxa] } - _ => self.repr.index(&(0..idxb)) + _ => &self.repr[0..idxb] } } }) @@ -370,13 +370,13 @@ impl GenericPath for Path { /// See `GenericPath::filename_str` for info. /// Always returns a `Some` value if `filename` returns a `Some` value. fn filename_str<'a>(&'a self) -> Option<&'a str> { - let repr = self.repr.index(&FullRange); + let repr = &self.repr[]; match self.sepidx_or_prefix_len() { None if "." == repr || ".." == repr => None, None => Some(repr), - Some((_,idxa,end)) if repr.index(&(idxa..end)) == ".." => None, + Some((_,idxa,end)) if &repr[idxa..end] == ".." => None, Some((_,idxa,end)) if idxa == end => None, - Some((_,idxa,end)) => Some(repr.index(&(idxa..end))) + Some((_,idxa,end)) => Some(&repr[idxa..end]) } } @@ -408,7 +408,7 @@ impl GenericPath for Path { true } Some((idxb,idxa,end)) if idxb == idxa && idxb == end => false, - Some((idxb,_,end)) if self.repr.index(&(idxb..end)) == "\\" => false, + Some((idxb,_,end)) if &self.repr[idxb..end] == "\\" => false, Some((idxb,idxa,_)) => { let trunc = match self.prefix { Some(DiskPrefix) | Some(VerbatimDiskPrefix) | None => { @@ -428,15 +428,15 @@ impl GenericPath for Path { if self.prefix.is_some() { Some(Path::new(match self.prefix { Some(DiskPrefix) if self.is_absolute() => { - self.repr.index(&(0..(self.prefix_len()+1))) + &self.repr[0..(self.prefix_len()+1)] } Some(VerbatimDiskPrefix) => { - self.repr.index(&(0..(self.prefix_len()+1))) + &self.repr[0..(self.prefix_len()+1)] } - _ => self.repr.index(&(0..self.prefix_len())) + _ => &self.repr[0..self.prefix_len()] })) } else if is_vol_relative(self) { - Some(Path::new(self.repr.index(&(0..1)))) + Some(Path::new(&self.repr[0..1])) } else { None } @@ -455,7 +455,7 @@ impl GenericPath for Path { fn is_absolute(&self) -> bool { match self.prefix { Some(DiskPrefix) => { - let rest = self.repr.index(&(self.prefix_len()..)); + let rest = &self.repr[self.prefix_len()..]; rest.len() > 0 && rest.as_bytes()[0] == SEP_BYTE } Some(_) => true, @@ -630,15 +630,15 @@ impl Path { /// Does not distinguish between absolute and cwd-relative paths, e.g. /// C:\foo and C:foo. pub fn str_components<'a>(&'a self) -> StrComponents<'a> { - let repr = self.repr.index(&FullRange); + let repr = &self.repr[]; let s = match self.prefix { Some(_) => { let plen = self.prefix_len(); if repr.len() > plen && repr.as_bytes()[plen] == SEP_BYTE { - repr.index(&((plen+1)..)) - } else { repr.index(&(plen..)) } + &repr[(plen+1)..] + } else { &repr[plen..] } } - None if repr.as_bytes()[0] == SEP_BYTE => repr.index(&(1..)), + None if repr.as_bytes()[0] == SEP_BYTE => &repr[1..], None => repr }; let some: fn(&'a str) -> Option<&'a str> = Some; // coerce to fn ptr @@ -658,8 +658,8 @@ impl Path { } fn equiv_prefix(&self, other: &Path) -> bool { - let s_repr = self.repr.index(&FullRange); - let o_repr = other.repr.index(&FullRange); + let s_repr = &self.repr[]; + let o_repr = &other.repr[]; match (self.prefix, other.prefix) { (Some(DiskPrefix), Some(VerbatimDiskPrefix)) => { self.is_absolute() && @@ -676,14 +676,14 @@ impl Path { o_repr.as_bytes()[4].to_ascii_lowercase() } (Some(UNCPrefix(_,_)), Some(VerbatimUNCPrefix(_,_))) => { - s_repr.index(&(2..self.prefix_len())) == o_repr.index(&(8..other.prefix_len())) + &s_repr[2..self.prefix_len()] == &o_repr[8..other.prefix_len()] } (Some(VerbatimUNCPrefix(_,_)), Some(UNCPrefix(_,_))) => { - s_repr.index(&(8..self.prefix_len())) == o_repr.index(&(2..other.prefix_len())) + &s_repr[8..self.prefix_len()] == &o_repr[2..other.prefix_len()] } (None, None) => true, (a, b) if a == b => { - s_repr.index(&(0..self.prefix_len())) == o_repr.index(&(0..other.prefix_len())) + &s_repr[0..self.prefix_len()] == &o_repr[0..other.prefix_len()] } _ => false } @@ -737,7 +737,7 @@ impl Path { match prefix.unwrap() { DiskPrefix => { let len = prefix_len(prefix) + is_abs as uint; - let mut s = String::from_str(s.index(&(0..len))); + let mut s = String::from_str(&s[0..len]); unsafe { let v = s.as_mut_vec(); v[0] = (*v)[0].to_ascii_uppercase(); @@ -752,7 +752,7 @@ impl Path { } VerbatimDiskPrefix => { let len = prefix_len(prefix) + is_abs as uint; - let mut s = String::from_str(s.index(&(0..len))); + let mut s = String::from_str(&s[0..len]); unsafe { let v = s.as_mut_vec(); v[4] = (*v)[4].to_ascii_uppercase(); @@ -762,14 +762,14 @@ impl Path { _ => { let plen = prefix_len(prefix); if s.len() > plen { - Some(String::from_str(s.index(&(0..plen)))) + Some(String::from_str(&s[0..plen])) } else { None } } } } else if is_abs && comps.is_empty() { Some(repeat(SEP).take(1).collect()) } else { - let prefix_ = s.index(&(0..prefix_len(prefix))); + let prefix_ = &s[0..prefix_len(prefix)]; let n = prefix_.len() + if is_abs { comps.len() } else { comps.len() - 1} + comps.iter().map(|v| v.len()).sum(); @@ -780,15 +780,15 @@ impl Path { s.push(':'); } Some(VerbatimDiskPrefix) => { - s.push_str(prefix_.index(&(0..4))); + s.push_str(&prefix_[0..4]); s.push(prefix_.as_bytes()[4].to_ascii_uppercase() as char); - s.push_str(prefix_.index(&(5..))); + s.push_str(&prefix_[5..]); } Some(UNCPrefix(a,b)) => { s.push_str("\\\\"); - s.push_str(prefix_.index(&(2..(a+2)))); + s.push_str(&prefix_[2..(a+2)]); s.push(SEP); - s.push_str(prefix_.index(&((3+a)..(3+a+b)))); + s.push_str(&prefix_[(3+a)..(3+a+b)]); } Some(_) => s.push_str(prefix_), None => () @@ -813,8 +813,8 @@ impl Path { fn update_sepidx(&mut self) { let s = if self.has_nonsemantic_trailing_slash() { - self.repr.index(&(0..(self.repr.len()-1))) - } else { self.repr.index(&FullRange) }; + &self.repr[0..(self.repr.len()-1)] + } else { &self.repr[] }; let sep_test: fn(char) -> bool = if !prefix_is_verbatim(self.prefix) { is_sep } else { @@ -893,17 +893,17 @@ pub fn is_verbatim(path: &Path) -> bool { /// non-verbatim, the non-verbatim version is returned. /// Otherwise, None is returned. pub fn make_non_verbatim(path: &Path) -> Option<Path> { - let repr = path.repr.index(&FullRange); + let repr = &path.repr[]; let new_path = match path.prefix { Some(VerbatimPrefix(_)) | Some(DeviceNSPrefix(_)) => return None, Some(UNCPrefix(_,_)) | Some(DiskPrefix) | None => return Some(path.clone()), Some(VerbatimDiskPrefix) => { // \\?\D:\ - Path::new(repr.index(&(4..))) + Path::new(&repr[4..]) } Some(VerbatimUNCPrefix(_,_)) => { // \\?\UNC\server\share - Path::new(format!(r"\{}", repr.index(&(7..)))) + Path::new(format!(r"\{}", &repr[7..])) } }; if new_path.prefix.is_none() { @@ -912,8 +912,7 @@ pub fn make_non_verbatim(path: &Path) -> Option<Path> { return None; } // now ensure normalization didn't change anything - if repr.index(&(path.prefix_len()..)) == - new_path.repr.index(&(new_path.prefix_len()..)) { + if &repr[path.prefix_len()..] == &new_path.repr[new_path.prefix_len()..] { Some(new_path) } else { None @@ -978,13 +977,13 @@ pub enum PathPrefix { fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> { if path.starts_with("\\\\") { // \\ - path = path.index(&(2..)); + path = &path[2..]; if path.starts_with("?\\") { // \\?\ - path = path.index(&(2..)); + path = &path[2..]; if path.starts_with("UNC\\") { // \\?\UNC\server\share - path = path.index(&(4..)); + path = &path[4..]; let (idx_a, idx_b) = match parse_two_comps(path, is_sep_verbatim) { Some(x) => x, None => (path.len(), 0) @@ -1005,7 +1004,7 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> { } } else if path.starts_with(".\\") { // \\.\path - path = path.index(&(2..)); + path = &path[2..]; let idx = path.find('\\').unwrap_or(path.len()); return Some(DeviceNSPrefix(idx)); } @@ -1030,7 +1029,7 @@ fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> { None => return None, Some(x) => x }; - path = path.index(&((idx_a+1)..)); + path = &path[(idx_a+1)..]; let idx_b = path.find(f).unwrap_or(path.len()); Some((idx_a, idx_b)) } @@ -1044,8 +1043,8 @@ fn normalize_helper<'a>(s: &'a str, prefix: Option<PathPrefix>) -> (bool, Option is_sep_verbatim }; let is_abs = s.len() > prefix_len(prefix) && f(s.char_at(prefix_len(prefix))); - let s_ = s.index(&(prefix_len(prefix)..)); - let s_ = if is_abs { s_.index(&(1..)) } else { s_ }; + let s_ = &s[prefix_len(prefix)..]; + let s_ = if is_abs { &s_[1..] } else { s_ }; if is_abs && s_.is_empty() { return (is_abs, match prefix { diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index dcb342b9ca2..d9c942c0185 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -17,7 +17,7 @@ #[stable] #[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce}; // TEMPORARY -#[unstable] #[doc(no_inline)] pub use ops::{Index, IndexMut, FullRange}; +#[unstable] #[doc(no_inline)] pub use ops::FullRange; // Reexported functions #[stable] #[doc(no_inline)] pub use mem::drop; diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index d3e6cd166ec..3fa1efe1ccd 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -230,9 +230,9 @@ use rc::Rc; use result::Result::{Ok, Err}; use vec::Vec; -#[cfg(not(target_word_size="64"))] +#[cfg(any(all(stage0, target_word_size = "32"), all(not(stage0), target_pointer_width = "32")))] use core_rand::IsaacRng as IsaacWordRng; -#[cfg(target_word_size="64")] +#[cfg(any(all(stage0, target_word_size = "64"), all(not(stage0), target_pointer_width = "64")))] use core_rand::Isaac64Rng as IsaacWordRng; pub use core_rand::{Rand, Rng, SeedableRng, Open01, Closed01}; @@ -403,7 +403,7 @@ pub fn random<T: Rand>() -> T { /// /// let mut rng = thread_rng(); /// let sample = sample(&mut rng, range(1i, 100), 5); -/// println!("{}", sample); +/// println!("{:?}", sample); /// ``` pub fn sample<T, I: Iterator<Item=T>, R: Rng>(rng: &mut R, mut iter: I, diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index fd84f220942..03876189da9 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -544,7 +544,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) -> // MAX_CALLBACKS, so we're sure to clamp it as necessary. let callbacks = { let amt = CALLBACK_CNT.load(Ordering::SeqCst); - CALLBACKS.index(&(0..cmp::min(amt, MAX_CALLBACKS))) + &CALLBACKS[0..cmp::min(amt, MAX_CALLBACKS)] }; for cb in callbacks.iter() { match cb.load(Ordering::SeqCst) { diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index 59f654a95ca..c076f0a7c6c 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -131,7 +131,7 @@ pub fn abort(args: fmt::Arguments) -> ! { impl<'a> fmt::Writer for BufWriter<'a> { fn write_str(&mut self, bytes: &str) -> fmt::Result { let left = self.buf.slice_from_mut(self.pos); - let to_write = bytes.as_bytes().index(&(0..cmp::min(bytes.len(), left.len()))); + let to_write = &bytes.as_bytes()[0..cmp::min(bytes.len(), left.len())]; slice::bytes::copy_memory(left, to_write); self.pos += to_write.len(); Ok(()) @@ -142,7 +142,7 @@ pub fn abort(args: fmt::Arguments) -> ! { let mut msg = [0u8; 512]; let mut w = BufWriter { buf: &mut msg, pos: 0 }; let _ = write!(&mut w, "{}", args); - let msg = str::from_utf8(w.buf.index_mut(&(0..w.pos))).unwrap_or("aborted"); + let msg = str::from_utf8(&w.buf[0..w.pos]).unwrap_or("aborted"); let msg = if msg.is_empty() {"aborted"} else {msg}; // Give some context to the message diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs index bd1e74a3390..f4b20c7b742 100644 --- a/src/libstd/sync/mpsc/stream.rs +++ b/src/libstd/sync/mpsc/stream.rs @@ -338,7 +338,7 @@ impl<T: Send> Packet<T> { // upgrade pending, then go through the whole recv rigamarole to update // the internal state. match self.queue.peek() { - Some(&GoUp(..)) => { + Some(&mut GoUp(..)) => { match self.recv() { Err(Upgraded(port)) => Err(port), _ => unreachable!(), @@ -367,7 +367,7 @@ impl<T: Send> Packet<T> { Ok(()) => SelSuccess, Err(token) => { let ret = match self.queue.peek() { - Some(&GoUp(..)) => { + Some(&mut GoUp(..)) => { match self.queue.pop() { Some(GoUp(port)) => SelUpgraded(token, port), _ => unreachable!(), @@ -457,7 +457,7 @@ impl<T: Send> Packet<T> { // upgraded port. if has_data { match self.queue.peek() { - Some(&GoUp(..)) => { + Some(&mut GoUp(..)) => { match self.queue.pop() { Some(GoUp(port)) => Err(port), _ => unreachable!(), diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs index be44aa99f49..f6161ec193d 100644 --- a/src/libstd/sys/common/backtrace.rs +++ b/src/libstd/sys/common/backtrace.rs @@ -12,8 +12,11 @@ use prelude::v1::*; use io::IoResult; -#[cfg(target_word_size = "64")] pub const HEX_WIDTH: uint = 18; -#[cfg(target_word_size = "32")] pub const HEX_WIDTH: uint = 10; +#[cfg(any(all(stage0, target_word_size = "64"), all(not(stage0), target_pointer_width = "64")))] +pub const HEX_WIDTH: uint = 18; + +#[cfg(any(all(stage0, target_word_size = "32"), all(not(stage0), target_pointer_width = "32")))] +pub const HEX_WIDTH: uint = 10; // All rust symbols are in theory lists of "::"-separated identifiers. Some // assemblers, however, can't handle these characters in symbol names. To get diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 902942d7244..4cf891ac498 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -469,7 +469,7 @@ pub fn write<T, L, W>(fd: sock_t, // Also as with read(), we use MSG_DONTWAIT to guard ourselves // against unforeseen circumstances. let _guard = lock(); - let ptr = buf.index(&(written..)).as_ptr(); + let ptr = buf[written..].as_ptr(); let len = buf.len() - written; match retry(|| write(deadline.is_some(), ptr, len)) { -1 if wouldblock() => {} diff --git a/src/libstd/sys/unix/c.rs b/src/libstd/sys/unix/c.rs index cc661877bc0..1d523ed6edd 100644 --- a/src/libstd/sys/unix/c.rs +++ b/src/libstd/sys/unix/c.rs @@ -169,13 +169,13 @@ mod signal { unsafe impl ::marker::Sync for sigaction { } #[repr(C)] - #[cfg(target_word_size = "32")] + #[cfg(any(all(stage0, target_word_size = "32"), all(not(stage0), target_pointer_width = "32")))] pub struct sigset_t { __val: [libc::c_ulong; 32], } #[repr(C)] - #[cfg(target_word_size = "64")] + #[cfg(any(all(stage0, target_word_size = "64"), all(not(stage0), target_pointer_width = "64")))] pub struct sigset_t { __val: [libc::c_ulong; 16], } diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 1357bbdd5a3..36bf696dba5 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -11,7 +11,8 @@ use prelude::v1::*; use self::Req::*; -use collections; +use collections::HashMap; +use collections::hash_map::Hasher; use ffi::CString; use hash::Hash; use io::process::{ProcessExit, ExitStatus, ExitSignal}; @@ -60,7 +61,7 @@ impl Process { out_fd: Option<P>, err_fd: Option<P>) -> IoResult<Process> where C: ProcessConfig<K, V>, P: AsInner<FileDesc>, - K: BytesContainer + Eq + Hash, V: BytesContainer + K: BytesContainer + Eq + Hash<Hasher>, V: BytesContainer { use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp}; use libc::funcs::bsd44::getdtablesize; @@ -553,11 +554,11 @@ fn with_argv<T,F>(prog: &CString, args: &[CString], cb(ptrs.as_ptr()) } -fn with_envp<K,V,T,F>(env: Option<&collections::HashMap<K, V>>, +fn with_envp<K,V,T,F>(env: Option<&HashMap<K, V>>, cb: F) -> T where F : FnOnce(*const c_void) -> T, - K : BytesContainer + Eq + Hash, + K : BytesContainer + Eq + Hash<Hasher>, V : BytesContainer { // On posixy systems we can pass a char** for envp, which is a diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index 1fd619a28db..48a51813ba4 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -182,12 +182,14 @@ mod imp { sa_restorer: *mut libc::c_void, } - #[cfg(target_word_size = "32")] + #[cfg(any(all(stage0, target_word_size = "32"), + all(not(stage0), target_pointer_width = "32")))] #[repr(C)] pub struct sigset_t { __val: [libc::c_ulong; 32], } - #[cfg(target_word_size = "64")] + #[cfg(any(all(stage0, target_word_size = "64"), + all(not(stage0), target_pointer_width = "64")))] #[repr(C)] pub struct sigset_t { __val: [libc::c_ulong; 16], diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs index eb76f13afe7..ee2dd14955b 100644 --- a/src/libstd/sys/windows/backtrace.rs +++ b/src/libstd/sys/windows/backtrace.rs @@ -362,7 +362,7 @@ pub fn write(w: &mut Writer) -> IoResult<()> { let bytes = unsafe { ffi::c_str_to_bytes(&ptr) }; match str::from_utf8(bytes) { Ok(s) => try!(demangle(w, s)), - Err(..) => try!(w.write(bytes.index(&(..(bytes.len()-1))))), + Err(..) => try!(w.write(&bytes[..(bytes.len()-1)])), } } try!(w.write(&['\n' as u8])); diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index f8c75335b35..a7330f7c67c 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -270,7 +270,7 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> { return Err(IoError { kind: io::InvalidInput, desc: "path was not valid UTF-16", - detail: Some(format!("path was not valid UTF-16: {}", filename)), + detail: Some(format!("path was not valid UTF-16: {:?}", filename)), }) }, // FIXME #12056: Convert the UCS-2 to invalid utf-8 instead of erroring } diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index fcde5c01080..064633f321c 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -36,7 +36,7 @@ const BUF_BYTES : uint = 2048u; pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { match v.iter().position(|c| *c == 0) { // don't include the 0 - Some(i) => v.index(&(0..i)), + Some(i) => &v[0..i], None => v } } diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 016757ef63e..9996909f2f5 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -453,7 +453,7 @@ impl UnixStream { } let ret = unsafe { libc::WriteFile(self.handle(), - buf.index(&(offset..)).as_ptr() as libc::LPVOID, + buf[offset..].as_ptr() as libc::LPVOID, (buf.len() - offset) as libc::DWORD, &mut bytes_written, &mut overlapped) diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 8e1f169b5cd..1b837385d1e 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -13,6 +13,7 @@ use prelude::v1::*; use collections; use ffi::CString; use hash::Hash; +use collections::hash_map::Hasher; use io::fs::PathExtensions; use io::process::{ProcessExit, ExitStatus, ExitSignal}; use io::{IoResult, IoError}; @@ -109,7 +110,7 @@ impl Process { out_fd: Option<P>, err_fd: Option<P>) -> IoResult<Process> where C: ProcessConfig<K, V>, P: AsInner<FileDesc>, - K: BytesContainer + Eq + Hash, V: BytesContainer + K: BytesContainer + Eq + Hash<Hasher>, V: BytesContainer { use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO}; use libc::consts::os::extra::{ @@ -424,8 +425,10 @@ fn make_command_line(prog: &CString, args: &[CString]) -> String { } } -fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T where - K: BytesContainer + Eq + Hash, V: BytesContainer, F: FnOnce(*mut c_void) -> T, +fn with_envp<K, V, T, F>(env: Option<&collections::HashMap<K, V>>, cb: F) -> T + where K: BytesContainer + Eq + Hash<Hasher>, + V: BytesContainer, + F: FnOnce(*mut c_void) -> T, { // On Windows we pass an "environment block" which is not a char**, but // rather a concatenation of null-terminated k=v\0 sequences, with a final diff --git a/src/libstd/sys/windows/timer.rs b/src/libstd/sys/windows/timer.rs index 343b78543bf..1ae3979cd9a 100644 --- a/src/libstd/sys/windows/timer.rs +++ b/src/libstd/sys/windows/timer.rs @@ -91,7 +91,7 @@ fn helper(input: libc::HANDLE, messages: Receiver<Req>, _: ()) { } else { let remove = { match &mut chans[idx as uint - 1] { - &(ref mut c, oneshot) => { c.call(); oneshot } + &mut (ref mut c, oneshot) => { c.call(); oneshot } } }; if remove { |
