diff options
| author | bors <bors@rust-lang.org> | 2015-01-07 05:31:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-01-07 05:31:23 +0000 |
| commit | 9e4e524e0eb17c8f463e731f23b544003e8709c6 (patch) | |
| tree | 916024d35e08f0826c20654f629ec596b5cb1f14 /src/libcore | |
| parent | ea6f65c5f1a3f84e010d2cef02a0160804e9567a (diff) | |
| parent | a64000820f0fc32be4d7535a9a92418a434fa4ba (diff) | |
| download | rust-9e4e524e0eb17c8f463e731f23b544003e8709c6.tar.gz rust-9e4e524e0eb17c8f463e731f23b544003e8709c6.zip | |
auto merge of #20677 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/any.rs | 2 | ||||
| -rw-r--r-- | src/libcore/array.rs | 38 | ||||
| -rw-r--r-- | src/libcore/atomic.rs | 4 | ||||
| -rw-r--r-- | src/libcore/borrow.rs | 22 | ||||
| -rw-r--r-- | src/libcore/cell.rs | 15 | ||||
| -rw-r--r-- | src/libcore/clone.rs | 2 | ||||
| -rw-r--r-- | src/libcore/cmp.rs | 4 | ||||
| -rw-r--r-- | src/libcore/fmt/float.rs | 4 | ||||
| -rw-r--r-- | src/libcore/fmt/mod.rs | 188 | ||||
| -rw-r--r-- | src/libcore/fmt/num.rs | 53 | ||||
| -rw-r--r-- | src/libcore/intrinsics.rs | 1 | ||||
| -rw-r--r-- | src/libcore/iter.rs | 155 | ||||
| -rw-r--r-- | src/libcore/kinds.rs | 298 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 24 | ||||
| -rw-r--r-- | src/libcore/macros.rs | 18 | ||||
| -rw-r--r-- | src/libcore/marker.rs | 314 | ||||
| -rw-r--r-- | src/libcore/mem.rs | 2 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 8 | ||||
| -rw-r--r-- | src/libcore/ops.rs | 109 | ||||
| -rw-r--r-- | src/libcore/option.rs | 2 | ||||
| -rw-r--r-- | src/libcore/prelude.rs | 4 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 2 | ||||
| -rw-r--r-- | src/libcore/raw.rs | 2 | ||||
| -rw-r--r-- | src/libcore/result.rs | 8 | ||||
| -rw-r--r-- | src/libcore/simd.rs | 2 | ||||
| -rw-r--r-- | src/libcore/slice.rs | 258 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 68 | ||||
| -rw-r--r-- | src/libcore/ty.rs | 2 |
28 files changed, 885 insertions, 724 deletions
diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 33cb335d756..25007bfde93 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -49,7 +49,7 @@ //! println!("String ({}): {}", as_string.len(), as_string); //! } //! None => { -//! println!("{}", value); +//! println!("{:?}", value); //! } //! } //! } diff --git a/src/libcore/array.rs b/src/libcore/array.rs index ba7714ad9bc..05db9e11760 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -17,8 +17,8 @@ use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; use fmt; -use kinds::Copy; -use ops::Deref; +use marker::Copy; +use ops::{Deref, FullRange, Index}; use option::Option; // macro for implementing n-ary tuple functions and operations @@ -35,7 +35,7 @@ macro_rules! array_impls { #[unstable = "waiting for Show to stabilize"] impl<T:fmt::Show> fmt::Show for [T; $N] { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Show::fmt(&self[], f) + fmt::Show::fmt(&self.index(&FullRange), f) } } @@ -43,11 +43,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.index(&FullRange) == other.index(&FullRange) } #[inline] fn ne(&self, other: &[B; $N]) -> bool { - self[] != other[] + self.index(&FullRange) != other.index(&FullRange) } } @@ -57,9 +57,13 @@ macro_rules! array_impls { Rhs: Deref<Target=[B]>, { #[inline(always)] - fn eq(&self, other: &Rhs) -> bool { PartialEq::eq(self[], &**other) } + fn eq(&self, other: &Rhs) -> bool { + PartialEq::eq(self.index(&FullRange), &**other) + } #[inline(always)] - fn ne(&self, other: &Rhs) -> bool { PartialEq::ne(self[], &**other) } + fn ne(&self, other: &Rhs) -> bool { + PartialEq::ne(self.index(&FullRange), &**other) + } } #[stable] @@ -68,9 +72,13 @@ macro_rules! array_impls { Lhs: Deref<Target=[A]> { #[inline(always)] - fn eq(&self, other: &[B; $N]) -> bool { PartialEq::eq(&**self, other[]) } + fn eq(&self, other: &[B; $N]) -> bool { + PartialEq::eq(&**self, other.index(&FullRange)) + } #[inline(always)] - fn ne(&self, other: &[B; $N]) -> bool { PartialEq::ne(&**self, other[]) } + fn ne(&self, other: &[B; $N]) -> bool { + PartialEq::ne(&**self, other.index(&FullRange)) + } } #[stable] @@ -80,23 +88,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.index(&FullRange), &other.index(&FullRange)) } #[inline] fn lt(&self, other: &[T; $N]) -> bool { - PartialOrd::lt(&self[], &other[]) + PartialOrd::lt(&self.index(&FullRange), &other.index(&FullRange)) } #[inline] fn le(&self, other: &[T; $N]) -> bool { - PartialOrd::le(&self[], &other[]) + PartialOrd::le(&self.index(&FullRange), &other.index(&FullRange)) } #[inline] fn ge(&self, other: &[T; $N]) -> bool { - PartialOrd::ge(&self[], &other[]) + PartialOrd::ge(&self.index(&FullRange), &other.index(&FullRange)) } #[inline] fn gt(&self, other: &[T; $N]) -> bool { - PartialOrd::gt(&self[], &other[]) + PartialOrd::gt(&self.index(&FullRange), &other.index(&FullRange)) } } @@ -104,7 +112,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.index(&FullRange), &other.index(&FullRange)) } } )+ diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index 15c20253c8b..e740a929252 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -50,7 +50,7 @@ //! let spinlock_clone = spinlock.clone(); //! Thread::spawn(move|| { //! spinlock_clone.store(0, Ordering::SeqCst); -//! }).detach(); +//! }); //! //! // Wait for the other task to release the lock //! while spinlock.load(Ordering::SeqCst) != 0 {} @@ -72,7 +72,7 @@ use self::Ordering::*; -use kinds::Sync; +use marker::Sync; use intrinsics; use cell::UnsafeCell; diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 2c08b976355..31631355422 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -47,7 +47,7 @@ use clone::Clone; use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; use fmt; -use kinds::Sized; +use marker::Sized; use ops::Deref; use option::Option; use self::Cow::*; @@ -133,6 +133,7 @@ impl<T> ToOwned<T> for T where T: Clone { /// } /// } /// ``` +//#[deriving(Show)] NOTE(stage0): uncomment after snapshot pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned<T> { /// Borrowed data. Borrowed(&'a B), @@ -141,6 +142,16 @@ pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned<T> { Owned(T) } +//NOTE(stage0): replace with deriving(Show) after snapshot +impl<'a, T, B: ?Sized> fmt::Show for Cow<'a, T, B> where + B: fmt::String + ToOwned<T>, + T: fmt::String +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::String::fmt(self, f) + } +} + #[stable] impl<'a, T, B: ?Sized> Clone for Cow<'a, T, B> where B: ToOwned<T> { fn clone(&self) -> Cow<'a, T, B> { @@ -237,11 +248,14 @@ impl<'a, T, B: ?Sized> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwne } } -impl<'a, T, B: ?Sized> fmt::Show for Cow<'a, T, B> where B: fmt::Show + ToOwned<T>, T: fmt::Show { +impl<'a, T, B: ?Sized> fmt::String for Cow<'a, T, B> where + B: fmt::String + ToOwned<T>, + T: fmt::String, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Borrowed(ref b) => fmt::Show::fmt(b, f), - Owned(ref o) => fmt::Show::fmt(o, f), + Borrowed(ref b) => fmt::String::fmt(b, f), + Owned(ref o) => fmt::String::fmt(o, f), } } } diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index fd18d6ac3f3..674364269f1 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -160,8 +160,7 @@ use clone::Clone; use cmp::PartialEq; use default::Default; -use fmt; -use kinds::{Copy, Send}; +use marker::{Copy, Send}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{None, Some}; @@ -364,16 +363,6 @@ impl<T: PartialEq> PartialEq for RefCell<T> { } } -#[unstable] -impl<T:fmt::Show> fmt::Show for RefCell<T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.try_borrow() { - Some(val) => write!(f, "{}", val), - None => write!(f, "<borrowed RefCell>") - } - } -} - struct BorrowRef<'b> { _borrow: &'b Cell<BorrowFlag>, } @@ -520,7 +509,7 @@ impl<'b, T> DerefMut for RefMut<'b, T> { /// /// ```rust /// use std::cell::UnsafeCell; -/// use std::kinds::marker; +/// use std::marker; /// /// struct NotThreadSafe<T> { /// value: UnsafeCell<T>, diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 17991659f97..3149247a83a 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -21,7 +21,7 @@ #![stable] -use kinds::Sized; +use marker::Sized; /// A common trait for cloning an object. #[stable] diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index af5e98ed303..c3dfd5f5159 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -43,7 +43,7 @@ use self::Ordering::*; -use kinds::Sized; +use marker::Sized; use option::Option::{self, Some, None}; /// Trait for equality comparisons which are [partial equivalence relations]( @@ -316,7 +316,7 @@ pub fn partial_max<T: PartialOrd>(v1: T, v2: T) -> Option<T> { mod impls { use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering}; use cmp::Ordering::{Less, Greater, Equal}; - use kinds::Sized; + use marker::Sized; use option::Option; use option::Option::{Some, None}; diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index f63242b4f85..d833b8fed77 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -20,7 +20,7 @@ use fmt; use iter::{IteratorExt, range}; use num::{cast, Float, ToPrimitive}; use num::FpCategory as Fp; -use ops::FnOnce; +use ops::{FnOnce, Index}; use result::Result::Ok; use slice::{self, SliceExt}; use str::{self, StrExt}; @@ -332,5 +332,5 @@ pub fn float_to_str_bytes_common<T: Float, U, F>( } } - f(unsafe { str::from_utf8_unchecked(buf[..end]) }) + f(unsafe { str::from_utf8_unchecked(buf.index(&(0..end))) }) } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 951f5c29f00..f9027f19068 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -13,22 +13,20 @@ #![allow(unused_variables)] use any; -use cell::{Cell, Ref, RefMut}; +use cell::{Cell, RefCell, Ref, RefMut}; +use char::CharExt; use iter::{Iterator, IteratorExt, range}; -use kinds::{Copy, Sized}; +use marker::{Copy, Sized}; use mem; use option::Option; use option::Option::{Some, None}; -use ops::{Deref, FnOnce}; use result::Result::Ok; +use ops::{Deref, FnOnce, Index}; use result; use slice::SliceExt; use slice; use str::{self, StrExt, Utf8Error}; -// NOTE: for old macros; remove after the next snapshot -#[cfg(stage0)] use result::Result::Err; - pub use self::num::radix; pub use self::num::Radix; pub use self::num::RadixFmt; @@ -217,19 +215,32 @@ pub struct Arguments<'a> { impl<'a> Show for Arguments<'a> { fn fmt(&self, fmt: &mut Formatter) -> Result { + String::fmt(self, fmt) + } +} + +impl<'a> String for Arguments<'a> { + fn fmt(&self, fmt: &mut Formatter) -> Result { write(fmt.buf, *self) } } -/// When a format is not otherwise specified, types are formatted by ascribing -/// to this trait. There is not an explicit way of selecting this trait to be -/// used for formatting, it is only if no other format is specified. +/// Format trait for the `:?` format. Useful for debugging, most all types +/// should implement this. #[unstable = "I/O and core have yet to be reconciled"] pub trait Show { /// Formats the value using the given formatter. fn fmt(&self, &mut Formatter) -> Result; } +/// When a value can be semantically expressed as a String, this trait may be +/// used. It corresponds to the default format, `{}`. +#[unstable = "I/O and core have yet to be reconciled"] +pub trait String { + /// Formats the value using the given formatter. + fn fmt(&self, &mut Formatter) -> Result; +} + /// Format trait for the `o` character #[unstable = "I/O and core have yet to be reconciled"] @@ -413,7 +424,7 @@ impl<'a> Formatter<'a> { for c in sign.into_iter() { let mut b = [0; 4]; let n = c.encode_utf8(&mut b).unwrap_or(0); - let b = unsafe { str::from_utf8_unchecked(b[0..n]) }; + let b = unsafe { str::from_utf8_unchecked(b.index(&(0..n))) }; try!(f.buf.write_str(b)); } if prefixed { f.buf.write_str(prefix) } @@ -521,7 +532,7 @@ impl<'a> Formatter<'a> { let mut fill = [0u8; 4]; let len = self.fill.encode_utf8(&mut fill).unwrap_or(0); - let fill = unsafe { str::from_utf8_unchecked(fill[..len]) }; + let fill = unsafe { str::from_utf8_unchecked(fill.index(&(..len))) }; for _ in range(0, pre_pad) { try!(self.buf.write_str(fill)); @@ -572,7 +583,7 @@ impl<'a> Formatter<'a> { impl Show for Error { fn fmt(&self, f: &mut Formatter) -> Result { - "an error occurred when formatting an argument".fmt(f) + String::fmt("an error occurred when formatting an argument", f) } } @@ -595,33 +606,86 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> { // Implementations of the core formatting traits -impl<'a, T: ?Sized + Show> Show for &'a T { - fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) } -} -impl<'a, T: ?Sized + Show> Show for &'a mut T { - fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) } +macro_rules! fmt_refs { + ($($tr:ident),*) => { + $( + impl<'a, T: ?Sized + $tr> $tr for &'a T { + fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } + } + impl<'a, T: ?Sized + $tr> $tr for &'a mut T { + fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) } + } + )* + } } +fmt_refs! { Show, String, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } + impl Show for bool { fn fmt(&self, f: &mut Formatter) -> Result { - Show::fmt(if *self { "true" } else { "false" }, f) + String::fmt(self, f) + } +} + +impl String for bool { + fn fmt(&self, f: &mut Formatter) -> Result { + String::fmt(if *self { "true" } else { "false" }, f) + } +} + +#[cfg(stage0)] +//NOTE(stage0): remove impl after snapshot +impl Show for str { + fn fmt(&self, f: &mut Formatter) -> Result { + String::fmt(self, f) } } +#[cfg(not(stage0))] +//NOTE(stage0): remove cfg after snapshot impl Show for str { fn fmt(&self, f: &mut Formatter) -> Result { + try!(write!(f, "\"")); + for c in self.chars().flat_map(|c| c.escape_default()) { + try!(write!(f, "{}", c)); + } + write!(f, "\"") + } +} + +impl String for str { + fn fmt(&self, f: &mut Formatter) -> Result { f.pad(self) } } +#[cfg(stage0)] +//NOTE(stage0): remove impl after snapshot +impl Show for char { + fn fmt(&self, f: &mut Formatter) -> Result { + String::fmt(self, f) + } +} + +#[cfg(not(stage0))] +//NOTE(stage0): remove cfg after snapshot impl Show for char { fn fmt(&self, f: &mut Formatter) -> Result { use char::CharExt; + try!(write!(f, "'")); + for c in self.escape_default() { + try!(write!(f, "{}", c)); + } + write!(f, "'") + } +} +impl String for char { + fn fmt(&self, f: &mut Formatter) -> Result { let mut utf8 = [0u8; 4]; let amt = self.encode_utf8(&mut utf8).unwrap_or(0); - let s: &str = unsafe { mem::transmute(utf8[..amt]) }; - Show::fmt(s, f) + let s: &str = unsafe { mem::transmute(utf8.index(&(0..amt))) }; + String::fmt(s, f) } } @@ -653,8 +717,16 @@ impl<'a, T> Pointer for &'a mut T { } macro_rules! floating { ($ty:ident) => { + impl Show for $ty { fn fmt(&self, fmt: &mut Formatter) -> Result { + try!(String::fmt(self, fmt)); + fmt.write_str(stringify!($ty)) + } + } + + impl String for $ty { + fn fmt(&self, fmt: &mut Formatter) -> Result { use num::Float; let digits = match fmt.precision { @@ -724,10 +796,15 @@ floating! { f64 } impl<T> Show for *const T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } - +impl<T> String for *const T { + fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } +} impl<T> Show for *mut T { fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } } +impl<T> String for *mut T { + fn fmt(&self, f: &mut Formatter) -> Result { Pointer::fmt(self, f) } +} macro_rules! peel { ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* }) @@ -746,7 +823,7 @@ macro_rules! tuple { if n > 0 { try!(write!(f, ", ")); } - try!(write!(f, "{}", *$name)); + try!(write!(f, "{:?}", *$name)); n += 1; )* if n == 1 { @@ -777,6 +854,49 @@ impl<T: Show> Show for [T] { } else { try!(write!(f, ", ")); } + try!(write!(f, "{:?}", *x)) + } + if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { + try!(write!(f, "]")); + } + Ok(()) + } +} + +#[cfg(stage0)] +impl<T: Show> String for [T] { + fn fmt(&self, f: &mut Formatter) -> Result { + if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { + try!(write!(f, "[")); + } + let mut is_first = true; + for x in self.iter() { + if is_first { + is_first = false; + } else { + try!(write!(f, ", ")); + } + try!(write!(f, "{}", *x)) + } + if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { + try!(write!(f, "]")); + } + Ok(()) + } +} +#[cfg(not(stage0))] +impl<T: String> String for [T] { + fn fmt(&self, f: &mut Formatter) -> Result { + if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { + try!(write!(f, "[")); + } + let mut is_first = true; + for x in self.iter() { + if is_first { + is_first = false; + } else { + try!(write!(f, ", ")); + } try!(write!(f, "{}", *x)) } if f.flags & (1 << (rt::FlagAlternate as uint)) == 0 { @@ -792,25 +912,41 @@ impl Show for () { } } +impl String for () { + fn fmt(&self, f: &mut Formatter) -> Result { + f.pad("()") + } +} + impl<T: Copy + Show> Show for Cell<T> { fn fmt(&self, f: &mut Formatter) -> Result { - write!(f, "Cell {{ value: {} }}", self.get()) + write!(f, "Cell {{ value: {:?} }}", self.get()) + } +} + +#[unstable] +impl<T: Show> Show for RefCell<T> { + fn fmt(&self, f: &mut Formatter) -> Result { + match self.try_borrow() { + Some(val) => write!(f, "RefCell {{ value: {:?} }}", val), + None => write!(f, "RefCell {{ <borrowed> }}") + } } } impl<'b, T: Show> Show for Ref<'b, T> { fn fmt(&self, f: &mut Formatter) -> Result { - (**self).fmt(f) + Show::fmt(&**self, f) } } impl<'b, T: Show> Show for RefMut<'b, T> { fn fmt(&self, f: &mut Formatter) -> Result { - (*(self.deref())).fmt(f) + Show::fmt(&*(self.deref()), f) } } -impl Show for Utf8Error { +impl String for Utf8Error { fn fmt(&self, f: &mut Formatter) -> Result { match *self { Utf8Error::InvalidByte(n) => { diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index e0724fc2da5..17149aed3db 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -16,6 +16,7 @@ use fmt; use iter::IteratorExt; +use ops::Index; use num::{Int, cast}; use slice::SliceExt; use str; @@ -61,7 +62,7 @@ trait GenericRadix { if x == zero { break }; // No more digits left to accumulate. } } - let buf = unsafe { str::from_utf8_unchecked(buf[curr..]) }; + let buf = unsafe { str::from_utf8_unchecked(buf.index(&(curr..))) }; f.pad_integral(is_positive, self.prefix(), buf) } } @@ -153,9 +154,23 @@ pub fn radix<T>(x: T, base: u8) -> RadixFmt<T, Radix> { } macro_rules! radix_fmt { - ($T:ty as $U:ty, $fmt:ident) => { + ($T:ty as $U:ty, $fmt:ident, $S:expr) => { + #[cfg(stage0)] impl fmt::Show for RadixFmt<$T, Radix> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::String::fmt(self, f) + } + } + + #[cfg(not(stage0))] + impl fmt::Show for RadixFmt<$T, Radix> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(fmt::String::fmt(self, f)); + f.write_str($S) + } + } + impl fmt::String for RadixFmt<$T, Radix> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { RadixFmt(ref x, radix) => radix.$fmt(*x as $U, f) } } } @@ -170,24 +185,48 @@ macro_rules! int_base { } } } + +macro_rules! show { + ($T:ident with $S:expr) => { + #[cfg(stage0)] + impl fmt::Show for $T { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::String::fmt(self, f) + } + } + + #[cfg(not(stage0))] + impl fmt::Show for $T { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(fmt::String::fmt(self, f)); + f.write_str($S) + } + } + } +} macro_rules! integer { ($Int:ident, $Uint:ident) => { - int_base! { Show for $Int as $Int -> Decimal } + integer! { $Int, $Uint, stringify!($Int), stringify!($Uint) } + }; + ($Int:ident, $Uint:ident, $SI:expr, $SU:expr) => { + int_base! { String for $Int as $Int -> Decimal } int_base! { Binary for $Int as $Uint -> Binary } int_base! { Octal for $Int as $Uint -> Octal } int_base! { LowerHex for $Int as $Uint -> LowerHex } int_base! { UpperHex for $Int as $Uint -> UpperHex } - radix_fmt! { $Int as $Int, fmt_int } + radix_fmt! { $Int as $Int, fmt_int, $SI } + show! { $Int with $SI } - int_base! { Show for $Uint as $Uint -> Decimal } + int_base! { String for $Uint as $Uint -> Decimal } int_base! { Binary for $Uint as $Uint -> Binary } int_base! { Octal for $Uint as $Uint -> Octal } int_base! { LowerHex for $Uint as $Uint -> LowerHex } int_base! { UpperHex for $Uint as $Uint -> UpperHex } - radix_fmt! { $Uint as $Uint, fmt_int } + radix_fmt! { $Uint as $Uint, fmt_int, $SU } + show! { $Uint with $SU } } } -integer! { int, uint } +integer! { int, uint, "i", "u" } integer! { i8, u8 } integer! { i16, u16 } integer! { i32, u32 } diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 7e1359d5c12..822416a387e 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -202,7 +202,6 @@ extern "rust-intrinsic" { /// crate it is invoked in. pub fn type_id<T: 'static>() -> TypeId; - /// Create a value initialized to zero. /// /// `init` is unsafe because it returns a zeroed-out datum, diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index e5753f6cc2e..d30cfc405a1 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -67,7 +67,7 @@ use num::{ToPrimitive, Int}; use ops::{Add, Deref, FnMut}; use option::Option; use option::Option::{Some, None}; -use std::kinds::Sized; +use std::marker::Sized; use uint; /// An interface for dealing with "external iterators". These types of iterators @@ -142,7 +142,7 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn last(mut self) -> Option< <Self as Iterator>::Item> { + fn last(mut self) -> Option<Self::Item> { let mut last = None; for x in self { last = Some(x); } last @@ -161,7 +161,7 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn nth(&mut self, mut n: uint) -> Option< <Self as Iterator>::Item> { + fn nth(&mut self, mut n: uint) -> Option<Self::Item> { for x in *self { if n == 0 { return Some(x) } n -= 1; @@ -186,7 +186,7 @@ pub trait IteratorExt: Iterator + Sized { #[inline] #[stable] fn chain<U>(self, other: U) -> Chain<Self, U> where - U: Iterator<Item=<Self as Iterator>::Item>, + U: Iterator<Item=Self::Item>, { Chain{a: self, b: other, flag: false} } @@ -228,8 +228,8 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn map<B, F>(self, f: F) -> Map< <Self as Iterator>::Item, B, Self, F> where - F: FnMut(<Self as Iterator>::Item) -> B, + fn map<B, F>(self, f: F) -> Map<Self::Item, B, Self, F> where + F: FnMut(Self::Item) -> B, { Map{iter: self, f: f} } @@ -248,8 +248,8 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn filter<P>(self, predicate: P) -> Filter< <Self as Iterator>::Item, Self, P> where - P: FnMut(&<Self as Iterator>::Item) -> bool, + fn filter<P>(self, predicate: P) -> Filter<Self::Item, Self, P> where + P: FnMut(&Self::Item) -> bool, { Filter{iter: self, predicate: predicate} } @@ -268,8 +268,8 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn filter_map<B, F>(self, f: F) -> FilterMap< <Self as Iterator>::Item, B, Self, F> where - F: FnMut(<Self as Iterator>::Item) -> Option<B>, + fn filter_map<B, F>(self, f: F) -> FilterMap<Self::Item, B, Self, F> where + F: FnMut(Self::Item) -> Option<B>, { FilterMap { iter: self, f: f } } @@ -312,7 +312,7 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn peekable(self) -> Peekable< <Self as Iterator>::Item, Self> { + fn peekable(self) -> Peekable<Self::Item, Self> { Peekable{iter: self, peeked: None} } @@ -332,8 +332,8 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn skip_while<P>(self, predicate: P) -> SkipWhile< <Self as Iterator>::Item, Self, P> where - P: FnMut(&<Self as Iterator>::Item) -> bool, + fn skip_while<P>(self, predicate: P) -> SkipWhile<Self::Item, Self, P> where + P: FnMut(&Self::Item) -> bool, { SkipWhile{iter: self, flag: false, predicate: predicate} } @@ -353,8 +353,8 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn take_while<P>(self, predicate: P) -> TakeWhile< <Self as Iterator>::Item, Self, P> where - P: FnMut(&<Self as Iterator>::Item) -> bool, + fn take_while<P>(self, predicate: P) -> TakeWhile<Self::Item, Self, P> where + P: FnMut(&Self::Item) -> bool, { TakeWhile{iter: self, flag: false, predicate: predicate} } @@ -422,8 +422,8 @@ pub trait IteratorExt: Iterator + Sized { self, initial_state: St, f: F, - ) -> Scan< <Self as Iterator>::Item, B, Self, St, F> where - F: FnMut(&mut St, <Self as Iterator>::Item) -> Option<B>, + ) -> Scan<Self::Item, B, Self, St, F> where + F: FnMut(&mut St, Self::Item) -> Option<B>, { Scan{iter: self, f: f, state: initial_state} } @@ -448,9 +448,9 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn flat_map<B, U, F>(self, f: F) -> FlatMap< <Self as Iterator>::Item, B, Self, U, F> where + fn flat_map<B, U, F>(self, f: F) -> FlatMap<Self::Item, B, Self, U, F> where U: Iterator<Item=B>, - F: FnMut(<Self as Iterator>::Item) -> U, + F: FnMut(Self::Item) -> U, { FlatMap{iter: self, f: f, frontiter: None, backiter: None } } @@ -508,8 +508,8 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn inspect<F>(self, f: F) -> Inspect< <Self as Iterator>::Item, Self, F> where - F: FnMut(&<Self as Iterator>::Item), + fn inspect<F>(self, f: F) -> Inspect<Self::Item, Self, F> where + F: FnMut(&Self::Item), { Inspect{iter: self, f: f} } @@ -546,7 +546,7 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn collect<B: FromIterator< <Self as Iterator>::Item>>(self) -> B { + fn collect<B: FromIterator<Self::Item>>(self) -> B { FromIterator::from_iter(self) } @@ -563,8 +563,8 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[unstable = "recently added as part of collections reform"] fn partition<B, F>(mut self, mut f: F) -> (B, B) where - B: Default + Extend< <Self as Iterator>::Item>, - F: FnMut(&<Self as Iterator>::Item) -> bool + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool { let mut left: B = Default::default(); let mut right: B = Default::default(); @@ -592,7 +592,7 @@ pub trait IteratorExt: Iterator + Sized { #[inline] #[stable] fn fold<B, F>(mut self, init: B, mut f: F) -> B where - F: FnMut(B, <Self as Iterator>::Item) -> B, + F: FnMut(B, Self::Item) -> B, { let mut accum = init; for x in self { @@ -612,7 +612,7 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn all<F>(mut self, mut f: F) -> bool where F: FnMut(<Self as Iterator>::Item) -> bool { + fn all<F>(mut self, mut f: F) -> bool where F: FnMut(Self::Item) -> bool { for x in self { if !f(x) { return false; } } true } @@ -630,7 +630,7 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn any<F>(&mut self, mut f: F) -> bool where F: FnMut(<Self as Iterator>::Item) -> bool { + fn any<F>(&mut self, mut f: F) -> bool where F: FnMut(Self::Item) -> bool { for x in *self { if f(x) { return true; } } false } @@ -640,8 +640,8 @@ pub trait IteratorExt: Iterator + Sized { /// Does not consume the iterator past the first found element. #[inline] #[stable] - fn find<P>(&mut self, mut predicate: P) -> Option< <Self as Iterator>::Item> where - P: FnMut(&<Self as Iterator>::Item) -> bool, + fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where + P: FnMut(&Self::Item) -> bool, { for x in *self { if predicate(&x) { return Some(x) } @@ -653,7 +653,7 @@ pub trait IteratorExt: Iterator + Sized { #[inline] #[stable] fn position<P>(&mut self, mut predicate: P) -> Option<uint> where - P: FnMut(<Self as Iterator>::Item) -> bool, + P: FnMut(Self::Item) -> bool, { let mut i = 0; for x in *self { @@ -671,7 +671,7 @@ pub trait IteratorExt: Iterator + Sized { #[inline] #[stable] fn rposition<P>(&mut self, mut predicate: P) -> Option<uint> where - P: FnMut(<Self as Iterator>::Item) -> bool, + P: FnMut(Self::Item) -> bool, Self: ExactSizeIterator + DoubleEndedIterator { let len = self.len(); @@ -693,8 +693,7 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn max(self) -> Option< <Self as Iterator>::Item> where - <Self as Iterator>::Item: Ord + fn max(self) -> Option<Self::Item> where Self::Item: Ord { self.fold(None, |max, x| { match max { @@ -714,8 +713,7 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[stable] - fn min(self) -> Option< <Self as Iterator>::Item> where - <Self as Iterator>::Item: Ord + fn min(self) -> Option<Self::Item> where Self::Item: Ord { self.fold(None, |min, x| { match min { @@ -759,8 +757,7 @@ pub trait IteratorExt: Iterator + Sized { /// assert!(v.iter().min_max() == MinMax(&1, &1)); /// ``` #[unstable = "return type may change"] - fn min_max(mut self) -> MinMaxResult< <Self as Iterator>::Item> where - <Self as Iterator>::Item: Ord + fn min_max(mut self) -> MinMaxResult<Self::Item> where Self::Item: Ord { let (mut min, mut max) = match self.next() { None => return NoElements, @@ -817,10 +814,10 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[unstable = "may want to produce an Ordering directly; see #15311"] - fn max_by<B: Ord, F>(self, mut f: F) -> Option< <Self as Iterator>::Item> where - F: FnMut(&<Self as Iterator>::Item) -> B, + fn max_by<B: Ord, F>(self, mut f: F) -> Option<Self::Item> where + F: FnMut(&Self::Item) -> B, { - self.fold(None, |max: Option<(<Self as Iterator>::Item, B)>, x| { + self.fold(None, |max: Option<(Self::Item, B)>, x| { let x_val = f(&x); match max { None => Some((x, x_val)), @@ -846,10 +843,10 @@ pub trait IteratorExt: Iterator + Sized { /// ``` #[inline] #[unstable = "may want to produce an Ordering directly; see #15311"] - fn min_by<B: Ord, F>(self, mut f: F) -> Option< <Self as Iterator>::Item> where - F: FnMut(&<Self as Iterator>::Item) -> B, + fn min_by<B: Ord, F>(self, mut f: F) -> Option<Self::Item> where + F: FnMut(&Self::Item) -> B, { - self.fold(None, |min: Option<(<Self as Iterator>::Item, B)>, x| { + self.fold(None, |min: Option<(Self::Item, B)>, x| { let x_val = f(&x); match min { None => Some((x, x_val)), @@ -968,7 +965,7 @@ impl<I> IteratorExt for I where I: Iterator {} #[stable] pub trait DoubleEndedIterator: Iterator { /// Yield an element from the end of the range, returning `None` if the range is empty. - fn next_back(&mut self) -> Option< <Self as Iterator>::Item>; + fn next_back(&mut self) -> Option<Self::Item>; } /// An object implementing random access indexing by `uint` @@ -984,7 +981,7 @@ pub trait RandomAccessIterator: Iterator { fn indexable(&self) -> uint; /// Return an element at an index, or `None` if the index is out of bounds - fn idx(&mut self, index: uint) -> Option< <Self as Iterator>::Item>; + fn idx(&mut self, index: uint) -> Option<Self::Item>; } /// An iterator that knows its exact length @@ -1015,14 +1012,14 @@ pub trait ExactSizeIterator: Iterator { impl<I> ExactSizeIterator for Enumerate<I> where I: ExactSizeIterator {} #[stable] impl<A, I, F> ExactSizeIterator for Inspect<A, I, F> where - I: ExactSizeIterator + Iterator<Item=A>, + I: ExactSizeIterator<Item=A>, F: FnMut(&A), {} #[stable] impl<I> ExactSizeIterator for Rev<I> where I: ExactSizeIterator + DoubleEndedIterator {} #[stable] impl<A, B, I, F> ExactSizeIterator for Map<A, B, I, F> where - I: ExactSizeIterator + Iterator<Item=A>, + I: ExactSizeIterator<Item=A>, F: FnMut(A) -> B, {} #[stable] @@ -1041,7 +1038,7 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator { type Item = <I as Iterator>::Item; #[inline] - fn next(&mut self) -> Option< <I as Iterator>::Item> { self.iter.next_back() } + fn next(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next_back() } #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() } } @@ -1049,7 +1046,7 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator { #[stable] impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator { #[inline] - fn next_back(&mut self) -> Option< <I as Iterator>::Item> { self.iter.next() } + fn next_back(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next() } } #[experimental = "trait is experimental"] @@ -1057,7 +1054,7 @@ impl<I> RandomAccessIterator for Rev<I> where I: DoubleEndedIterator + RandomAcc #[inline] fn indexable(&self) -> uint { self.iter.indexable() } #[inline] - fn idx(&mut self, index: uint) -> Option< <I as Iterator>::Item> { + fn idx(&mut self, index: uint) -> Option<<I as Iterator>::Item> { let amt = self.indexable(); self.iter.idx(amt - index - 1) } @@ -1075,7 +1072,7 @@ impl<'a, I> Iterator for ByRef<'a, I> where I: 'a + Iterator { type Item = <I as Iterator>::Item; #[inline] - fn next(&mut self) -> Option< <I as Iterator>::Item> { self.iter.next() } + fn next(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next() } #[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() } } @@ -1083,7 +1080,7 @@ impl<'a, I> Iterator for ByRef<'a, I> where I: 'a + Iterator { #[stable] impl<'a, I> DoubleEndedIterator for ByRef<'a, I> where I: 'a + DoubleEndedIterator { #[inline] - fn next_back(&mut self) -> Option< <I as Iterator>::Item> { self.iter.next_back() } + fn next_back(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next_back() } } /// A trait for iterators over elements which can be added together @@ -1244,7 +1241,7 @@ impl<T, D, I> Iterator for Cloned<I> where impl<T, D, I> DoubleEndedIterator for Cloned<I> where T: Clone, D: Deref<Target=T>, - I: DoubleEndedIterator + Iterator<Item=D>, + I: DoubleEndedIterator<Item=D>, { fn next_back(&mut self) -> Option<T> { self.it.next_back().cloned() @@ -1255,7 +1252,7 @@ impl<T, D, I> DoubleEndedIterator for Cloned<I> where impl<T, D, I> ExactSizeIterator for Cloned<I> where T: Clone, D: Deref<Target=T>, - I: ExactSizeIterator + Iterator<Item=D>, + I: ExactSizeIterator<Item=D>, {} /// An iterator that repeats endlessly @@ -1272,7 +1269,7 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator { type Item = <I as Iterator>::Item; #[inline] - fn next(&mut self) -> Option< <I as Iterator>::Item> { + fn next(&mut self) -> Option<<I as Iterator>::Item> { match self.iter.next() { None => { self.iter = self.orig.clone(); self.iter.next() } y => y @@ -1304,7 +1301,7 @@ impl<I> RandomAccessIterator for Cycle<I> where } #[inline] - fn idx(&mut self, index: uint) -> Option< <I as Iterator>::Item> { + fn idx(&mut self, index: uint) -> Option<<I as Iterator>::Item> { let liter = self.iter.indexable(); let lorig = self.orig.indexable(); if lorig == 0 { @@ -1363,8 +1360,8 @@ impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<It #[stable] impl<T, A, B> DoubleEndedIterator for Chain<A, B> where - A: DoubleEndedIterator + Iterator<Item=T>, - B: DoubleEndedIterator + Iterator<Item=T>, + A: DoubleEndedIterator<Item=T>, + B: DoubleEndedIterator<Item=T>, { #[inline] fn next_back(&mut self) -> Option<T> { @@ -1377,8 +1374,8 @@ impl<T, A, B> DoubleEndedIterator for Chain<A, B> where #[experimental = "trait is experimental"] impl<T, A, B> RandomAccessIterator for Chain<A, B> where - A: RandomAccessIterator + Iterator<Item=T>, - B: RandomAccessIterator + Iterator<Item=T>, + A: RandomAccessIterator<Item=T>, + B: RandomAccessIterator<Item=T>, { #[inline] fn indexable(&self) -> uint { @@ -1444,8 +1441,8 @@ impl<T, U, A, B> Iterator for Zip<A, B> where #[stable] impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where - A: ExactSizeIterator + Iterator<Item=T> + DoubleEndedIterator, - B: ExactSizeIterator + Iterator<Item=U> + DoubleEndedIterator, + A: DoubleEndedIterator + ExactSizeIterator<Item=T>, + B: DoubleEndedIterator + ExactSizeIterator<Item=U>, { #[inline] fn next_back(&mut self) -> Option<(T, U)> { @@ -1469,8 +1466,8 @@ impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where #[experimental = "trait is experimental"] impl<T, U, A, B> RandomAccessIterator for Zip<A, B> where - A: RandomAccessIterator + Iterator<Item=T>, - B: RandomAccessIterator + Iterator<Item=U>, + A: RandomAccessIterator<Item=T>, + B: RandomAccessIterator<Item=U>, { #[inline] fn indexable(&self) -> uint { @@ -1539,7 +1536,7 @@ impl<A, B, I, F> Iterator for Map<A, B, I, F> where I: Iterator<Item=A>, F: FnMu #[stable] impl<A, B, I, F> DoubleEndedIterator for Map<A, B, I, F> where - I: DoubleEndedIterator + Iterator<Item=A>, + I: DoubleEndedIterator<Item=A>, F: FnMut(A) -> B, { #[inline] @@ -1551,7 +1548,7 @@ impl<A, B, I, F> DoubleEndedIterator for Map<A, B, I, F> where #[experimental = "trait is experimental"] impl<A, B, I, F> RandomAccessIterator for Map<A, B, I, F> where - I: RandomAccessIterator + Iterator<Item=A>, + I: RandomAccessIterator<Item=A>, F: FnMut(A) -> B, { #[inline] @@ -1613,7 +1610,7 @@ impl<A, I, P> Iterator for Filter<A, I, P> where I: Iterator<Item=A>, P: FnMut(& #[stable] impl<A, I, P> DoubleEndedIterator for Filter<A, I, P> where - I: DoubleEndedIterator + Iterator<Item=A>, + I: DoubleEndedIterator<Item=A>, P: FnMut(&A) -> bool, { #[inline] @@ -1676,7 +1673,7 @@ impl<A, B, I, F> Iterator for FilterMap<A, B, I, F> where #[stable] impl<A, B, I, F> DoubleEndedIterator for FilterMap<A, B, I, F> where - I: DoubleEndedIterator + Iterator<Item=A>, + I: DoubleEndedIterator<Item=A>, F: FnMut(A) -> Option<B>, { #[inline] @@ -1925,7 +1922,7 @@ impl<I> Iterator for Skip<I> where I: Iterator { type Item = <I as Iterator>::Item; #[inline] - fn next(&mut self) -> Option< <I as Iterator>::Item> { + fn next(&mut self) -> Option<<I as Iterator>::Item> { let mut next = self.iter.next(); if self.n == 0 { next @@ -1972,7 +1969,7 @@ impl<I> RandomAccessIterator for Skip<I> where I: RandomAccessIterator{ } #[inline] - fn idx(&mut self, index: uint) -> Option< <I as Iterator>::Item> { + fn idx(&mut self, index: uint) -> Option<<I as Iterator>::Item> { if index >= self.indexable() { None } else { @@ -1995,7 +1992,7 @@ impl<I> Iterator for Take<I> where I: Iterator{ type Item = <I as Iterator>::Item; #[inline] - fn next(&mut self) -> Option< <I as Iterator>::Item> { + fn next(&mut self) -> Option<<I as Iterator>::Item> { if self.n != 0 { self.n -= 1; self.iter.next() @@ -2027,7 +2024,7 @@ impl<I> RandomAccessIterator for Take<I> where I: RandomAccessIterator{ } #[inline] - fn idx(&mut self, index: uint) -> Option< <I as Iterator>::Item> { + fn idx(&mut self, index: uint) -> Option<<I as Iterator>::Item> { if index >= self.n { None } else { @@ -2153,8 +2150,8 @@ impl<A, B, I, U, F> Iterator for FlatMap<A, B, I, U, F> where #[stable] impl<A, B, I, U, F> DoubleEndedIterator for FlatMap<A, B, I, U, F> where - I: DoubleEndedIterator + Iterator<Item=A>, - U: DoubleEndedIterator + Iterator<Item=B>, + I: DoubleEndedIterator<Item=A>, + U: DoubleEndedIterator<Item=B>, F: FnMut(A) -> U, { #[inline] @@ -2189,7 +2186,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator { type Item = <I as Iterator>::Item; #[inline] - fn next(&mut self) -> Option< <I as Iterator>::Item> { + fn next(&mut self) -> Option<<I as Iterator>::Item> { if self.done { None } else { @@ -2216,7 +2213,7 @@ impl<I> Iterator for Fuse<I> where I: Iterator { #[stable] impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator { #[inline] - fn next_back(&mut self) -> Option< <I as Iterator>::Item> { + fn next_back(&mut self) -> Option<<I as Iterator>::Item> { if self.done { None } else { @@ -2240,7 +2237,7 @@ impl<I> RandomAccessIterator for Fuse<I> where I: RandomAccessIterator { } #[inline] - fn idx(&mut self, index: uint) -> Option< <I as Iterator>::Item> { + fn idx(&mut self, index: uint) -> Option<<I as Iterator>::Item> { self.iter.idx(index) } } @@ -2308,7 +2305,7 @@ impl<A, I, F> Iterator for Inspect<A, I, F> where I: Iterator<Item=A>, F: FnMut( #[stable] impl<A, I, F> DoubleEndedIterator for Inspect<A, I, F> where - I: DoubleEndedIterator + Iterator<Item=A>, + I: DoubleEndedIterator<Item=A>, F: FnMut(&A), { #[inline] @@ -2320,7 +2317,7 @@ impl<A, I, F> DoubleEndedIterator for Inspect<A, I, F> where #[experimental = "trait is experimental"] impl<A, I, F> RandomAccessIterator for Inspect<A, I, F> where - I: RandomAccessIterator + Iterator<Item=A>, + I: RandomAccessIterator<Item=A>, F: FnMut(&A), { #[inline] diff --git a/src/libcore/kinds.rs b/src/libcore/kinds.rs deleted file mode 100644 index 5d69938fccf..00000000000 --- a/src/libcore/kinds.rs +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright 2012 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. - -//! Primitive traits representing basic 'kinds' of types -//! -//! Rust types can be classified in various useful ways according to -//! intrinsic properties of the type. These classifications, often called -//! 'kinds', are represented as traits. -//! -//! They cannot be implemented by user code, but are instead implemented -//! by the compiler automatically for the types to which they apply. - -/// Types able to be transferred across task boundaries. -#[lang="send"] -pub unsafe trait Send : 'static { - // empty. -} - -/// Types with a constant size known at compile-time. -#[lang="sized"] -pub trait Sized { - // Empty. -} - -/// Types that can be copied by simply copying bits (i.e. `memcpy`). -#[lang="copy"] -pub trait Copy { - // Empty. -} - -/// Types that can be safely shared between tasks when aliased. -/// -/// The precise definition is: a type `T` is `Sync` if `&T` is -/// thread-safe. In other words, there is no possibility of data races -/// when passing `&T` references between tasks. -/// -/// As one would expect, primitive types like `u8` and `f64` are all -/// `Sync`, and so are simple aggregate types containing them (like -/// tuples, structs and enums). More instances of basic `Sync` types -/// include "immutable" types like `&T` and those with simple -/// inherited mutability, such as `Box<T>`, `Vec<T>` and most other -/// collection types. (Generic parameters need to be `Sync` for their -/// container to be `Sync`.) -/// -/// A somewhat surprising consequence of the definition is `&mut T` is -/// `Sync` (if `T` is `Sync`) even though it seems that it might -/// provide unsynchronised mutation. The trick is a mutable reference -/// stored in an aliasable reference (that is, `& &mut T`) becomes -/// read-only, as if it were a `& &T`, hence there is no risk of a data -/// race. -/// -/// Types that are not `Sync` are those that have "interior -/// mutability" in a non-thread-safe way, such as `Cell` and `RefCell` -/// in `std::cell`. These types allow for mutation of their contents -/// even when in an immutable, aliasable slot, e.g. the contents of -/// `&Cell<T>` can be `.set`, and do not ensure data races are -/// impossible, hence they cannot be `Sync`. A higher level example -/// of a non-`Sync` type is the reference counted pointer -/// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new -/// reference, which modifies the reference counts in a non-atomic -/// way. -/// -/// For cases when one does need thread-safe interior mutability, -/// types like the atomics in `std::sync` and `Mutex` & `RWLock` in -/// the `sync` crate do ensure that any mutation cannot cause data -/// races. Hence these types are `Sync`. -/// -/// Users writing their own types with interior mutability (or anything -/// else that is not thread-safe) should use the `NoSync` marker type -/// (from `std::kinds::marker`) to ensure that the compiler doesn't -/// consider the user-defined type to be `Sync`. Any types with -/// interior mutability must also use the `std::cell::UnsafeCell` wrapper -/// 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). -#[lang="sync"] -pub unsafe trait Sync { - // Empty -} - -/// Marker types are special types that are used with unsafe code to -/// inform the compiler of special constraints. Marker types should -/// only be needed when you are creating an abstraction that is -/// implemented using unsafe code. In that case, you may want to embed -/// some of the marker types below into your type. -pub mod marker { - use super::{Copy,Sized}; - use clone::Clone; - - /// 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`. - /// - /// # Example - /// - /// Given a struct `S` that includes a type parameter `T` - /// but does not actually *reference* that type parameter: - /// - /// ```ignore - /// use std::mem; - /// - /// struct S<T> { x: *() } - /// fn get<T>(s: &S<T>) -> T { - /// unsafe { - /// let x: *T = mem::transmute(s.x); - /// *x - /// } - /// } - /// ``` - /// - /// 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). - #[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. - /// - /// 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 contravariant constraint. - /// If you are not sure, you probably want to use `InvariantType`. - /// - /// # Example - /// - /// Given a struct `S` that includes a type parameter `T` - /// but does not actually *reference* that type parameter: - /// - /// ``` - /// 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. - #[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>. - /// - /// # Example - /// - /// The Cell type is an example which uses unsafe code to achieve - /// "interior" mutability: - /// - /// ``` - /// pub struct Cell<T> { value: T } - /// # fn main() {} - /// ``` - /// - /// 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. - #[lang="invariant_type"] - #[derive(PartialEq, Eq, PartialOrd, Ord)] - pub struct InvariantType<T: ?Sized>; - - impl<T: ?Sized> Copy for InvariantType<T> {} - 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>. - #[lang="covariant_lifetime"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct CovariantLifetime<'a>; - - /// 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>. - #[lang="contravariant_lifetime"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct ContravariantLifetime<'a>; - - /// 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`). - #[lang="invariant_lifetime"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct InvariantLifetime<'a>; - - /// A type which is considered "not sendable", meaning that it cannot - /// be safely sent between tasks, even if it is owned. This is - /// typically embedded in other types, such as `Gc`, to ensure that - /// their instances remain thread-local. - #[lang="no_send_bound"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct NoSend; - - /// 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. - #[lang="no_copy_bound"] - #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] - #[allow(missing_copy_implementations)] - pub struct NoCopy; - - /// A type which is considered "not sync", meaning that - /// its contents are not threadsafe, hence they cannot be - /// shared between tasks. - #[lang="no_sync_bound"] - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct NoSync; - - /// A type which is considered managed by the GC. This is typically - /// embedded in other types. - #[lang="managed_bound"] - #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] - #[allow(missing_copy_implementations)] - pub struct Managed; -} - diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index aff0065c527..a7e3b61b0d4 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -56,29 +56,25 @@ html_playground_url = "http://play.rust-lang.org/")] #![no_std] -#![allow(unknown_features, raw_pointer_deriving)] -#![feature(globs, intrinsics, lang_items, macro_rules, phase)] +#![allow(unknown_features, raw_pointer_derive)] +#![feature(intrinsics, lang_items)] #![feature(simd, unsafe_destructor, slicing_syntax)] -#![feature(default_type_params, unboxed_closures, associated_types)] +#![feature(unboxed_closures)] #![deny(missing_docs)] -#[cfg_attr(stage0, macro_escape)] -#[cfg_attr(not(stage0), macro_use)] +#[macro_use] mod macros; #[path = "num/float_macros.rs"] -#[cfg_attr(stage0, macro_escape)] -#[cfg_attr(not(stage0), macro_use)] +#[macro_use] mod float_macros; #[path = "num/int_macros.rs"] -#[cfg_attr(stage0, macro_escape)] -#[cfg_attr(not(stage0), macro_use)] +#[macro_use] mod int_macros; #[path = "num/uint_macros.rs"] -#[cfg_attr(stage0, macro_escape)] -#[cfg_attr(not(stage0), macro_use)] +#[macro_use] mod uint_macros; #[path = "num/int.rs"] pub mod int; @@ -111,7 +107,7 @@ pub mod ptr; /* Core language traits */ -pub mod kinds; +pub mod marker; pub mod ops; pub mod cmp; pub mod clone; @@ -150,7 +146,9 @@ mod core { mod std { pub use clone; pub use cmp; - pub use kinds; + #[cfg(stage0)] + pub use marker as kinds; + pub use marker; pub use option; pub use fmt; pub use hash; diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index a579f9db416..bfe88fff22f 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -83,7 +83,7 @@ macro_rules! assert_eq { if !((*left_val == *right_val) && (*right_val == *left_val)) { panic!("assertion failed: `(left == right) && (right == left)` \ - (left: `{}`, right: `{}`)", *left_val, *right_val) + (left: `{:?}`, right: `{:?}`)", *left_val, *right_val) } } } @@ -142,16 +142,9 @@ macro_rules! debug_assert_eq { ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); }) } -#[cfg(stage0)] -#[macro_export] -macro_rules! try { - ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) }) -} - /// Short circuiting evaluation on Err /// /// `libstd` contains a more general `try!` macro that uses `FromError`. -#[cfg(not(stage0))] #[macro_export] macro_rules! try { ($e:expr) => ({ @@ -186,9 +179,12 @@ macro_rules! write { #[macro_export] #[stable] macro_rules! writeln { - ($dst:expr, $fmt:expr $($arg:tt)*) => ( - write!($dst, concat!($fmt, "\n") $($arg)*) - ) + ($dst:expr, $fmt:expr) => ( + write!($dst, concat!($fmt, "\n")) + ); + ($dst:expr, $fmt:expr, $($arg:tt)*) => ( + write!($dst, concat!($fmt, "\n"), $($arg)*) + ); } /// A utility macro for indicating unreachable code. diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs new file mode 100644 index 00000000000..d400cb47cbf --- /dev/null +++ b/src/libcore/marker.rs @@ -0,0 +1,314 @@ +// 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. + +//! Primitive traits and marker types representing basic 'kinds' of types. +//! +//! Rust types can be classified in various useful ways according to +//! intrinsic properties of the type. These classifications, often called +//! 'kinds', are represented as traits. +//! +//! They cannot be implemented by user code, but are instead implemented +//! by the compiler automatically for the types to which they apply. +//! +//! Marker types are special types that are used with unsafe code to +//! inform the compiler of special constraints. Marker types should +//! only be needed when you are creating an abstraction that is +//! implemented using unsafe code. In that case, you may want to embed +//! some of the marker types below into your type. + +#![stable] + +use clone::Clone; + +/// Types able to be transferred across task boundaries. +#[unstable = "will be overhauled with new lifetime rules; see RFC 458"] +#[lang="send"] +pub unsafe trait Send: 'static { + // empty. +} + +/// Types with a constant size known at compile-time. +#[stable] +#[lang="sized"] +pub trait Sized { + // Empty. +} + +/// Types that can be copied by simply copying bits (i.e. `memcpy`). +#[stable] +#[lang="copy"] +pub trait Copy { + // Empty. +} + +/// Types that can be safely shared between tasks when aliased. +/// +/// The precise definition is: a type `T` is `Sync` if `&T` is +/// thread-safe. In other words, there is no possibility of data races +/// when passing `&T` references between tasks. +/// +/// As one would expect, primitive types like `u8` and `f64` are all +/// `Sync`, and so are simple aggregate types containing them (like +/// tuples, structs and enums). More instances of basic `Sync` types +/// include "immutable" types like `&T` and those with simple +/// inherited mutability, such as `Box<T>`, `Vec<T>` and most other +/// collection types. (Generic parameters need to be `Sync` for their +/// container to be `Sync`.) +/// +/// A somewhat surprising consequence of the definition is `&mut T` is +/// `Sync` (if `T` is `Sync`) even though it seems that it might +/// provide unsynchronised mutation. The trick is a mutable reference +/// stored in an aliasable reference (that is, `& &mut T`) becomes +/// read-only, as if it were a `& &T`, hence there is no risk of a data +/// race. +/// +/// Types that are not `Sync` are those that have "interior +/// mutability" in a non-thread-safe way, such as `Cell` and `RefCell` +/// in `std::cell`. These types allow for mutation of their contents +/// even when in an immutable, aliasable slot, e.g. the contents of +/// `&Cell<T>` can be `.set`, and do not ensure data races are +/// impossible, hence they cannot be `Sync`. A higher level example +/// of a non-`Sync` type is the reference counted pointer +/// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new +/// reference, which modifies the reference counts in a non-atomic +/// way. +/// +/// For cases when one does need thread-safe interior mutability, +/// types like the atomics in `std::sync` and `Mutex` & `RWLock` in +/// the `sync` crate do ensure that any mutation cannot cause data +/// races. Hence these types are `Sync`. +/// +/// Users writing their own types with interior mutability (or anything +/// else that is not thread-safe) should use the `NoSync` marker type +/// (from `std::marker`) to ensure that the compiler doesn't +/// consider the user-defined type to be `Sync`. Any types with +/// interior mutability must also use the `std::cell::UnsafeCell` wrapper +/// 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 = "will be overhauled with new lifetime rules; see RFC 458"] +#[lang="sync"] +pub unsafe trait Sync { + // Empty +} + + +/// 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`. +/// +/// # Example +/// +/// Given a struct `S` that includes a type parameter `T` +/// but does not actually *reference* that type parameter: +/// +/// ```ignore +/// use std::mem; +/// +/// struct S<T> { x: *() } +/// fn get<T>(s: &S<T>) -> T { +/// unsafe { +/// let x: *T = mem::transmute(s.x); +/// *x +/// } +/// } +/// ``` +/// +/// 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 = "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. +/// +/// 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 contravariant constraint. +/// If you are not sure, you probably want to use `InvariantType`. +/// +/// # Example +/// +/// Given a struct `S` that includes a type parameter `T` +/// but does not actually *reference* that type parameter: +/// +/// ``` +/// 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 = "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>. +/// +/// # Example +/// +/// The Cell type is an example which uses unsafe code to achieve +/// "interior" mutability: +/// +/// ``` +/// pub struct Cell<T> { value: T } +/// # fn main() {} +/// ``` +/// +/// 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. +#[unstable = "likely to change with new variance strategy"] +#[lang="invariant_type"] +#[derive(PartialEq, Eq, PartialOrd, Ord)] +pub struct InvariantType<T: ?Sized>; + +#[unstable = "likely to change with new variance strategy"] +impl<T: ?Sized> Copy for InvariantType<T> {} +#[unstable = "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 = "likely to change with new variance strategy"] +#[lang="covariant_lifetime"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct CovariantLifetime<'a>; + +/// 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 = "likely to change with new variance strategy"] +#[lang="contravariant_lifetime"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct ContravariantLifetime<'a>; + +/// 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 = "likely to change with new variance strategy"] +#[lang="invariant_lifetime"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct InvariantLifetime<'a>; + +/// A type which is considered "not sendable", meaning that it cannot +/// be safely sent between tasks, even if it is owned. This is +/// typically embedded in other types, such as `Gc`, to ensure that +/// their instances remain thread-local. +#[unstable = "likely to change with new variance strategy"] +#[lang="no_send_bound"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct NoSend; + +/// 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 = "likely to change with new variance strategy"] +#[lang="no_copy_bound"] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +#[allow(missing_copy_implementations)] +pub struct NoCopy; + +/// A type which is considered "not sync", meaning that +/// its contents are not threadsafe, hence they cannot be +/// shared between tasks. +#[unstable = "likely to change with new variance strategy"] +#[lang="no_sync_bound"] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct NoSync; + +/// A type which is considered managed by the GC. This is typically +/// embedded in other types. +#[unstable = "likely to change with new variance strategy"] +#[lang="managed_bound"] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +#[allow(missing_copy_implementations)] +pub struct Managed; diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index c6056916121..8438c9b206e 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -15,7 +15,7 @@ #![stable] -use kinds::Sized; +use marker::Sized; use intrinsics; use ptr; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 192d6063f6b..490d8111f46 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -21,10 +21,10 @@ use cmp::{PartialEq, Eq}; use cmp::{PartialOrd, Ord}; use intrinsics; use iter::IteratorExt; -use kinds::Copy; +use marker::Copy; use mem::size_of; use ops::{Add, Sub, Mul, Div, Rem, Neg}; -use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; +use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr, Index}; use option::Option; use option::Option::{Some, None}; use str::{FromStr, StrExt}; @@ -992,7 +992,7 @@ impl_to_primitive_float! { f64 } /// A generic trait for converting a number to a value. #[experimental = "trait is likely to be removed"] -pub trait FromPrimitive : ::kinds::Sized { +pub trait FromPrimitive : ::marker::Sized { /// Convert an `int` to return an optional value of this type. If the /// value cannot be represented by this value, the `None` is returned. #[inline] @@ -1577,7 +1577,7 @@ macro_rules! from_str_radix_float_impl { }; // Parse the exponent as decimal integer - let src = src[offset..]; + let src = src.index(&(offset..)); let (is_positive, exp) = match src.slice_shift_char() { Some(('-', src)) => (false, src.parse::<uint>()), Some(('+', src)) => (true, src.parse::<uint>()), diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 97d94e73bb3..4debab91739 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -51,8 +51,8 @@ //! } //! } //! fn main() { -//! println!("{}", Point {x: 1, y: 0} + Point {x: 2, y: 3}); -//! println!("{}", Point {x: 1, y: 0} - Point {x: 2, y: 3}); +//! println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3}); +//! println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3}); //! } //! ``` //! @@ -63,7 +63,7 @@ use clone::Clone; use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator}; -use kinds::Sized; +use marker::Sized; use option::Option::{self, Some, None}; /// The `Drop` trait is used to run some code when a value goes out of scope. This @@ -846,105 +846,6 @@ pub trait IndexMut<Index: ?Sized> { fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output; } -/// The `Slice` trait is used to specify the functionality of slicing operations -/// like `arr[from..to]` when used in an immutable context. -/// -/// # Example -/// -/// A trivial implementation of `Slice`. When `Foo[..Foo]` happens, it ends up -/// calling `slice_to`, and therefore, `main` prints `Slicing!`. -/// -/// ```ignore -/// use std::ops::Slice; -/// -/// #[derive(Copy)] -/// struct Foo; -/// -/// impl Slice<Foo, Foo> for Foo { -/// fn as_slice_<'a>(&'a self) -> &'a Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_from_or_fail<'a>(&'a self, _from: &Foo) -> &'a Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_to_or_fail<'a>(&'a self, _to: &Foo) -> &'a Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_or_fail<'a>(&'a self, _from: &Foo, _to: &Foo) -> &'a Foo { -/// println!("Slicing!"); -/// self -/// } -/// } -/// -/// fn main() { -/// Foo[..Foo]; -/// } -/// ``` -#[lang="slice"] -pub trait Slice<Idx: ?Sized, Result: ?Sized> { - /// The method for the slicing operation foo[] - fn as_slice_<'a>(&'a self) -> &'a Result; - /// The method for the slicing operation foo[from..] - fn slice_from_or_fail<'a>(&'a self, from: &Idx) -> &'a Result; - /// The method for the slicing operation foo[..to] - fn slice_to_or_fail<'a>(&'a self, to: &Idx) -> &'a Result; - /// The method for the slicing operation foo[from..to] - fn slice_or_fail<'a>(&'a self, from: &Idx, to: &Idx) -> &'a Result; -} - -/// The `SliceMut` trait is used to specify the functionality of slicing -/// operations like `arr[from..to]`, when used in a mutable context. -/// -/// # Example -/// -/// A trivial implementation of `SliceMut`. When `Foo[Foo..]` happens, it ends up -/// calling `slice_from_mut`, and therefore, `main` prints `Slicing!`. -/// -/// ```ignore -/// use std::ops::SliceMut; -/// -/// #[derive(Copy)] -/// struct Foo; -/// -/// impl SliceMut<Foo, Foo> for Foo { -/// fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_from_or_fail_mut<'a>(&'a mut self, _from: &Foo) -> &'a mut Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_to_or_fail_mut<'a>(&'a mut self, _to: &Foo) -> &'a mut Foo { -/// println!("Slicing!"); -/// self -/// } -/// fn slice_or_fail_mut<'a>(&'a mut self, _from: &Foo, _to: &Foo) -> &'a mut Foo { -/// println!("Slicing!"); -/// self -/// } -/// } -/// -/// pub fn main() { -/// Foo[mut Foo..]; -/// } -/// ``` -#[lang="slice_mut"] -pub trait SliceMut<Idx: ?Sized, Result: ?Sized> { - /// The method for the slicing operation foo[] - fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Result; - /// The method for the slicing operation foo[from..] - fn slice_from_or_fail_mut<'a>(&'a mut self, from: &Idx) -> &'a mut Result; - /// The method for the slicing operation foo[..to] - fn slice_to_or_fail_mut<'a>(&'a mut self, to: &Idx) -> &'a mut Result; - /// The method for the slicing operation foo[from..to] - fn slice_or_fail_mut<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result; -} - - /// An unbounded range. #[derive(Copy)] #[lang="full_range"] @@ -962,8 +863,6 @@ pub struct Range<Idx> { pub end: Idx, } -// FIXME(#19391) needs a snapshot -//impl<Idx: Clone + Step<T=uint>> Iterator<Idx> for Range<Idx> { #[unstable = "API still in development"] impl<Idx: Clone + Step> Iterator for Range<Idx> { type Item = Idx; @@ -1134,7 +1033,7 @@ impl<'a, T: ?Sized> Deref for &'a mut T { pub trait DerefMut: Deref { /// The method called to mutably dereference a value #[stable] - fn deref_mut<'a>(&'a mut self) -> &'a mut <Self as Deref>::Target; + fn deref_mut<'a>(&'a mut self) -> &'a mut Self::Target; } #[stable] diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 39d0f024d4d..272570a0d5b 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -238,7 +238,7 @@ impl<T> Option<T> { /// // First, cast `Option<String>` to `Option<&String>` with `as_ref`, /// // then consume *that* with `map`, leaving `num_as_str` on the stack. /// let num_as_int: Option<uint> = num_as_str.as_ref().map(|n| n.len()); - /// println!("still can print num_as_str: {}", num_as_str); + /// println!("still can print num_as_str: {:?}", num_as_str); /// ``` #[inline] #[stable] diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index e88cb73c8a9..c3bb9c91557 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -29,8 +29,8 @@ //! ``` // Reexported core operators -pub use kinds::{Copy, Send, Sized, Sync}; -pub use ops::{Drop, Fn, FnMut, FnOnce}; +pub use marker::{Copy, Send, Sized, Sync}; +pub use ops::{Drop, Fn, FnMut, FnOnce, FullRange}; // Reexported functions pub use iter::range; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 0b77f3456b2..c35d948165a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -92,7 +92,7 @@ use mem; use clone::Clone; use intrinsics; use option::Option::{self, Some, None}; -use kinds::{Send, Sized, Sync}; +use marker::{Send, Sized, Sync}; use cmp::{PartialEq, Eq, Ord, PartialOrd}; use cmp::Ordering::{self, Less, Equal, Greater}; diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index 5ef6f6b2623..1ad6d43f76f 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -18,7 +18,7 @@ //! //! Their definition should always match the ABI defined in `rustc::back::abi`. -use kinds::Copy; +use marker::Copy; use mem; /// The representation of a Rust slice diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 8e9bf5487e3..95ae6ebfb68 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -47,10 +47,10 @@ //! let version = parse_version(&[1, 2, 3, 4]); //! match version { //! Ok(v) => { -//! println!("working with version: {}", v); +//! println!("working with version: {:?}", v); //! } //! Err(e) => { -//! println!("error parsing header: {}", e); +//! println!("error parsing header: {:?}", e); //! } //! } //! ``` @@ -743,7 +743,7 @@ impl<T, E: Show> Result<T, E> { match self { Ok(t) => t, Err(e) => - panic!("called `Result::unwrap()` on an `Err` value: {}", e) + panic!("called `Result::unwrap()` on an `Err` value: {:?}", e) } } } @@ -773,7 +773,7 @@ impl<T: Show, E> Result<T, E> { pub fn unwrap_err(self) -> E { match self { Ok(t) => - panic!("called `Result::unwrap_err()` on an `Ok` value: {}", t), + panic!("called `Result::unwrap_err()` on an `Ok` value: {:?}", t), Err(e) => e } } diff --git a/src/libcore/simd.rs b/src/libcore/simd.rs index 66b29bab98c..1f9aebb91be 100644 --- a/src/libcore/simd.rs +++ b/src/libcore/simd.rs @@ -25,7 +25,7 @@ //! use std::simd::f32x4; //! let a = f32x4(40.0, 41.0, 42.0, 43.0); //! let b = f32x4(1.0, 1.1, 3.4, 9.8); -//! println!("{}", a + b); +//! println!("{:?}", a + b); //! } //! ``` //! diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 093ed0b242f..bf2df465370 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -41,9 +41,9 @@ use cmp::Ordering::{Less, Equal, Greater}; use cmp; use default::Default; use iter::*; -use kinds::Copy; +use marker::Copy; use num::Int; -use ops::{FnMut, self}; +use ops::{FnMut, self, Index}; use option::Option; use option::Option::{None, Some}; use result::Result; @@ -52,7 +52,7 @@ use ptr; use ptr::PtrExt; use mem; use mem::size_of; -use kinds::{Sized, marker}; +use marker::{Sized, self}; use raw::Repr; // Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module. use raw::Slice as RawSlice; @@ -159,7 +159,7 @@ impl<T> SliceExt for [T] { #[inline] fn split_at(&self, mid: uint) -> (&[T], &[T]) { - (self[..mid], self[mid..]) + (self.index(&(0..mid)), self.index(&(mid..))) } #[inline] @@ -236,11 +236,11 @@ impl<T> SliceExt for [T] { } #[inline] - fn tail(&self) -> &[T] { self[1..] } + fn tail(&self) -> &[T] { self.index(&(1..)) } #[inline] fn init(&self) -> &[T] { - self[..self.len() - 1] + self.index(&(0..(self.len() - 1))) } #[inline] @@ -292,17 +292,17 @@ impl<T> SliceExt for [T] { fn as_mut_slice(&mut self) -> &mut [T] { self } fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] { - ops::SliceMut::slice_or_fail_mut(self, &start, &end) + ops::IndexMut::index_mut(self, &ops::Range { start: start, end: end } ) } #[inline] fn slice_from_mut(&mut self, start: uint) -> &mut [T] { - ops::SliceMut::slice_from_or_fail_mut(self, &start) + ops::IndexMut::index_mut(self, &ops::RangeFrom { start: start } ) } #[inline] fn slice_to_mut(&mut self, end: uint) -> &mut [T] { - ops::SliceMut::slice_to_or_fail_mut(self, &end) + ops::IndexMut::index_mut(self, &ops::RangeTo { end: end } ) } #[inline] @@ -310,8 +310,8 @@ impl<T> SliceExt for [T] { unsafe { let self2: &mut [T] = mem::transmute_copy(&self); - (ops::SliceMut::slice_to_or_fail_mut(self, &mid), - ops::SliceMut::slice_from_or_fail_mut(self2, &mid)) + (ops::IndexMut::index_mut(self, &ops::RangeTo { end: mid } ), + ops::IndexMut::index_mut(self2, &ops::RangeFrom { start: mid } )) } } @@ -443,13 +443,13 @@ impl<T> SliceExt for [T] { #[inline] fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq { let n = needle.len(); - self.len() >= n && needle == self[..n] + self.len() >= n && needle == self.index(&(0..n)) } #[inline] fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq { let (m, n) = (self.len(), needle.len()); - m >= n && needle == self[m-n..] + m >= n && needle == self.index(&((m-n)..)) } #[unstable] @@ -551,62 +551,79 @@ impl<T> ops::IndexMut<uint> for [T] { } } -impl<T> ops::Slice<uint, [T]> for [T] { +impl<T> ops::Index<ops::Range<uint>> for [T] { + type Output = [T]; #[inline] - fn as_slice_<'a>(&'a self) -> &'a [T] { - self - } - - #[inline] - fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] { - self.slice_or_fail(start, &self.len()) - } - - #[inline] - fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] { - self.slice_or_fail(&0, end) - } - #[inline] - fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { - assert!(*start <= *end); - assert!(*end <= self.len()); + fn index(&self, index: &ops::Range<uint>) -> &[T] { + assert!(index.start <= index.end); + assert!(index.end <= self.len()); unsafe { transmute(RawSlice { - data: self.as_ptr().offset(*start as int), - len: (*end - *start) + data: self.as_ptr().offset(index.start as int), + len: index.end - index.start }) } } } - -impl<T> ops::SliceMut<uint, [T]> for [T] { +impl<T> ops::Index<ops::RangeTo<uint>> for [T] { + type Output = [T]; #[inline] - fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { - self + fn index(&self, index: &ops::RangeTo<uint>) -> &[T] { + self.index(&ops::Range{ start: 0, end: index.end }) } - +} +impl<T> ops::Index<ops::RangeFrom<uint>> for [T] { + type Output = [T]; #[inline] - fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] { - let len = &self.len(); - self.slice_or_fail_mut(start, len) + fn index(&self, index: &ops::RangeFrom<uint>) -> &[T] { + self.index(&ops::Range{ start: index.start, end: self.len() }) } - +} +impl<T> ops::Index<ops::FullRange> for [T] { + type Output = [T]; #[inline] - fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] { - self.slice_or_fail_mut(&0, end) + fn index(&self, _index: &ops::FullRange) -> &[T] { + self } +} + +impl<T> ops::IndexMut<ops::Range<uint>> for [T] { + type Output = [T]; #[inline] - fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { - assert!(*start <= *end); - assert!(*end <= self.len()); + fn index_mut(&mut self, index: &ops::Range<uint>) -> &mut [T] { + assert!(index.start <= index.end); + assert!(index.end <= self.len()); unsafe { transmute(RawSlice { - data: self.as_ptr().offset(*start as int), - len: (*end - *start) + data: self.as_ptr().offset(index.start as int), + len: index.end - index.start }) } } } +impl<T> ops::IndexMut<ops::RangeTo<uint>> for [T] { + type Output = [T]; + #[inline] + fn index_mut(&mut self, index: &ops::RangeTo<uint>) -> &mut [T] { + self.index_mut(&ops::Range{ start: 0, end: index.end }) + } +} +impl<T> ops::IndexMut<ops::RangeFrom<uint>> for [T] { + type Output = [T]; + #[inline] + fn index_mut(&mut self, index: &ops::RangeFrom<uint>) -> &mut [T] { + let len = self.len(); + self.index_mut(&ops::Range{ start: index.start, end: len }) + } +} +impl<T> ops::IndexMut<ops::FullRange> for [T] { + type Output = [T]; + #[inline] + fn index_mut(&mut self, _index: &ops::FullRange) -> &mut [T] { + self + } +} + //////////////////////////////////////////////////////////////////////////////// // Common traits @@ -716,7 +733,7 @@ macro_rules! iterator { } macro_rules! make_slice { - ($t: ty -> $result: ty: $start: expr, $end: expr) => {{ + ($t: ty => $result: ty: $start: expr, $end: expr) => {{ let diff = $end as uint - $start as uint; let len = if mem::size_of::<T>() == 0 { diff @@ -738,21 +755,38 @@ pub struct Iter<'a, T: 'a> { } #[experimental] -impl<'a, T> ops::Slice<uint, [T]> for Iter<'a, T> { - fn as_slice_(&self) -> &[T] { - self.as_slice() +impl<'a, T> ops::Index<ops::Range<uint>> for Iter<'a, T> { + type Output = [T]; + #[inline] + fn index(&self, index: &ops::Range<uint>) -> &[T] { + self.as_slice().index(index) } - fn slice_from_or_fail<'b>(&'b self, from: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice().slice_from_or_fail(from) +} + +#[experimental] +impl<'a, T> ops::Index<ops::RangeTo<uint>> for Iter<'a, T> { + type Output = [T]; + #[inline] + fn index(&self, index: &ops::RangeTo<uint>) -> &[T] { + self.as_slice().index(index) } - fn slice_to_or_fail<'b>(&'b self, to: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice().slice_to_or_fail(to) +} + +#[experimental] +impl<'a, T> ops::Index<ops::RangeFrom<uint>> for Iter<'a, T> { + type Output = [T]; + #[inline] + fn index(&self, index: &ops::RangeFrom<uint>) -> &[T] { + self.as_slice().index(index) } - fn slice_or_fail<'b>(&'b self, from: &uint, to: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice().slice_or_fail(from, to) +} + +#[experimental] +impl<'a, T> ops::Index<ops::FullRange> for Iter<'a, T> { + type Output = [T]; + #[inline] + fn index(&self, _index: &ops::FullRange) -> &[T] { + self.as_slice() } } @@ -763,7 +797,7 @@ impl<'a, T> Iter<'a, T> { /// iterator can continue to be used while this exists. #[experimental] pub fn as_slice(&self) -> &'a [T] { - make_slice!(T -> &'a [T]: self.ptr, self.end) + make_slice!(T => &'a [T]: self.ptr, self.end) } } @@ -812,44 +846,74 @@ pub struct IterMut<'a, T: 'a> { marker: marker::ContravariantLifetime<'a>, } + #[experimental] -impl<'a, T> ops::Slice<uint, [T]> for IterMut<'a, T> { - fn as_slice_<'b>(&'b self) -> &'b [T] { - make_slice!(T -> &'b [T]: self.ptr, self.end) +impl<'a, T> ops::Index<ops::Range<uint>> for IterMut<'a, T> { + type Output = [T]; + #[inline] + fn index(&self, index: &ops::Range<uint>) -> &[T] { + self.index(&ops::FullRange).index(index) } - fn slice_from_or_fail<'b>(&'b self, from: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice_().slice_from_or_fail(from) +} +#[experimental] +impl<'a, T> ops::Index<ops::RangeTo<uint>> for IterMut<'a, T> { + type Output = [T]; + #[inline] + fn index(&self, index: &ops::RangeTo<uint>) -> &[T] { + self.index(&ops::FullRange).index(index) } - fn slice_to_or_fail<'b>(&'b self, to: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice_().slice_to_or_fail(to) +} +#[experimental] +impl<'a, T> ops::Index<ops::RangeFrom<uint>> for IterMut<'a, T> { + type Output = [T]; + #[inline] + fn index(&self, index: &ops::RangeFrom<uint>) -> &[T] { + self.index(&ops::FullRange).index(index) } - fn slice_or_fail<'b>(&'b self, from: &uint, to: &uint) -> &'b [T] { - use ops::Slice; - self.as_slice_().slice_or_fail(from, to) +} +#[experimental] +impl<'a, T> ops::Index<ops::FullRange> for IterMut<'a, T> { + type Output = [T]; + #[inline] + fn index(&self, _index: &ops::FullRange) -> &[T] { + make_slice!(T => &[T]: self.ptr, self.end) } } #[experimental] -impl<'a, T> ops::SliceMut<uint, [T]> for IterMut<'a, T> { - fn as_mut_slice_<'b>(&'b mut self) -> &'b mut [T] { - make_slice!(T -> &'b mut [T]: self.ptr, self.end) +impl<'a, T> ops::IndexMut<ops::Range<uint>> for IterMut<'a, T> { + type Output = [T]; + #[inline] + fn index_mut(&mut self, index: &ops::Range<uint>) -> &mut [T] { + self.index_mut(&ops::FullRange).index_mut(index) } - fn slice_from_or_fail_mut<'b>(&'b mut self, from: &uint) -> &'b mut [T] { - use ops::SliceMut; - self.as_mut_slice_().slice_from_or_fail_mut(from) +} +#[experimental] +impl<'a, T> ops::IndexMut<ops::RangeTo<uint>> for IterMut<'a, T> { + type Output = [T]; + #[inline] + fn index_mut(&mut self, index: &ops::RangeTo<uint>) -> &mut [T] { + self.index_mut(&ops::FullRange).index_mut(index) } - fn slice_to_or_fail_mut<'b>(&'b mut self, to: &uint) -> &'b mut [T] { - use ops::SliceMut; - self.as_mut_slice_().slice_to_or_fail_mut(to) +} +#[experimental] +impl<'a, T> ops::IndexMut<ops::RangeFrom<uint>> for IterMut<'a, T> { + type Output = [T]; + #[inline] + fn index_mut(&mut self, index: &ops::RangeFrom<uint>) -> &mut [T] { + self.index_mut(&ops::FullRange).index_mut(index) } - fn slice_or_fail_mut<'b>(&'b mut self, from: &uint, to: &uint) -> &'b mut [T] { - use ops::SliceMut; - self.as_mut_slice_().slice_or_fail_mut(from, to) +} +#[experimental] +impl<'a, T> ops::IndexMut<ops::FullRange> for IterMut<'a, T> { + type Output = [T]; + #[inline] + fn index_mut(&mut self, _index: &ops::FullRange) -> &mut [T] { + make_slice!(T => &mut [T]: self.ptr, self.end) } } + impl<'a, T> IterMut<'a, T> { /// View the underlying data as a subslice of the original data. /// @@ -859,7 +923,7 @@ impl<'a, T> IterMut<'a, T> { /// restricted lifetimes that do not consume the iterator. #[experimental] pub fn into_slice(self) -> &'a mut [T] { - make_slice!(T -> &'a mut [T]: self.ptr, self.end) + make_slice!(T => &'a mut [T]: self.ptr, self.end) } } @@ -873,7 +937,7 @@ impl<'a, T> ExactSizeIterator for IterMut<'a, T> {} trait SplitIter: DoubleEndedIterator { /// Mark the underlying iterator as complete, extracting the remaining /// portion of the slice. - fn finish(&mut self) -> Option< <Self as Iterator>::Item>; + fn finish(&mut self) -> Option<Self::Item>; } /// An iterator over subslices separated by elements that match a predicate @@ -908,8 +972,8 @@ impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool { match self.v.iter().position(|x| (self.pred)(x)) { None => self.finish(), Some(idx) => { - let ret = Some(self.v[..idx]); - self.v = self.v[idx + 1..]; + let ret = Some(self.v.index(&(0..idx))); + self.v = self.v.index(&((idx + 1)..)); ret } } @@ -934,8 +998,8 @@ impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P> where P: FnMut(&T) -> boo match self.v.iter().rposition(|x| (self.pred)(x)) { None => self.finish(), Some(idx) => { - let ret = Some(self.v[idx + 1..]); - self.v = self.v[..idx]; + let ret = Some(self.v.index(&((idx + 1)..))); + self.v = self.v.index(&(0..idx)); ret } } @@ -1038,7 +1102,7 @@ struct GenericSplitN<I> { invert: bool } -impl<T, I: SplitIter + Iterator<Item=T>> Iterator for GenericSplitN<I> { +impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> { type Item = T; #[inline] @@ -1131,8 +1195,8 @@ impl<'a, T> Iterator for Windows<'a, T> { if self.size > self.v.len() { None } else { - let ret = Some(self.v[..self.size]); - self.v = self.v[1..]; + let ret = Some(self.v.index(&(0..self.size))); + self.v = self.v.index(&(1..)); ret } } @@ -1219,7 +1283,7 @@ impl<'a, T> RandomAccessIterator for Chunks<'a, T> { let mut hi = lo + self.size; if hi < lo || hi > self.v.len() { hi = self.v.len(); } - Some(self.v[lo..hi]) + Some(self.v.index(&(lo..hi))) } else { None } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index a39787b8207..3f8ce000e21 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -23,10 +23,10 @@ use default::Default; use iter::range; use iter::ExactSizeIterator; use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator}; -use kinds::Sized; +use marker::Sized; use mem; use num::Int; -use ops::{Fn, FnMut}; +use ops::{Fn, FnMut, Index}; use option::Option::{self, None, Some}; use ptr::PtrExt; use raw::{Repr, Slice}; @@ -35,9 +35,8 @@ use slice::{self, SliceExt}; use uint; macro_rules! delegate_iter { - (exact $te:ty in $ti:ty) => { - delegate_iter!{$te in $ti} - #[stable] + (exact $te:ty : $ti:ty) => { + delegate_iter!{$te : $ti} impl<'a> ExactSizeIterator for $ti { #[inline] fn len(&self) -> uint { @@ -45,7 +44,7 @@ macro_rules! delegate_iter { } } }; - ($te:ty in $ti:ty) => { + ($te:ty : $ti:ty) => { #[stable] impl<'a> Iterator for $ti { type Item = $te; @@ -67,7 +66,7 @@ macro_rules! delegate_iter { } } }; - (pattern $te:ty in $ti:ty) => { + (pattern $te:ty : $ti:ty) => { #[stable] impl<'a, P: CharEq> Iterator for $ti { type Item = $te; @@ -89,7 +88,7 @@ macro_rules! delegate_iter { } } }; - (pattern forward $te:ty in $ti:ty) => { + (pattern forward $te:ty : $ti:ty) => { #[stable] impl<'a, P: CharEq> Iterator for $ti { type Item = $te; @@ -143,7 +142,7 @@ Section: Creating a string */ /// Errors which can occur when attempting to interpret a byte slice as a `str`. -#[derive(Copy, Eq, PartialEq, Clone)] +#[derive(Copy, Eq, PartialEq, Clone, Show)] #[unstable = "error enumeration recently added and definitions may be refined"] pub enum Utf8Error { /// An invalid byte was detected at the byte offset given. @@ -415,7 +414,7 @@ impl<'a> DoubleEndedIterator for CharIndices<'a> { #[stable] #[derive(Clone)] pub struct Bytes<'a>(Map<&'a u8, u8, slice::Iter<'a, u8>, BytesDeref>); -delegate_iter!{exact u8 in Bytes<'a>} +delegate_iter!{exact u8 : Bytes<'a>} /// A temporary fn new type that ensures that the `Bytes` iterator /// is cloneable. @@ -581,7 +580,7 @@ impl NaiveSearcher { fn next(&mut self, haystack: &[u8], needle: &[u8]) -> Option<(uint, uint)> { while self.position + needle.len() <= haystack.len() { - if haystack[self.position .. self.position + needle.len()] == needle { + if haystack.index(&(self.position .. self.position + needle.len())) == needle { let match_pos = self.position; self.position += needle.len(); // add 1 for all matches return Some((match_pos, match_pos + needle.len())); @@ -702,10 +701,10 @@ impl TwoWaySearcher { // // What's going on is we have some critical factorization (u, v) of the // needle, and we want to determine whether u is a suffix of - // v[..period]. If it is, we use "Algorithm CP1". Otherwise we use + // v.index(&(0..period)). If it is, we use "Algorithm CP1". Otherwise we use // "Algorithm CP2", which is optimized for when the period of the needle // is large. - if needle[..crit_pos] == needle[period.. period + crit_pos] { + if needle.index(&(0..crit_pos)) == needle.index(&(period.. period + crit_pos)) { TwoWaySearcher { crit_pos: crit_pos, period: period, @@ -1119,25 +1118,32 @@ mod traits { } } - impl ops::Slice<uint, str> for str { + impl ops::Index<ops::Range<uint>> for str { + type Output = str; #[inline] - fn as_slice_<'a>(&'a self) -> &'a str { - self + fn index(&self, index: &ops::Range<uint>) -> &str { + self.slice(index.start, index.end) } - + } + impl ops::Index<ops::RangeTo<uint>> for str { + type Output = str; #[inline] - fn slice_from_or_fail<'a>(&'a self, from: &uint) -> &'a str { - self.slice_from(*from) + fn index(&self, index: &ops::RangeTo<uint>) -> &str { + self.slice_to(index.end) } - + } + impl ops::Index<ops::RangeFrom<uint>> for str { + type Output = str; #[inline] - fn slice_to_or_fail<'a>(&'a self, to: &uint) -> &'a str { - self.slice_to(*to) + fn index(&self, index: &ops::RangeFrom<uint>) -> &str { + self.slice_from(index.start) } - + } + impl ops::Index<ops::FullRange> for str { + type Output = str; #[inline] - fn slice_or_fail<'a>(&'a self, from: &uint, to: &uint) -> &'a str { - self.slice(*from, *to) + fn index(&self, _index: &ops::FullRange) -> &str { + self } } } @@ -1165,25 +1171,25 @@ impl<'a, S: ?Sized> Str for &'a S where S: Str { #[derive(Clone)] #[stable] pub struct Split<'a, P>(CharSplits<'a, P>); -delegate_iter!{pattern &'a str in Split<'a, P>} +delegate_iter!{pattern &'a str : Split<'a, P>} /// Return type of `StrExt::split_terminator` #[derive(Clone)] #[unstable = "might get removed in favour of a constructor method on Split"] pub struct SplitTerminator<'a, P>(CharSplits<'a, P>); -delegate_iter!{pattern &'a str in SplitTerminator<'a, P>} +delegate_iter!{pattern &'a str : SplitTerminator<'a, P>} /// Return type of `StrExt::splitn` #[derive(Clone)] #[stable] pub struct SplitN<'a, P>(CharSplitsN<'a, P>); -delegate_iter!{pattern forward &'a str in SplitN<'a, P>} +delegate_iter!{pattern forward &'a str : SplitN<'a, P>} /// Return type of `StrExt::rsplitn` #[derive(Clone)] #[stable] pub struct RSplitN<'a, P>(CharSplitsN<'a, P>); -delegate_iter!{pattern forward &'a str in RSplitN<'a, P>} +delegate_iter!{pattern forward &'a str : RSplitN<'a, P>} /// Methods for string slices #[allow(missing_docs)] @@ -1406,13 +1412,13 @@ impl StrExt for str { #[inline] fn starts_with(&self, needle: &str) -> bool { let n = needle.len(); - self.len() >= n && needle.as_bytes() == self.as_bytes()[..n] + self.len() >= n && needle.as_bytes() == self.as_bytes().index(&(0..n)) } #[inline] fn ends_with(&self, needle: &str) -> bool { let (m, n) = (self.len(), needle.len()); - m >= n && needle.as_bytes() == self.as_bytes()[m-n..] + m >= n && needle.as_bytes() == self.as_bytes().index(&((m-n)..)) } #[inline] diff --git a/src/libcore/ty.rs b/src/libcore/ty.rs index f8e03662b00..35c1cb09281 100644 --- a/src/libcore/ty.rs +++ b/src/libcore/ty.rs @@ -10,4 +10,4 @@ //! Types dealing with unsafe actions. -use kinds::marker; +use marker; |
