diff options
| author | bors <bors@rust-lang.org> | 2015-02-19 18:36:59 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-02-19 18:36:59 +0000 |
| commit | 522d09dfecbeca1595f25ac58c6d0178bbd21d7d (patch) | |
| tree | cc0252dd3413e5f890d0ebcfdaa096e5b002be0b /src/libcore | |
| parent | 0b664bb8436f2cfda7f13a6f302ab486f332816f (diff) | |
| parent | 49771bafa5fca16486bfd06741dac3de2c587adf (diff) | |
| download | rust-522d09dfecbeca1595f25ac58c6d0178bbd21d7d.tar.gz rust-522d09dfecbeca1595f25ac58c6d0178bbd21d7d.zip | |
Auto merge of #22541 - Manishearth:rollup, r=Gankro 1.0.0-alpha.2
Continued from #22520
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/array.rs | 40 | ||||
| -rw-r--r-- | src/libcore/atomic.rs | 5 | ||||
| -rw-r--r-- | src/libcore/borrow.rs | 265 | ||||
| -rw-r--r-- | src/libcore/cmp.rs | 12 | ||||
| -rw-r--r-- | src/libcore/default.rs | 16 | ||||
| -rw-r--r-- | src/libcore/fmt/mod.rs | 7 | ||||
| -rw-r--r-- | src/libcore/hash/mod.rs | 471 | ||||
| -rw-r--r-- | src/libcore/hash/sip.rs | 45 | ||||
| -rw-r--r-- | src/libcore/intrinsics.rs | 24 | ||||
| -rw-r--r-- | src/libcore/iter.rs | 52 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 1 | ||||
| -rw-r--r-- | src/libcore/marker.rs | 393 | ||||
| -rw-r--r-- | src/libcore/nonzero.rs | 9 | ||||
| -rw-r--r-- | src/libcore/option.rs | 6 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 56 | ||||
| -rw-r--r-- | src/libcore/result.rs | 7 | ||||
| -rw-r--r-- | src/libcore/slice.rs | 14 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 2 |
18 files changed, 728 insertions, 697 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 838ca4e478b..afb5d95c9f8 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -17,7 +17,7 @@ use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use fmt; -use hash::{Hash, Hasher, self}; +use hash::{Hash, self}; use iter::IntoIterator; use marker::Copy; use ops::Deref; @@ -35,16 +35,24 @@ macro_rules! array_impls { } } - impl<S: hash::Writer + Hasher, T: Hash<S>> Hash<S> for [T; $N] { + #[cfg(stage0)] + impl<S: hash::Writer + hash::Hasher, T: Hash<S>> Hash<S> for [T; $N] { fn hash(&self, state: &mut S) { - Hash::hash(&self[], state) + Hash::hash(&self[..], state) + } + } + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + impl<T: Hash> Hash for [T; $N] { + fn hash<H: hash::Hasher>(&self, state: &mut H) { + Hash::hash(&self[..], state) } } #[stable(feature = "rust1", since = "1.0.0")] impl<T: fmt::Debug> fmt::Debug for [T; $N] { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&&self[], f) + fmt::Debug::fmt(&&self[..], f) } } @@ -72,11 +80,11 @@ macro_rules! array_impls { impl<A, B> PartialEq<[B; $N]> for [A; $N] where A: PartialEq<B> { #[inline] fn eq(&self, other: &[B; $N]) -> bool { - &self[] == &other[] + &self[..] == &other[..] } #[inline] fn ne(&self, other: &[B; $N]) -> bool { - &self[] != &other[] + &self[..] != &other[..] } } @@ -87,11 +95,11 @@ macro_rules! array_impls { { #[inline(always)] fn eq(&self, other: &Rhs) -> bool { - PartialEq::eq(&self[], &**other) + PartialEq::eq(&self[..], &**other) } #[inline(always)] fn ne(&self, other: &Rhs) -> bool { - PartialEq::ne(&self[], &**other) + PartialEq::ne(&self[..], &**other) } } @@ -102,11 +110,11 @@ macro_rules! array_impls { { #[inline(always)] fn eq(&self, other: &[B; $N]) -> bool { - PartialEq::eq(&**self, &other[]) + PartialEq::eq(&**self, &other[..]) } #[inline(always)] fn ne(&self, other: &[B; $N]) -> bool { - PartialEq::ne(&**self, &other[]) + PartialEq::ne(&**self, &other[..]) } } @@ -117,23 +125,23 @@ macro_rules! array_impls { impl<T:PartialOrd> PartialOrd for [T; $N] { #[inline] fn partial_cmp(&self, other: &[T; $N]) -> Option<Ordering> { - PartialOrd::partial_cmp(&&self[], &&other[]) + PartialOrd::partial_cmp(&&self[..], &&other[..]) } #[inline] fn lt(&self, other: &[T; $N]) -> bool { - PartialOrd::lt(&&self[], &&other[]) + PartialOrd::lt(&&self[..], &&other[..]) } #[inline] fn le(&self, other: &[T; $N]) -> bool { - PartialOrd::le(&&self[], &&other[]) + PartialOrd::le(&&self[..], &&other[..]) } #[inline] fn ge(&self, other: &[T; $N]) -> bool { - PartialOrd::ge(&&self[], &&other[]) + PartialOrd::ge(&&self[..], &&other[..]) } #[inline] fn gt(&self, other: &[T; $N]) -> bool { - PartialOrd::gt(&&self[], &&other[]) + PartialOrd::gt(&&self[..], &&other[..]) } } @@ -141,7 +149,7 @@ macro_rules! array_impls { impl<T:Ord> Ord for [T; $N] { #[inline] fn cmp(&self, other: &[T; $N]) -> Ordering { - Ord::cmp(&&self[], &&other[]) + Ord::cmp(&&self[..], &&other[..]) } } )+ diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index 05d864accc1..6afe5b2257d 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -76,6 +76,7 @@ use marker::Sync; use intrinsics; use cell::UnsafeCell; +use marker::PhantomData; /// A boolean type which can be safely shared between threads. #[stable(feature = "rust1", since = "1.0.0")] @@ -105,6 +106,7 @@ unsafe impl Sync for AtomicUsize {} #[stable(feature = "rust1", since = "1.0.0")] pub struct AtomicPtr<T> { p: UnsafeCell<usize>, + _marker: PhantomData<*mut T>, } unsafe impl<T> Sync for AtomicPtr<T> {} @@ -791,7 +793,8 @@ impl<T> AtomicPtr<T> { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn new(p: *mut T) -> AtomicPtr<T> { - AtomicPtr { p: UnsafeCell::new(p as usize) } + AtomicPtr { p: UnsafeCell::new(p as usize), + _marker: PhantomData } } /// Loads a value from the pointer. diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs deleted file mode 100644 index 035443e9c3f..00000000000 --- a/src/libcore/borrow.rs +++ /dev/null @@ -1,265 +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. - -//! A module for working with borrowed data. -//! -//! # The `BorrowFrom` traits -//! -//! In general, there may be several ways to "borrow" a piece of data. The -//! typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` -//! (a mutable borrow). But types like `Vec<T>` provide additional kinds of -//! borrows: the borrowed slices `&[T]` and `&mut [T]`. -//! -//! When writing generic code, it is often desirable to abstract over all ways -//! of borrowing data from a given type. That is the role of the `BorrowFrom` -//! trait: if `T: BorrowFrom<U>`, then `&T` can be borrowed from `&U`. A given -//! type can be borrowed as multiple different types. In particular, `Vec<T>: -//! BorrowFrom<Vec<T>>` and `[T]: BorrowFrom<Vec<T>>`. -//! -//! # The `ToOwned` trait -//! -//! Some types make it possible to go from borrowed to owned, usually by -//! implementing the `Clone` trait. But `Clone` works only for going from `&T` -//! to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data -//! from any borrow of a given type. -//! -//! # The `Cow` (clone-on-write) type -//! -//! The type `Cow` is a smart pointer providing clone-on-write functionality: it -//! can enclose and provide immutable access to borrowed data, and clone the -//! data lazily when mutation or ownership is required. The type is designed to -//! work with general borrowed data via the `BorrowFrom` trait. -//! -//! `Cow` implements both `Deref`, which means that you can call -//! non-mutating methods directly on the data it encloses. If mutation -//! is desired, `to_mut` will obtain a mutable references to an owned -//! value, cloning if necessary. - -#![unstable(feature = "core", - reason = "recently added as part of collections reform")] - -use clone::Clone; -use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; -use fmt; -use marker::Sized; -use ops::Deref; -use option::Option; -use self::Cow::*; - -/// A trait for borrowing data. -#[old_orphan_check] -pub trait BorrowFrom<Owned: ?Sized> { - /// Immutably borrow from an owned value. - fn borrow_from(owned: &Owned) -> &Self; -} - -/// A trait for mutably borrowing data. -#[old_orphan_check] -pub trait BorrowFromMut<Owned: ?Sized> : BorrowFrom<Owned> { - /// Mutably borrow from an owned value. - fn borrow_from_mut(owned: &mut Owned) -> &mut Self; -} - -impl<T: ?Sized> BorrowFrom<T> for T { - fn borrow_from(owned: &T) -> &T { owned } -} - -impl<T: ?Sized> BorrowFromMut<T> for T { - fn borrow_from_mut(owned: &mut T) -> &mut T { owned } -} - -impl<'a, T: ?Sized> BorrowFrom<&'a T> for T { - fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned } -} - -impl<'a, T: ?Sized> BorrowFrom<&'a mut T> for T { - fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned } -} - -impl<'a, T: ?Sized> BorrowFromMut<&'a mut T> for T { - fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned } -} - -impl<'a, T, B: ?Sized> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> { - fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B { - &**owned - } -} - -/// Trait for moving into a `Cow` -#[old_orphan_check] -pub trait IntoCow<'a, T, B: ?Sized> { - /// Moves `self` into `Cow` - fn into_cow(self) -> Cow<'a, T, B>; -} - -impl<'a, T, B: ?Sized> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned<T> { - fn into_cow(self) -> Cow<'a, T, B> { - self - } -} - -/// A generalization of Clone to borrowed data. -#[old_orphan_check] -pub trait ToOwned<Owned>: BorrowFrom<Owned> { - /// Create owned data from borrowed data, usually by copying. - fn to_owned(&self) -> Owned; -} - -impl<T> ToOwned<T> for T where T: Clone { - fn to_owned(&self) -> T { self.clone() } -} - -/// A clone-on-write smart pointer. -/// -/// # Example -/// -/// ```rust -/// use std::borrow::Cow; -/// -/// fn abs_all(input: &mut Cow<Vec<int>, [int]>) { -/// for i in 0..input.len() { -/// let v = input[i]; -/// if v < 0 { -/// // clones into a vector the first time (if not already owned) -/// input.to_mut()[i] = -v; -/// } -/// } -/// } -/// ``` -pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned<T> { - /// Borrowed data. - Borrowed(&'a B), - - /// Owned data. - Owned(T) -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Clone for Cow<'a, T, B> where B: ToOwned<T> { - fn clone(&self) -> Cow<'a, T, B> { - match *self { - Borrowed(b) => Borrowed(b), - Owned(ref o) => { - let b: &B = BorrowFrom::borrow_from(o); - Owned(b.to_owned()) - }, - } - } -} - -impl<'a, T, B: ?Sized> Cow<'a, T, B> where B: ToOwned<T> { - /// Acquire a mutable reference to the owned form of the data. - /// - /// Copies the data if it is not already owned. - pub fn to_mut(&mut self) -> &mut T { - match *self { - Borrowed(borrowed) => { - *self = Owned(borrowed.to_owned()); - self.to_mut() - } - Owned(ref mut owned) => owned - } - } - - /// Extract the owned data. - /// - /// Copies the data if it is not already owned. - pub fn into_owned(self) -> T { - match self { - Borrowed(borrowed) => borrowed.to_owned(), - Owned(owned) => owned - } - } - - /// Returns true if this `Cow` wraps a borrowed value - pub fn is_borrowed(&self) -> bool { - match *self { - Borrowed(_) => true, - _ => false, - } - } - - /// Returns true if this `Cow` wraps an owned value - pub fn is_owned(&self) -> bool { - match *self { - Owned(_) => true, - _ => false, - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Deref for Cow<'a, T, B> where B: ToOwned<T> { - type Target = B; - - fn deref(&self) -> &B { - match *self { - Borrowed(borrowed) => borrowed, - Owned(ref owned) => BorrowFrom::borrow_from(owned) - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> { - #[inline] - fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering { - Ord::cmp(&**self, &**other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b, T, U, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where - B: PartialEq<C> + ToOwned<T>, - C: ToOwned<U>, -{ - #[inline] - fn eq(&self, other: &Cow<'b, U, C>) -> bool { - PartialEq::eq(&**self, &**other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> { - #[inline] - fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> { - PartialOrd::partial_cmp(&**self, &**other) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> fmt::Debug for Cow<'a, T, B> where - B: fmt::Debug + ToOwned<T>, - T: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Borrowed(ref b) => fmt::Debug::fmt(b, f), - Owned(ref o) => fmt::Debug::fmt(o, f), - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, B: ?Sized> fmt::Display for Cow<'a, T, B> where - B: fmt::Display + ToOwned<T>, - T: fmt::Display, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Borrowed(ref b) => fmt::Display::fmt(b, f), - Owned(ref o) => fmt::Display::fmt(o, f), - } - } -} diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 19ec245300d..b37bad5f754 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -215,7 +215,7 @@ impl Ord for Ordering { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn cmp(&self, other: &Ordering) -> Ordering { - (*self as int).cmp(&(*other as int)) + (*self as i32).cmp(&(*other as i32)) } } @@ -224,7 +224,7 @@ impl PartialOrd for Ordering { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> { - (*self as int).partial_cmp(&(*other as int)) + (*self as i32).partial_cmp(&(*other as i32)) } } @@ -482,7 +482,7 @@ mod impls { } partial_eq_impl! { - bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 + bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } macro_rules! eq_impl { @@ -492,7 +492,7 @@ mod impls { )*) } - eq_impl! { () bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 } + eq_impl! { () bool char usize u8 u16 u32 u64 isize i8 i16 i32 i64 } macro_rules! partial_ord_impl { ($($t:ty)*) => ($( @@ -535,7 +535,7 @@ mod impls { } } - partial_ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 } + partial_ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } macro_rules! ord_impl { ($($t:ty)*) => ($( @@ -565,7 +565,7 @@ mod impls { } } - ord_impl! { char uint u8 u16 u32 u64 int i8 i16 i32 i64 } + ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 } // & pointers diff --git a/src/libcore/default.rs b/src/libcore/default.rs index d79b613f589..7f46d9cbe50 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -16,7 +16,7 @@ //! //! ``` //! struct SomeOptions { -//! foo: int, +//! foo: i32, //! bar: f32, //! } //! ``` @@ -28,7 +28,7 @@ //! //! #[derive(Default)] //! struct SomeOptions { -//! foo: int, +//! foo: i32, //! bar: f32, //! } //! @@ -56,7 +56,7 @@ //! //! #[derive(Default)] //! struct SomeOptions { -//! foo: int, +//! foo: i32, //! bar: f32, //! baz: Kind, //! } @@ -73,7 +73,7 @@ //! # use std::default::Default; //! # #[derive(Default)] //! # struct SomeOptions { -//! # foo: int, +//! # foo: i32, //! # bar: f32, //! # } //! fn main() { @@ -93,7 +93,7 @@ /// ``` /// #[derive(Default)] /// struct SomeOptions { -/// foo: int, +/// foo: i32, /// bar: f32, /// } /// ``` @@ -113,7 +113,7 @@ pub trait Default { /// /// let i: i8 = Default::default(); /// let (x, y): (Option<String>, f64) = Default::default(); - /// let (a, b, (c, d)): (int, uint, (bool, bool)) = Default::default(); + /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default(); /// ``` /// /// Making your own: @@ -150,13 +150,13 @@ default_impl! { (), () } default_impl! { bool, false } default_impl! { char, '\x00' } -default_impl! { uint, 0 } +default_impl! { usize, 0 } default_impl! { u8, 0 } default_impl! { u16, 0 } default_impl! { u32, 0 } default_impl! { u64, 0 } -default_impl! { int, 0 } +default_impl! { isize, 0 } default_impl! { i8, 0 } default_impl! { i16, 0 } default_impl! { i32, 0 } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 67c8c9fec09..a2c1bbc0331 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -16,7 +16,7 @@ use any; use cell::{Cell, RefCell, Ref, RefMut, BorrowState}; use char::CharExt; use iter::{Iterator, IteratorExt}; -use marker::{Copy, Sized}; +use marker::{Copy, PhantomData, Sized}; use mem; use option::Option; use option::Option::{Some, None}; @@ -914,6 +914,11 @@ impl Debug for () { f.pad("()") } } +impl<T> Debug for PhantomData<T> { + fn fmt(&self, f: &mut Formatter) -> Result { + f.pad("PhantomData") + } +} #[stable(feature = "rust1", since = "1.0.0")] impl<T: Copy + Debug> Debug for Cell<T> { diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index a5d2618eff9..2e83334b937 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -35,7 +35,7 @@ //! the trait `Hash`: //! //! ```rust -//! use std::hash::{hash, Hash, Hasher, Writer, SipHasher}; +//! use std::hash::{hash, Hash, Hasher, SipHasher}; //! //! struct Person { //! id: uint, @@ -43,8 +43,8 @@ //! phone: u64, //! } //! -//! impl<H: Hasher + Writer> Hash<H> for Person { -//! fn hash(&self, state: &mut H) { +//! impl Hash for Person { +//! fn hash<H: Hasher>(&self, state: &mut H) { //! self.id.hash(state); //! self.phone.hash(state); //! } @@ -56,15 +56,12 @@ //! assert_eq!(hash::<_, SipHasher>(&person1), hash::<_, SipHasher>(&person2)); //! ``` -#![unstable(feature = "hash", - reason = "module was recently redesigned")] +#![stable(feature = "rust1", since = "1.0.0")] use prelude::*; -use borrow::{Cow, ToOwned}; use default::Default; use mem; -use num::Int; pub use self::sip::SipHasher; @@ -76,22 +73,123 @@ mod sip; /// to compute the hash. Specific implementations of this trait may specialize /// for particular instances of `H` in order to be able to optimize the hashing /// behavior. +#[cfg(not(stage0))] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Hash { + /// Feeds this value into the state given, updating the hasher as necessary. + #[stable(feature = "rust1", since = "1.0.0")] + fn hash<H: Hasher>(&self, state: &mut H); + + /// Feeds a slice of this type into the state provided. + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) where Self: Sized { + for piece in data { + piece.hash(state); + } + } +} + +/// A hashable type. +/// +/// The `H` type parameter is an abstract hash state that is used by the `Hash` +/// to compute the hash. Specific implementations of this trait may specialize +/// for particular instances of `H` in order to be able to optimize the hashing +/// behavior. +#[cfg(stage0)] pub trait Hash<H: Hasher> { /// Feeds this value into the state given, updating the hasher as necessary. fn hash(&self, state: &mut H); } /// A trait which represents the ability to hash an arbitrary stream of bytes. +#[stable(feature = "rust1", since = "1.0.0")] pub trait Hasher { /// Result type of one run of hashing generated by this hasher. + #[cfg(stage0)] type Output; /// Resets this hasher back to its initial state (as if it were just /// created). + #[cfg(stage0)] fn reset(&mut self); /// Completes a round of hashing, producing the output hash generated. + #[cfg(stage0)] fn finish(&self) -> Self::Output; + + /// Completes a round of hashing, producing the output hash generated. + #[cfg(not(stage0))] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn finish(&self) -> u64; + + /// Writes some data into this `Hasher` + #[cfg(not(stage0))] + #[stable(feature = "rust1", since = "1.0.0")] + fn write(&mut self, bytes: &[u8]); + + /// Write a single `u8` into this hasher + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u8(&mut self, i: u8) { self.write(&[i]) } + /// Write a single `u16` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u16(&mut self, i: u16) { + self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) }) + } + /// Write a single `u32` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u32(&mut self, i: u32) { + self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) }) + } + /// Write a single `u64` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_u64(&mut self, i: u64) { + self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) }) + } + /// Write a single `usize` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_usize(&mut self, i: usize) { + if cfg!(target_pointer_width = "32") { + self.write_u32(i as u32) + } else { + self.write_u64(i as u64) + } + } + + /// Write a single `i8` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i8(&mut self, i: i8) { self.write_u8(i as u8) } + /// Write a single `i16` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i16(&mut self, i: i16) { self.write_u16(i as u16) } + /// Write a single `i32` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i32(&mut self, i: i32) { self.write_u32(i as u32) } + /// Write a single `i64` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_i64(&mut self, i: i64) { self.write_u64(i as u64) } + /// Write a single `isize` into this hasher. + #[cfg(not(stage0))] + #[inline] + #[unstable(feature = "hash", reason = "module was recently redesigned")] + fn write_isize(&mut self, i: isize) { self.write_usize(i as usize) } } /// A common bound on the `Hasher` parameter to `Hash` implementations in order @@ -99,6 +197,7 @@ pub trait Hasher { #[unstable(feature = "hash", reason = "this trait will likely be replaced by io::Writer")] #[allow(missing_docs)] +#[cfg(stage0)] pub trait Writer { fn write(&mut self, bytes: &[u8]); } @@ -107,148 +206,292 @@ pub trait Writer { /// /// The specified value will be hashed with this hasher and then the resulting /// hash will be returned. +#[cfg(stage0)] pub fn hash<T: Hash<H>, H: Hasher + Default>(value: &T) -> H::Output { let mut h: H = Default::default(); value.hash(&mut h); h.finish() } +/// Hash a value with the default SipHasher algorithm (two initial keys of 0). +/// +/// The specified value will be hashed with this hasher and then the resulting +/// hash will be returned. +#[cfg(not(stage0))] +#[unstable(feature = "hash", reason = "module was recently redesigned")] +pub fn hash<T: Hash, H: Hasher + Default>(value: &T) -> u64 { + let mut h: H = Default::default(); + value.hash(&mut h); + h.finish() +} + ////////////////////////////////////////////////////////////////////////////// -macro_rules! impl_hash { - ($ty:ident, $uty:ident) => { - impl<S: Writer + Hasher> Hash<S> for $ty { - #[inline] - fn hash(&self, state: &mut S) { - let a: [u8; ::$ty::BYTES] = unsafe { - mem::transmute((*self as $uty).to_le() as $ty) - }; - state.write(&a) +#[cfg(stage0)] +mod impls { + use prelude::*; + + use mem; + use num::Int; + use super::*; + + macro_rules! impl_hash { + ($ty:ident, $uty:ident) => { + impl<S: Writer + Hasher> Hash<S> for $ty { + #[inline] + fn hash(&self, state: &mut S) { + let a: [u8; ::$ty::BYTES] = unsafe { + mem::transmute(*self) + }; + state.write(&a) + } } } } -} -impl_hash! { u8, u8 } -impl_hash! { u16, u16 } -impl_hash! { u32, u32 } -impl_hash! { u64, u64 } -impl_hash! { uint, uint } -impl_hash! { i8, u8 } -impl_hash! { i16, u16 } -impl_hash! { i32, u32 } -impl_hash! { i64, u64 } -impl_hash! { int, uint } - -impl<S: Writer + Hasher> Hash<S> for bool { - #[inline] - fn hash(&self, state: &mut S) { - (*self as u8).hash(state); + impl_hash! { u8, u8 } + impl_hash! { u16, u16 } + impl_hash! { u32, u32 } + impl_hash! { u64, u64 } + impl_hash! { uint, uint } + impl_hash! { i8, u8 } + impl_hash! { i16, u16 } + impl_hash! { i32, u32 } + impl_hash! { i64, u64 } + impl_hash! { int, uint } + + impl<S: Writer + Hasher> Hash<S> for bool { + #[inline] + fn hash(&self, state: &mut S) { + (*self as u8).hash(state); + } } -} -impl<S: Writer + Hasher> Hash<S> for char { - #[inline] - fn hash(&self, state: &mut S) { - (*self as u32).hash(state); + impl<S: Writer + Hasher> Hash<S> for char { + #[inline] + fn hash(&self, state: &mut S) { + (*self as u32).hash(state); + } } -} -impl<S: Writer + Hasher> Hash<S> for str { - #[inline] - fn hash(&self, state: &mut S) { - state.write(self.as_bytes()); - 0xffu8.hash(state) + impl<S: Writer + Hasher> Hash<S> for str { + #[inline] + fn hash(&self, state: &mut S) { + state.write(self.as_bytes()); + 0xffu8.hash(state) + } } -} -macro_rules! impl_hash_tuple { - () => ( - impl<S: Hasher> Hash<S> for () { - #[inline] - fn hash(&self, _state: &mut S) {} - } - ); - - ( $($name:ident)+) => ( - impl<S: Hasher, $($name: Hash<S>),*> Hash<S> for ($($name,)*) { - #[inline] - #[allow(non_snake_case)] - fn hash(&self, state: &mut S) { - match *self { - ($(ref $name,)*) => { - $( - $name.hash(state); - )* + macro_rules! impl_hash_tuple { + () => ( + impl<S: Hasher> Hash<S> for () { + #[inline] + fn hash(&self, _state: &mut S) {} + } + ); + + ( $($name:ident)+) => ( + impl<S: Hasher, $($name: Hash<S>),*> Hash<S> for ($($name,)*) { + #[inline] + #[allow(non_snake_case)] + fn hash(&self, state: &mut S) { + match *self { + ($(ref $name,)*) => { + $( + $name.hash(state); + )* + } } } } + ); + } + + impl_hash_tuple! {} + impl_hash_tuple! { A } + impl_hash_tuple! { A B } + impl_hash_tuple! { A B C } + impl_hash_tuple! { A B C D } + impl_hash_tuple! { A B C D E } + impl_hash_tuple! { A B C D E F } + impl_hash_tuple! { A B C D E F G } + impl_hash_tuple! { A B C D E F G H } + impl_hash_tuple! { A B C D E F G H I } + impl_hash_tuple! { A B C D E F G H I J } + impl_hash_tuple! { A B C D E F G H I J K } + impl_hash_tuple! { A B C D E F G H I J K L } + + impl<S: Writer + Hasher, T: Hash<S>> Hash<S> for [T] { + #[inline] + fn hash(&self, state: &mut S) { + self.len().hash(state); + for elt in self { + elt.hash(state); + } } - ); -} + } -impl_hash_tuple! {} -impl_hash_tuple! { A } -impl_hash_tuple! { A B } -impl_hash_tuple! { A B C } -impl_hash_tuple! { A B C D } -impl_hash_tuple! { A B C D E } -impl_hash_tuple! { A B C D E F } -impl_hash_tuple! { A B C D E F G } -impl_hash_tuple! { A B C D E F G H } -impl_hash_tuple! { A B C D E F G H I } -impl_hash_tuple! { A B C D E F G H I J } -impl_hash_tuple! { A B C D E F G H I J K } -impl_hash_tuple! { A B C D E F G H I J K L } - -impl<S: Writer + Hasher, T: Hash<S>> Hash<S> for [T] { - #[inline] - fn hash(&self, state: &mut S) { - self.len().hash(state); - for elt in self { - elt.hash(state); + + impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a T { + #[inline] + fn hash(&self, state: &mut S) { + (**self).hash(state); } } -} + impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a mut T { + #[inline] + fn hash(&self, state: &mut S) { + (**self).hash(state); + } + } -impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a T { - #[inline] - fn hash(&self, state: &mut S) { - (**self).hash(state); + impl<S: Writer + Hasher, T> Hash<S> for *const T { + #[inline] + fn hash(&self, state: &mut S) { + // NB: raw-pointer Hash does _not_ dereference + // to the target; it just gives you the pointer-bytes. + (*self as uint).hash(state); + } } -} -impl<'a, S: Hasher, T: ?Sized + Hash<S>> Hash<S> for &'a mut T { - #[inline] - fn hash(&self, state: &mut S) { - (**self).hash(state); + impl<S: Writer + Hasher, T> Hash<S> for *mut T { + #[inline] + fn hash(&self, state: &mut S) { + // NB: raw-pointer Hash does _not_ dereference + // to the target; it just gives you the pointer-bytes. + (*self as uint).hash(state); + } } } -impl<S: Writer + Hasher, T> Hash<S> for *const T { - #[inline] - fn hash(&self, state: &mut S) { - // NB: raw-pointer Hash does _not_ dereference - // to the target; it just gives you the pointer-bytes. - (*self as uint).hash(state); +#[cfg(not(stage0))] +mod impls { + use prelude::*; + + use slice; + use super::*; + + macro_rules! impl_write { + ($(($ty:ident, $meth:ident),)*) => {$( + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for $ty { + fn hash<H: Hasher>(&self, state: &mut H) { + state.$meth(*self) + } + + fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) { + let newlen = data.len() * ::$ty::BYTES; + let ptr = data.as_ptr() as *const u8; + state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) + } + } + )*} } -} -impl<S: Writer + Hasher, T> Hash<S> for *mut T { - #[inline] - fn hash(&self, state: &mut S) { - // NB: raw-pointer Hash does _not_ dereference - // to the target; it just gives you the pointer-bytes. - (*self as uint).hash(state); + impl_write! { + (u8, write_u8), + (u16, write_u16), + (u32, write_u32), + (u64, write_u64), + (usize, write_usize), + (i8, write_i8), + (i16, write_i16), + (i32, write_i32), + (i64, write_i64), + (isize, write_isize), } -} -impl<'a, T, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, T, B> - where B: Hash<S> + ToOwned<T> -{ - #[inline] - fn hash(&self, state: &mut S) { - Hash::hash(&**self, state) + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for bool { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_u8(*self as u8) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for char { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_u32(*self as u32) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for str { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write(self.as_bytes()); + state.write_u8(0xff) + } + } + + macro_rules! impl_hash_tuple { + () => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl Hash for () { + fn hash<H: Hasher>(&self, _state: &mut H) {} + } + ); + + ( $($name:ident)+) => ( + #[stable(feature = "rust1", since = "1.0.0")] + impl<$($name: Hash),*> Hash for ($($name,)*) { + #[allow(non_snake_case)] + fn hash<S: Hasher>(&self, state: &mut S) { + let ($(ref $name,)*) = *self; + $($name.hash(state);)* + } + } + ); + } + + impl_hash_tuple! {} + impl_hash_tuple! { A } + impl_hash_tuple! { A B } + impl_hash_tuple! { A B C } + impl_hash_tuple! { A B C D } + impl_hash_tuple! { A B C D E } + impl_hash_tuple! { A B C D E F } + impl_hash_tuple! { A B C D E F G } + impl_hash_tuple! { A B C D E F G H } + impl_hash_tuple! { A B C D E F G H I } + impl_hash_tuple! { A B C D E F G H I J } + impl_hash_tuple! { A B C D E F G H I J K } + impl_hash_tuple! { A B C D E F G H I J K L } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T: Hash> Hash for [T] { + fn hash<H: Hasher>(&self, state: &mut H) { + self.len().hash(state); + Hash::hash_slice(self, state) + } + } + + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a T { + fn hash<H: Hasher>(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized + Hash> Hash for &'a mut T { + fn hash<H: Hasher>(&self, state: &mut H) { + (**self).hash(state); + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T> Hash for *const T { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_usize(*self as usize) + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl<T> Hash for *mut T { + fn hash<H: Hasher>(&self, state: &mut H) { + state.write_usize(*self as usize) + } } } diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index d405d0d28be..ce8917cc205 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -15,7 +15,9 @@ use prelude::*; use default::Default; -use super::{Hasher, Writer}; +use super::Hasher; +#[cfg(stage0)] +use super::Writer; /// An implementation of SipHash 2-4. /// @@ -30,6 +32,7 @@ use super::{Hasher, Writer}; /// strong, this implementation has not been reviewed for such purposes. /// As such, all cryptographic uses of this implementation are strongly /// discouraged. +#[stable(feature = "rust1", since = "1.0.0")] pub struct SipHasher { k0: u64, k1: u64, @@ -88,12 +91,14 @@ macro_rules! compress { impl SipHasher { /// Creates a new `SipHasher` with the two initial keys set to 0. #[inline] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> SipHasher { SipHasher::new_with_keys(0, 0) } /// Creates a `SipHasher` that is keyed off the provided keys. #[inline] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher { let mut state = SipHasher { k0: key0, @@ -114,10 +119,16 @@ impl SipHasher { #[unstable(feature = "hash")] #[deprecated(since = "1.0.0", reason = "renamed to finish")] pub fn result(&self) -> u64 { self.finish() } -} -impl Writer for SipHasher { - #[inline] + fn reset(&mut self) { + self.length = 0; + self.v0 = self.k0 ^ 0x736f6d6570736575; + self.v1 = self.k1 ^ 0x646f72616e646f6d; + self.v2 = self.k0 ^ 0x6c7967656e657261; + self.v3 = self.k1 ^ 0x7465646279746573; + self.ntail = 0; + } + fn write(&mut self, msg: &[u8]) { let length = msg.len(); self.length += length; @@ -164,16 +175,28 @@ impl Writer for SipHasher { } } +#[cfg(stage0)] +impl Writer for SipHasher { + #[inline] + fn write(&mut self, msg: &[u8]) { + self.write(msg) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] impl Hasher for SipHasher { + #[cfg(stage0)] type Output = u64; + #[cfg(stage0)] fn reset(&mut self) { - self.length = 0; - self.v0 = self.k0 ^ 0x736f6d6570736575; - self.v1 = self.k1 ^ 0x646f72616e646f6d; - self.v2 = self.k0 ^ 0x6c7967656e657261; - self.v3 = self.k1 ^ 0x7465646279746573; - self.ntail = 0; + self.reset(); + } + + #[inline] + #[cfg(not(stage0))] + fn write(&mut self, msg: &[u8]) { + self.write(msg) } fn finish(&self) -> u64 { @@ -199,6 +222,7 @@ impl Hasher for SipHasher { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Clone for SipHasher { #[inline] fn clone(&self) -> SipHasher { @@ -216,6 +240,7 @@ impl Clone for SipHasher { } } +#[stable(feature = "rust1", since = "1.0.0")] impl Default for SipHasher { fn default() -> SipHasher { SipHasher::new() diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 050c144b742..b2ee9596387 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -50,10 +50,10 @@ pub type GlueFn = extern "Rust" fn(*const i8); #[derive(Copy)] pub struct TyDesc { // sizeof(T) - pub size: uint, + pub size: usize, // alignof(T) - pub align: uint, + pub align: usize, // Called when a value of type `T` is no longer needed pub drop_glue: GlueFn, @@ -186,15 +186,15 @@ extern "rust-intrinsic" { /// would *exactly* overwrite a value. When laid out in vectors /// and structures there may be additional padding between /// elements. - pub fn size_of<T>() -> uint; + pub fn size_of<T>() -> usize; /// Move a value to an uninitialized memory location. /// /// Drop glue is not run on the destination. pub fn move_val_init<T>(dst: &mut T, src: T); - pub fn min_align_of<T>() -> uint; - pub fn pref_align_of<T>() -> uint; + pub fn min_align_of<T>() -> usize; + pub fn pref_align_of<T>() -> usize; /// Get a static pointer to a type descriptor. pub fn get_tydesc<T: ?Sized>() -> *const TyDesc; @@ -253,7 +253,7 @@ extern "rust-intrinsic" { /// /// This is implemented as an intrinsic to avoid converting to and from an /// integer, since the conversion would throw away aliasing information. - pub fn offset<T>(dst: *const T, offset: int) -> *const T; + pub fn offset<T>(dst: *const T, offset: isize) -> *const T; /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source /// and destination may *not* overlap. @@ -294,7 +294,7 @@ extern "rust-intrinsic" { /// } /// ``` #[unstable(feature = "core")] - pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint); + pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize); /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source /// and destination may overlap. @@ -324,13 +324,13 @@ extern "rust-intrinsic" { /// ``` /// #[unstable(feature = "core")] - pub fn copy_memory<T>(dst: *mut T, src: *const T, count: uint); + pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize); /// Invokes memset on the specified pointer, setting `count * size_of::<T>()` /// bytes of memory starting at `dst` to `c`. #[unstable(feature = "core", reason = "uncertain about naming and semantics")] - pub fn set_memory<T>(dst: *mut T, val: u8, count: uint); + pub fn set_memory<T>(dst: *mut T, val: u8, count: usize); /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::<T>()` and an alignment of @@ -338,19 +338,19 @@ extern "rust-intrinsic" { /// /// The volatile parameter parameter is set to `true`, so it will not be optimized out. pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, - count: uint); + count: usize); /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::<T>()` and an alignment of /// `min_align_of::<T>()` /// /// The volatile parameter parameter is set to `true`, so it will not be optimized out. - pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: uint); + pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize); /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a /// size of `count` * `size_of::<T>()` and an alignment of /// `min_align_of::<T>()`. /// /// The volatile parameter parameter is set to `true`, so it will not be optimized out. - pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: uint); + pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize); /// Perform a volatile load from the `src` pointer. pub fn volatile_load<T>(src: *const T) -> T; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index fffba1561a3..8fb10b5b2dc 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -62,6 +62,7 @@ use clone::Clone; use cmp; use cmp::Ord; use default::Default; +use marker; use mem; use num::{ToPrimitive, Int}; use ops::{Add, Deref, FnMut}; @@ -113,9 +114,9 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I { #[rustc_on_unimplemented="a collection of type `{Self}` cannot be \ built from an iterator over elements of type `{A}`"] pub trait FromIterator<A> { - /// Build a container with elements from an external iterator. + /// Build a container with elements from something iterable. #[stable(feature = "rust1", since = "1.0.0")] - fn from_iter<T: Iterator<Item=A>>(iterator: T) -> Self; + fn from_iter<T: IntoIterator<Item=A>>(iterator: T) -> Self; } /// Conversion into an `Iterator` @@ -147,7 +148,7 @@ impl<I: Iterator> IntoIterator for I { pub trait Extend<A> { /// Extend a container with the elements yielded by an arbitrary iterator #[stable(feature = "rust1", since = "1.0.0")] - fn extend<T: Iterator<Item=A>>(&mut self, iterator: T); + fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T); } /// An extension trait providing numerous methods applicable to all iterators. @@ -332,7 +333,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let xs = [100, 200, 300]; - /// let mut it = xs.iter().map(|x| *x).peekable(); + /// let mut it = xs.iter().cloned().peekable(); /// assert_eq!(*it.peek().unwrap(), 100); /// assert_eq!(it.next().unwrap(), 100); /// assert_eq!(it.next().unwrap(), 200); @@ -522,11 +523,11 @@ pub trait IteratorExt: Iterator + Sized { /// /// let a = [1, 4, 2, 3, 8, 9, 6]; /// let sum = a.iter() - /// .map(|&x| x) - /// .inspect(|&x| println!("filtering {}", x)) - /// .filter(|&x| x % 2 == 0) - /// .inspect(|&x| println!("{} made it through", x)) - /// .sum(); + /// .map(|x| *x) + /// .inspect(|&x| println!("filtering {}", x)) + /// .filter(|&x| x % 2 == 0) + /// .inspect(|&x| println!("{} made it through", x)) + /// .sum(); /// println!("{}", sum); /// ``` #[inline] @@ -561,7 +562,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let a = [1, 2, 3, 4, 5]; - /// let b: Vec<_> = a.iter().map(|&x| x).collect(); + /// let b: Vec<_> = a.iter().cloned().collect(); /// assert_eq!(a, b); /// ``` #[inline] @@ -937,7 +938,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let a = [(1, 2), (3, 4)]; - /// let (left, right): (Vec<_>, Vec<_>) = a.iter().map(|&x| x).unzip(); + /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip(); /// assert_eq!([1, 3], left); /// assert_eq!([2, 4], right); /// ``` @@ -947,7 +948,7 @@ pub trait IteratorExt: Iterator + Sized { FromB: Default + Extend<B>, Self: Iterator<Item=(A, B)>, { - struct SizeHint<A>(usize, Option<usize>); + struct SizeHint<A>(usize, Option<usize>, marker::PhantomData<A>); impl<A> Iterator for SizeHint<A> { type Item = A; @@ -961,8 +962,8 @@ pub trait IteratorExt: Iterator + Sized { let mut ts: FromA = Default::default(); let mut us: FromB = Default::default(); - ts.extend(SizeHint(lo, hi)); - us.extend(SizeHint(lo, hi)); + ts.extend(SizeHint(lo, hi, marker::PhantomData)); + us.extend(SizeHint(lo, hi, marker::PhantomData)); for (t, u) in self { ts.extend(Some(t).into_iter()); @@ -1142,7 +1143,7 @@ pub trait AdditiveIterator<A> { /// use std::iter::AdditiveIterator; /// /// let a = [1i32, 2, 3, 4, 5]; - /// let mut it = a.iter().map(|&x| x); + /// let mut it = a.iter().cloned(); /// assert!(it.sum() == 15); /// ``` fn sum(self) -> A; @@ -1305,6 +1306,23 @@ impl<T, D, I> ExactSizeIterator for Cloned<I> where I: ExactSizeIterator<Item=D>, {} +#[unstable(feature = "core", reason = "trait is experimental")] +impl<T, D, I> RandomAccessIterator for Cloned<I> where + T: Clone, + D: Deref<Target=T>, + I: RandomAccessIterator<Item=D> +{ + #[inline] + fn indexable(&self) -> usize { + self.it.indexable() + } + + #[inline] + fn idx(&mut self, index: usize) -> Option<T> { + self.it.idx(index).cloned() + } +} + /// An iterator that repeats endlessly #[derive(Clone)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] @@ -2047,8 +2065,8 @@ pub struct Scan<I, St, F> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<B, I: Iterator, St, F> Iterator for Scan<I, St, F> where - F: FnMut(&mut St, I::Item) -> Option<B>, +impl<A, B, I: Iterator<Item=A>, St, F> Iterator for Scan<I, St, F> where + F: FnMut(&mut St, A) -> Option<B>, { type Item = B; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index f0c60ffe4bf..3c58480ff0c 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -126,7 +126,6 @@ pub mod default; pub mod any; pub mod atomic; -pub mod borrow; pub mod cell; pub mod char; pub mod panicking; diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 56e1c5dedc1..d284eb34179 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -26,6 +26,10 @@ #![stable(feature = "rust1", since = "1.0.0")] use clone::Clone; +use cmp; +use option::Option; +use hash::Hash; +use hash::Hasher; /// Types able to be transferred across thread boundaries. #[unstable(feature = "core", @@ -37,12 +41,11 @@ pub unsafe trait Send: 'static { // empty. } /// Types able to be transferred across thread boundaries. -#[unstable(feature = "core", - reason = "will be overhauled with new lifetime rules; see RFC 458")] +#[stable(feature = "rust1", since = "1.0.0")] #[lang="send"] #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"] #[cfg(not(stage0))] -pub unsafe trait Send { +pub unsafe trait Send : MarkerTrait { // empty. } @@ -50,7 +53,7 @@ pub unsafe trait Send { #[stable(feature = "rust1", since = "1.0.0")] #[lang="sized"] #[rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time"] -pub trait Sized { +pub trait Sized : MarkerTrait { // Empty. } @@ -155,7 +158,7 @@ pub trait Sized { /// change: that second example would fail to compile if we made `Foo` non-`Copy`. #[stable(feature = "rust1", since = "1.0.0")] #[lang="copy"] -pub trait Copy { +pub trait Copy : MarkerTrait { // Empty. } @@ -204,236 +207,179 @@ pub trait Copy { /// around the value(s) which can be mutated when behind a `&` /// reference; not doing this is undefined behaviour (for example, /// `transmute`-ing from `&T` to `&mut T` is illegal). -#[unstable(feature = "core", - reason = "will be overhauled with new lifetime rules; see RFC 458")] +#[stable(feature = "rust1", since = "1.0.0")] #[lang="sync"] #[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] -pub unsafe trait Sync { +pub unsafe trait Sync : MarkerTrait { // Empty } -/// A marker type that indicates to the compiler that the instances -/// of the type itself owns instances of the type parameter `T`. -/// -/// This is used to indicate that one or more instances of the type -/// `T` could be dropped when instances of the type itself is dropped, -/// though that may not be apparent from the other structure of the -/// type itself. For example, the type may hold a `*mut T`, which the -/// compiler does not automatically treat as owned. +/// A type which is considered "not POD", meaning that it is not +/// implicitly copyable. This is typically embedded in other types to +/// ensure that they are never copied, even if they lack a destructor. #[unstable(feature = "core", - reason = "Newly added to deal with scoping and destructor changes")] -#[lang="phantom_data"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct PhantomData<T: ?Sized>; + reason = "likely to change with new variance strategy")] +#[lang="no_copy_bound"] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct NoCopy; -impl<T: ?Sized> Copy for PhantomData<T> {} -impl<T: ?Sized> Clone for PhantomData<T> { - fn clone(&self) -> PhantomData<T> { *self } +/// A type which is considered managed by the GC. This is typically +/// embedded in other types. +#[unstable(feature = "core", + reason = "likely to change with new variance strategy")] +#[lang="managed_bound"] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct Managed; + +macro_rules! impls{ + ($t: ident) => ( + #[cfg(stage0)] + impl<T:?Sized, S: Hasher> Hash<S> for $t<T> { + #[inline] + fn hash(&self, _: &mut S) { + } + } + #[cfg(not(stage0))] + impl<T:?Sized> Hash for $t<T> { + #[inline] + fn hash<H: Hasher>(&self, _: &mut H) { + } + } + + impl<T:?Sized> cmp::PartialEq for $t<T> { + fn eq(&self, _other: &$t<T>) -> bool { + true + } + } + + impl<T:?Sized> cmp::Eq for $t<T> { + } + + impl<T:?Sized> cmp::PartialOrd for $t<T> { + fn partial_cmp(&self, _other: &$t<T>) -> Option<cmp::Ordering> { + Option::Some(cmp::Ordering::Equal) + } + } + + impl<T:?Sized> cmp::Ord for $t<T> { + fn cmp(&self, _other: &$t<T>) -> cmp::Ordering { + cmp::Ordering::Equal + } + } + + impl<T:?Sized> Copy for $t<T> { } + + impl<T:?Sized> Clone for $t<T> { + fn clone(&self) -> $t<T> { + $t + } + } + ) } -/// A marker type whose type parameter `T` is considered to be -/// covariant with respect to the type itself. This is (typically) -/// used to indicate that an instance of the type `T` is being stored -/// into memory and read from, even though that may not be apparent. -/// -/// For more information about variance, refer to this Wikipedia -/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. -/// -/// *Note:* It is very unusual to have to add a covariant constraint. -/// If you are not sure, you probably want to use `InvariantType`. +/// `MarkerTrait` is intended to be used as the supertrait for traits +/// that don't have any methods but instead serve just to designate +/// categories of types. An example would be the `Send` trait, which +/// indicates types that are sendable: `Send` does not itself offer +/// any methods, but instead is used to gate access to data. +/// +/// FIXME. Better documentation needed here! +pub trait MarkerTrait : PhantomFn<Self> { } +impl<T:?Sized> MarkerTrait for T { } + +/// `PhantomFn` is a marker trait for use with traits that contain +/// type or lifetime parameters that do not appear in any of their +/// methods. In that case, you can either remove those parameters, or +/// add a `PhantomFn` supertrait that reflects the signature of +/// methods that compiler should "pretend" exists. This most commonly +/// occurs for traits with no methods: in that particular case, you +/// can extend `MarkerTrait`, which is equivalent to +/// `PhantomFn<Self>`. /// /// # Example /// -/// Given a struct `S` that includes a type parameter `T` -/// but does not actually *reference* that type parameter: +/// As an example, consider a trait with no methods like `Even`, meant +/// to represent types that are "even": /// -/// ```ignore -/// use std::mem; -/// -/// struct S<T> { x: *() } -/// fn get<T>(s: &S<T>) -> T { -/// unsafe { -/// let x: *T = mem::transmute(s.x); -/// *x -/// } -/// } +/// ```rust,ignore +/// trait Even { } /// ``` /// -/// The type system would currently infer that the value of -/// the type parameter `T` is irrelevant, and hence a `S<int>` is -/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for -/// any `U`). But this is incorrect because `get()` converts the -/// `*()` into a `*T` and reads from it. Therefore, we should include the -/// a marker field `CovariantType<T>` to inform the type checker that -/// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U` -/// (for example, `S<&'static int>` is a subtype of `S<&'a int>` -/// for some lifetime `'a`, but not the other way around). -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="covariant_type"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct CovariantType<T: ?Sized>; - -impl<T: ?Sized> Copy for CovariantType<T> {} -impl<T: ?Sized> Clone for CovariantType<T> { - fn clone(&self) -> CovariantType<T> { *self } -} - -/// A marker type whose type parameter `T` is considered to be -/// contravariant with respect to the type itself. This is (typically) -/// used to indicate that an instance of the type `T` will be consumed -/// (but not read from), even though that may not be apparent. +/// In this case, because the implicit parameter `Self` is unused, the +/// compiler will issue an error. The only purpose of this trait is to +/// categorize types (and hence instances of those types) as "even" or +/// not, so if we *were* going to have a method, it might look like: /// -/// For more information about variance, refer to this Wikipedia -/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. +/// ```rust,ignore +/// trait Even { +/// fn is_even(self) -> bool { true } +/// } +/// ``` /// -/// *Note:* It is very unusual to have to add a contravariant constraint. -/// If you are not sure, you probably want to use `InvariantType`. +/// Therefore, we can model a method like this as follows: /// -/// # Example +/// ```rust +/// use std::marker::PhantomFn; +/// trait Even : PhantomFn<Self> { } +/// ``` /// -/// Given a struct `S` that includes a type parameter `T` -/// but does not actually *reference* that type parameter: +/// Another equivalent, but clearer, option would be to use +/// `MarkerTrait`: /// +/// ```rust +/// use std::marker::MarkerTrait; +/// trait Even : MarkerTrait { } /// ``` -/// use std::mem; -/// -/// struct S<T> { x: *const () } -/// fn get<T>(s: &S<T>, v: T) { -/// unsafe { -/// let x: fn(T) = mem::transmute(s.x); -/// x(v) -/// } -/// } -/// ``` -/// -/// The type system would currently infer that the value of -/// the type parameter `T` is irrelevant, and hence a `S<int>` is -/// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for -/// any `U`). But this is incorrect because `get()` converts the -/// `*()` into a `fn(T)` and then passes a value of type `T` to it. -/// -/// Supplying a `ContravariantType` marker would correct the -/// problem, because it would mark `S` so that `S<T>` is only a -/// subtype of `S<U>` if `U` is a subtype of `T`; given that the -/// function requires arguments of type `T`, it must also accept -/// arguments of type `U`, hence such a conversion is safe. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="contravariant_type"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct ContravariantType<T: ?Sized>; - -impl<T: ?Sized> Copy for ContravariantType<T> {} -impl<T: ?Sized> Clone for ContravariantType<T> { - fn clone(&self) -> ContravariantType<T> { *self } -} - -/// A marker type whose type parameter `T` is considered to be -/// invariant with respect to the type itself. This is (typically) -/// used to indicate that instances of the type `T` may be read or -/// written, even though that may not be apparent. /// -/// For more information about variance, refer to this Wikipedia -/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. +/// # Parameters /// -/// # Example +/// - `A` represents the type of the method's argument. You can use a +/// tuple to represent "multiple" arguments. Any types appearing here +/// will be considered "contravariant". +/// - `R`, if supplied, represents the method's return type. This defaults +/// to `()` as it is rarely needed. /// -/// The Cell type is an example of an `InvariantType` which uses unsafe -/// code to achieve "interior" mutability: +/// # Additional reading /// -/// ``` -/// struct Cell<T> { value: T } -/// ``` +/// More details and background can be found in [RFC 738][738]. /// -/// The type system would infer that `value` is only read here -/// and never written, but in fact `Cell` uses unsafe code to achieve -/// interior mutability. In order to get correct behavior, the -/// `InvariantType` marker must be applied. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="invariant_type"] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -pub struct InvariantType<T: ?Sized>; - -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -impl<T: ?Sized> Copy for InvariantType<T> {} -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -impl<T: ?Sized> Clone for InvariantType<T> { - fn clone(&self) -> InvariantType<T> { *self } -} - -/// As `CovariantType`, but for lifetime parameters. Using -/// `CovariantLifetime<'a>` indicates that it is ok to substitute -/// a *longer* lifetime for `'a` than the one you originally -/// started with (e.g., you could convert any lifetime `'foo` to -/// `'static`). You almost certainly want `ContravariantLifetime` -/// instead, or possibly `InvariantLifetime`. The only case where -/// it would be appropriate is that you have a (type-casted, and -/// hence hidden from the type system) function pointer with a -/// signature like `fn(&'a T)` (and no other uses of `'a`). In -/// this case, it is ok to substitute a larger lifetime for `'a` -/// (e.g., `fn(&'static T)`), because the function is only -/// becoming more selective in terms of what it accepts as -/// argument. -/// -/// For more information about variance, refer to this Wikipedia -/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="covariant_lifetime"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct CovariantLifetime<'a>; +/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md +#[lang="phantom_fn"] +#[stable(feature = "rust1", since = "1.0.0")] +pub trait PhantomFn<A:?Sized,R:?Sized=()> { } -/// As `ContravariantType`, but for lifetime parameters. Using -/// `ContravariantLifetime<'a>` indicates that it is ok to -/// substitute a *shorter* lifetime for `'a` than the one you -/// originally started with (e.g., you could convert `'static` to -/// any lifetime `'foo`). This is appropriate for cases where you -/// have an unsafe pointer that is actually a pointer into some -/// memory with lifetime `'a`, and thus you want to limit the -/// lifetime of your data structure to `'a`. An example of where -/// this is used is the iterator for vectors. -/// -/// For more information about variance, refer to this Wikipedia -/// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="contravariant_lifetime"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct ContravariantLifetime<'a>; +#[cfg(stage0)] // built into the trait matching system after stage0 +impl<A:?Sized, R:?Sized, U:?Sized> PhantomFn<A,R> for U { } -/// As `InvariantType`, but for lifetime parameters. Using -/// `InvariantLifetime<'a>` indicates that it is not ok to -/// substitute any other lifetime for `'a` besides its original -/// value. This is appropriate for cases where you have an unsafe -/// pointer that is actually a pointer into memory with lifetime `'a`, -/// and this pointer is itself stored in an inherently mutable -/// location (such as a `Cell`). -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="invariant_lifetime"] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct InvariantLifetime<'a>; +/// Specific to stage0. You should not be seeing these docs! +#[cfg(stage0)] +#[lang="covariant_type"] // only relevant to stage0 +pub struct PhantomData<T:?Sized>; -/// A type which is considered "not POD", meaning that it is not -/// implicitly copyable. This is typically embedded in other types to -/// ensure that they are never copied, even if they lack a destructor. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="no_copy_bound"] -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct NoCopy; +/// `PhantomData` is a way to tell the compiler about fake fields. +/// Phantom data is required whenever type parameters are not used. +/// The idea is that if the compiler encounters a `PhantomData<T>` +/// instance, it will behave *as if* an instance of the type `T` were +/// present for the purpose of various automatic analyses. +/// +/// For example, embedding a `PhantomData<T>` will inform the compiler +/// that one or more instances of the type `T` could be dropped when +/// instances of the type itself is dropped, though that may not be +/// apparent from the other structure of the type itself. This is +/// commonly necessary if the structure is using an unsafe pointer +/// like `*mut T` whose referent may be dropped when the type is +/// dropped, as a `*mut T` is otherwise not treated as owned. +/// +/// FIXME. Better documentation and examples of common patterns needed +/// here! For now, please see [RFC 738][738] for more information. +/// +/// [738]: https://github.com/rust-lang/rfcs/blob/master/text/0738-variance.md +#[cfg(not(stage0))] +#[lang="phantom_data"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct PhantomData<T:?Sized>; -/// A type which is considered managed by the GC. This is typically -/// embedded in other types. -#[unstable(feature = "core", - reason = "likely to change with new variance strategy")] -#[lang="managed_bound"] -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Managed; +impls! { PhantomData } #[cfg(not(stage0))] mod impls { @@ -442,3 +388,40 @@ mod impls { unsafe impl<'a, T: Sync + ?Sized> Send for &'a T {} unsafe impl<'a, T: Send + ?Sized> Send for &'a mut T {} } + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<&'a ()>`")] +#[lang="contravariant_lifetime"] +pub struct ContravariantLifetime<'a>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(&'a ())>`")] +#[lang="covariant_lifetime"] +pub struct CovariantLifetime<'a>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<&'a ()>>`")] +#[lang="invariant_lifetime"] +pub struct InvariantLifetime<'a>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<fn(T)>`")] +#[lang="contravariant_type"] +pub struct ContravariantType<T>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<T>`")] +#[lang="covariant_type"] +#[cfg(not(stage0))] +pub struct CovariantType<T>; + +/// Old-style marker trait. Deprecated. +#[unstable(feature = "core", reason = "deprecated")] +#[deprecated(since = "1.0.0", reason = "Replace with `PhantomData<Cell<T>>`")] +#[lang="invariant_type"] +pub struct InvariantType<T>; diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 5644f763069..230587b726f 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -10,15 +10,14 @@ //! Exposes the NonZero lang item which provides optimization hints. +use marker::{Sized, MarkerTrait}; use ops::Deref; -use ptr::Unique; /// Unsafe trait to indicate what types are usable with the NonZero struct -pub unsafe trait Zeroable {} +pub unsafe trait Zeroable : MarkerTrait {} -unsafe impl<T> Zeroable for *const T {} -unsafe impl<T> Zeroable for *mut T {} -unsafe impl<T> Zeroable for Unique<T> { } +unsafe impl<T:?Sized> Zeroable for *const T {} +unsafe impl<T:?Sized> Zeroable for *mut T {} unsafe impl Zeroable for isize {} unsafe impl Zeroable for usize {} unsafe impl Zeroable for i8 {} diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 9a89682127f..abfef72a5db 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -149,7 +149,7 @@ use clone::Clone; use cmp::{Eq, Ord}; use default::Default; use iter::{ExactSizeIterator}; -use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator}; +use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, IntoIterator}; use mem; use ops::{Deref, FnOnce}; use result::Result::{Ok, Err}; @@ -909,7 +909,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn from_iter<I: Iterator<Item=Option<A>>>(iter: I) -> Option<V> { + fn from_iter<I: IntoIterator<Item=Option<A>>>(iter: I) -> Option<V> { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. @@ -934,7 +934,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> { } } - let mut adapter = Adapter { iter: iter, found_none: false }; + let mut adapter = Adapter { iter: iter.into_iter(), found_none: false }; let v: V = FromIterator::from_iter(adapter.by_ref()); if adapter.found_none { diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 072c60c7036..16b84dcf18e 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -91,8 +91,10 @@ use mem; use clone::Clone; use intrinsics; +use ops::Deref; use option::Option::{self, Some, None}; -use marker::{self, Send, Sized, Sync}; +use marker::{PhantomData, Send, Sized, Sync}; +use nonzero::NonZero; use cmp::{PartialEq, Eq, Ord, PartialOrd}; use cmp::Ordering::{self, Less, Equal, Greater}; @@ -303,7 +305,7 @@ impl<T> PtrExt for *const T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn is_null(self) -> bool { self as usize == 0 } + fn is_null(self) -> bool { self == 0 as *const T } #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -330,7 +332,7 @@ impl<T> PtrExt for *mut T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn is_null(self) -> bool { self as usize == 0 } + fn is_null(self) -> bool { self == 0 as *mut T } #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -517,15 +519,16 @@ impl<T> PartialOrd for *mut T { /// A wrapper around a raw `*mut T` that indicates that the possessor /// of this wrapper owns the referent. This in turn implies that the -/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a -/// raw `*mut T` (which conveys no particular ownership semantics). -/// Useful for building abstractions like `Vec<T>` or `Box<T>`, which +/// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw +/// `*mut T` (which conveys no particular ownership semantics). It +/// also implies that the referent of the pointer should not be +/// modified without a unique path to the `Unique` reference. Useful +/// for building abstractions like `Vec<T>` or `Box<T>`, which /// internally use raw pointers to manage the memory that they own. #[unstable(feature = "core", reason = "recently added to this module")] -pub struct Unique<T: ?Sized> { - /// The wrapped `*mut T`. - pub ptr: *mut T, - _own: marker::PhantomData<T>, +pub struct Unique<T:?Sized> { + pointer: NonZero<*const T>, + _marker: PhantomData<T>, } /// `Unique` pointers are `Send` if `T` is `Send` because the data they @@ -542,25 +545,34 @@ unsafe impl<T: Send + ?Sized> Send for Unique<T> { } #[unstable(feature = "core", reason = "recently added to this module")] unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { } -impl<T> Unique<T> { - /// Returns a null Unique. +impl<T:?Sized> Unique<T> { + /// Create a new `Unique`. #[unstable(feature = "core", reason = "recently added to this module")] - pub fn null() -> Unique<T> { - Unique(null_mut()) + pub unsafe fn new(ptr: *mut T) -> Unique<T> { + Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData } } - /// Return an (unsafe) pointer into the memory owned by `self`. + /// Dereference the content. #[unstable(feature = "core", reason = "recently added to this module")] - pub unsafe fn offset(self, offset: isize) -> *mut T { - self.ptr.offset(offset) + pub unsafe fn get(&self) -> &T { + &**self.pointer + } + + /// Mutably dereference the content. + #[unstable(feature = "core", + reason = "recently added to this module")] + pub unsafe fn get_mut(&mut self) -> &mut T { + &mut ***self } } -/// Creates a `Unique` wrapped around `ptr`, taking ownership of the -/// data referenced by `ptr`. -#[allow(non_snake_case)] -pub fn Unique<T: ?Sized>(ptr: *mut T) -> Unique<T> { - Unique { ptr: ptr, _own: marker::PhantomData } +impl<T:?Sized> Deref for Unique<T> { + type Target = *mut T; + + #[inline] + fn deref<'a>(&'a self) -> &'a *mut T { + unsafe { mem::transmute(&*self.pointer) } + } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 1a874ee178b..23e936a75d7 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -230,7 +230,8 @@ use self::Result::{Ok, Err}; use clone::Clone; use fmt; -use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator}; +use iter::{Iterator, IteratorExt, DoubleEndedIterator, + FromIterator, ExactSizeIterator, IntoIterator}; use ops::{FnMut, FnOnce}; use option::Option::{self, None, Some}; use slice::AsSlice; @@ -906,7 +907,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> { /// assert!(res == Ok(vec!(2, 3))); /// ``` #[inline] - fn from_iter<I: Iterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> { + fn from_iter<I: IntoIterator<Item=Result<A, E>>>(iter: I) -> Result<V, E> { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. @@ -931,7 +932,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> { } } - let mut adapter = Adapter { iter: iter, err: None }; + let mut adapter = Adapter { iter: iter.into_iter(), err: None }; let v: V = FromIterator::from_iter(adapter.by_ref()); match adapter.err { diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index bbfe7e58ef4..a86da53b372 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -140,11 +140,11 @@ impl<T> SliceExt for [T] { if mem::size_of::<T>() == 0 { Iter {ptr: p, end: (p as usize + self.len()) as *const T, - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } else { Iter {ptr: p, end: p.offset(self.len() as isize), - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } } } @@ -279,11 +279,11 @@ impl<T> SliceExt for [T] { if mem::size_of::<T>() == 0 { IterMut {ptr: p, end: (p as usize + self.len()) as *mut T, - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } else { IterMut {ptr: p, end: p.offset(self.len() as isize), - marker: marker::ContravariantLifetime::<'a>} + _marker: marker::PhantomData} } } } @@ -733,7 +733,7 @@ macro_rules! make_slice { pub struct Iter<'a, T: 'a> { ptr: *const T, end: *const T, - marker: marker::ContravariantLifetime<'a> + _marker: marker::PhantomData<&'a T>, } #[unstable(feature = "core")] @@ -790,7 +790,7 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> {} #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for Iter<'a, T> { - fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, marker: self.marker } } + fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } } } #[unstable(feature = "core", reason = "trait is experimental")] @@ -823,7 +823,7 @@ impl<'a, T> RandomAccessIterator for Iter<'a, T> { pub struct IterMut<'a, T: 'a> { ptr: *mut T, end: *mut T, - marker: marker::ContravariantLifetime<'a>, + _marker: marker::PhantomData<&'a mut T>, } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ce26abe606d..eec997b9f10 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1280,7 +1280,7 @@ mod traits { /// Any string that can be represented as a slice #[unstable(feature = "core", reason = "Instead of taking this bound generically, this trait will be \ - replaced with one of slicing syntax (&foo[]), deref coercions, or \ + replaced with one of slicing syntax (&foo[..]), deref coercions, or \ a more generic conversion trait")] pub trait Str { /// Work with `self` as a slice. |
