about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-24 17:38:09 +0000
committerbors <bors@rust-lang.org>2015-03-24 17:38:09 +0000
commited810385045ab0db90303574ba3ea47dfa2a36d5 (patch)
tree161242c800aca625a26c56551fa5adb446c0089f /src/libcore
parent28a0b25f424090255966273994748a9f9901059f (diff)
parentd252d0ad5434bcf77076729ab766eeff98f20ead (diff)
downloadrust-ed810385045ab0db90303574ba3ea47dfa2a36d5.tar.gz
rust-ed810385045ab0db90303574ba3ea47dfa2a36d5.zip
Auto merge of #23654 - alexcrichton:rollup, r=alexcrichton
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/array.rs2
-rw-r--r--src/libcore/cell.rs1
-rw-r--r--src/libcore/cmp.rs7
-rw-r--r--src/libcore/convert.rs113
-rw-r--r--src/libcore/error.rs16
-rw-r--r--src/libcore/finally.rs2
-rw-r--r--src/libcore/fmt/mod.rs4
-rw-r--r--src/libcore/fmt/num.rs1
-rw-r--r--src/libcore/hash/mod.rs4
-rw-r--r--src/libcore/intrinsics.rs36
-rw-r--r--src/libcore/iter.rs22
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/libcore/macros.rs1
-rw-r--r--src/libcore/marker.rs6
-rw-r--r--src/libcore/num/f32.rs3
-rw-r--r--src/libcore/num/f64.rs3
-rw-r--r--src/libcore/num/mod.rs22
-rw-r--r--src/libcore/ops.rs18
-rw-r--r--src/libcore/option.rs21
-rw-r--r--src/libcore/prelude.rs1
-rw-r--r--src/libcore/ptr.rs31
-rw-r--r--src/libcore/raw.rs2
-rw-r--r--src/libcore/result.rs30
-rw-r--r--src/libcore/simd.rs2
-rw-r--r--src/libcore/slice.rs207
-rw-r--r--src/libcore/str/mod.rs236
-rw-r--r--src/libcore/str/pattern.rs20
27 files changed, 725 insertions, 88 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index edb11df5489..b2c23f051d5 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -14,6 +14,8 @@
 
 #![unstable(feature = "core")] // not yet reviewed
 
+#![doc(primitive = "array")]
+
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
 use fmt;
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index e3a7f23851c..a9c5de23d94 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -220,6 +220,7 @@ impl<T:Copy> Cell<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::cell::Cell;
     ///
     /// let c = Cell::new(5);
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index b37bad5f754..9ab8ab8672d 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -19,7 +19,8 @@
 //! could do the following:
 //!
 //! ```
-//! use core::num::SignedInt;
+//! # #![feature(core)]
+//! use std::num::SignedInt;
 //!
 //! struct FuzzyNum {
 //!     num: i32,
@@ -398,6 +399,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::cmp;
 ///
 /// assert_eq!(Some(1), cmp::partial_min(1, 2));
@@ -407,6 +409,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 /// When comparison is impossible:
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::cmp;
 ///
 /// let result = cmp::partial_min(std::f64::NAN, 1.0);
@@ -429,6 +432,7 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::cmp;
 ///
 /// assert_eq!(Some(2), cmp::partial_max(1, 2));
@@ -438,6 +442,7 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
 /// When comparison is impossible:
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::cmp;
 ///
 /// let result = cmp::partial_max(std::f64::NAN, 1.0);
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
new file mode 100644
index 00000000000..65a226d37cb
--- /dev/null
+++ b/src/libcore/convert.rs
@@ -0,0 +1,113 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Traits for conversions between types.
+//!
+//! The traits in this module provide a general way to talk about
+//! conversions from one type to another. They follow the standard
+//! Rust conventions of `as`/`to`/`into`/`from`.
+
+#![unstable(feature = "convert",
+            reason = "recently added, experimental traits")]
+
+use marker::Sized;
+
+/// A cheap, reference-to-reference conversion.
+pub trait AsRef<T: ?Sized> {
+    /// Perform the conversion.
+    fn as_ref(&self) -> &T;
+}
+
+/// A cheap, mutable reference-to-mutable reference conversion.
+pub trait AsMut<T: ?Sized> {
+    /// Perform the conversion.
+    fn as_mut(&mut self) -> &mut T;
+}
+
+/// A conversion that consumes `self`, which may or may not be
+/// expensive.
+pub trait Into<T>: Sized {
+    /// Perform the conversion.
+    fn into(self) -> T;
+}
+
+/// Construct `Self` via a conversion.
+pub trait From<T> {
+    /// Perform the conversion.
+    fn from(T) -> Self;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// GENERIC IMPLS
+////////////////////////////////////////////////////////////////////////////////
+
+// As implies Into
+impl<'a, T: ?Sized, U: ?Sized> Into<&'a U> for &'a T where T: AsRef<U> {
+    fn into(self) -> &'a U {
+        self.as_ref()
+    }
+}
+
+// As lifts over &
+impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> {
+    fn as_ref(&self) -> &U {
+        <T as AsRef<U>>::as_ref(*self)
+    }
+}
+
+// As lifts over &mut
+impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> {
+    fn as_ref(&self) -> &U {
+        <T as AsRef<U>>::as_ref(*self)
+    }
+}
+
+// AsMut implies Into
+impl<'a, T: ?Sized, U: ?Sized> Into<&'a mut U> for &'a mut T where T: AsMut<U> {
+    fn into(self) -> &'a mut U {
+        (*self).as_mut()
+    }
+}
+
+// AsMut lifts over &mut
+impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> {
+    fn as_mut(&mut self) -> &mut U {
+        (*self).as_mut()
+    }
+}
+
+// From implies Into
+impl<T, U> Into<U> for T where U: From<T> {
+    fn into(self) -> U {
+        U::from(self)
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CONCRETE IMPLS
+////////////////////////////////////////////////////////////////////////////////
+
+impl<T> AsRef<[T]> for [T] {
+    fn as_ref(&self) -> &[T] {
+        self
+    }
+}
+
+impl<T> AsMut<[T]> for [T] {
+    fn as_mut(&mut self) -> &mut [T] {
+        self
+    }
+}
+
+impl AsRef<str> for str {
+    fn as_ref(&self) -> &str {
+        self
+    }
+}
diff --git a/src/libcore/error.rs b/src/libcore/error.rs
index 161f6c78921..d7b4c9411fb 100644
--- a/src/libcore/error.rs
+++ b/src/libcore/error.rs
@@ -48,6 +48,7 @@
 //! For example,
 //!
 //! ```
+//! # #![feature(os, old_io, old_path)]
 //! use std::error::FromError;
 //! use std::old_io::{File, IoError};
 //! use std::os::{MemoryMap, MapError};
@@ -82,16 +83,21 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use prelude::*;
-use fmt::Display;
+use fmt::{Debug, Display};
 
 /// Base functionality for all errors in Rust.
-#[unstable(feature = "core",
-           reason = "the exact API of this trait may change")]
-pub trait Error: Display {
-    /// A short description of the error; usually a static string.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Error: Debug + Display + Send {
+    /// A short description of the error.
+    ///
+    /// The description should not contain newlines or sentence-ending
+    /// punctuation, to facilitate embedding in larger user-facing
+    /// strings.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn description(&self) -> &str;
 
     /// The lower-level cause of this error, if any.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn cause(&self) -> Option<&Error> { None }
 }
 
diff --git a/src/libcore/finally.rs b/src/libcore/finally.rs
index 19cd34cdb09..93a7d2bb17b 100644
--- a/src/libcore/finally.rs
+++ b/src/libcore/finally.rs
@@ -19,6 +19,7 @@
 //! # Examples
 //!
 //! ```
+//! # #![feature(core)]
 //! # #![feature(unboxed_closures)]
 //!
 //! use std::finally::Finally;
@@ -70,6 +71,7 @@ impl<T, F> Finally<T> for F where F: FnMut() -> T {
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::finally::try_finally;
 ///
 /// struct State<'a> { buffer: &'a mut [u8], len: usize }
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 741cf7b47fa..cf427c16588 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -624,6 +624,7 @@ impl<'a> Formatter<'a> {
     /// # Examples
     ///
     /// ```rust
+    /// # #![feature(debug_builders, core)]
     /// use std::fmt;
     ///
     /// struct Foo {
@@ -655,6 +656,7 @@ impl<'a> Formatter<'a> {
     /// # Examples
     ///
     /// ```rust
+    /// # #![feature(debug_builders, core)]
     /// use std::fmt;
     ///
     /// struct Foo(i32, String);
@@ -683,6 +685,7 @@ impl<'a> Formatter<'a> {
     /// # Examples
     ///
     /// ```rust
+    /// # #![feature(debug_builders, core)]
     /// use std::fmt;
     ///
     /// struct Foo(Vec<i32>);
@@ -712,6 +715,7 @@ impl<'a> Formatter<'a> {
     /// # Examples
     ///
     /// ```rust
+    /// # #![feature(debug_builders, core)]
     /// use std::fmt;
     ///
     /// struct Foo(Vec<(String, i32)>);
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index fe22ee60da6..49da99b97cb 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -146,6 +146,7 @@ pub struct RadixFmt<T, R>(T, R);
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::fmt::radix;
 /// assert_eq!(format!("{}", radix(55, 36)), "1j".to_string());
 /// ```
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index fdc0020dfcd..1d5e174a8dc 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -16,6 +16,7 @@
 //! # Examples
 //!
 //! ```rust
+//! # #![feature(hash)]
 //! use std::hash::{hash, Hash, SipHasher};
 //!
 //! #[derive(Hash)]
@@ -35,6 +36,7 @@
 //! the trait `Hash`:
 //!
 //! ```rust
+//! # #![feature(hash)]
 //! use std::hash::{hash, Hash, Hasher, SipHasher};
 //!
 //! struct Person {
@@ -90,7 +92,7 @@ pub trait Hash {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Hasher {
     /// Completes a round of hashing, producing the output hash generated.
-    #[unstable(feature = "hash", reason = "module was recently redesigned")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn finish(&self) -> u64;
 
     /// Writes some data into this `Hasher`
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 1462d07652d..1f1044b0b21 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -44,6 +44,10 @@
 
 use marker::Sized;
 
+#[cfg(stage0)] pub use self::copy_memory as copy;
+#[cfg(stage0)] pub use self::set_memory as write_bytes;
+#[cfg(stage0)] pub use self::copy_nonoverlapping_memory as copy_nonoverlapping;
+
 extern "rust-intrinsic" {
 
     // NB: These intrinsics take unsafe pointers because they mutate aliased
@@ -246,7 +250,7 @@ extern "rust-intrinsic" {
     /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
     /// and destination may *not* overlap.
     ///
-    /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
+    /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`.
     ///
     /// # Safety
     ///
@@ -262,6 +266,7 @@ extern "rust-intrinsic" {
     /// A safe swap function:
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::mem;
     /// use std::ptr;
     ///
@@ -271,9 +276,9 @@ extern "rust-intrinsic" {
     ///         let mut t: T = mem::uninitialized();
     ///
     ///         // Perform the swap, `&mut` pointers never alias
-    ///         ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
-    ///         ptr::copy_nonoverlapping_memory(x, &*y, 1);
-    ///         ptr::copy_nonoverlapping_memory(y, &t, 1);
+    ///         ptr::copy_nonoverlapping(&mut t, &*x, 1);
+    ///         ptr::copy_nonoverlapping(x, &*y, 1);
+    ///         ptr::copy_nonoverlapping(y, &t, 1);
     ///
     ///         // y and t now point to the same thing, but we need to completely forget `tmp`
     ///         // because it's no longer relevant.
@@ -282,12 +287,18 @@ extern "rust-intrinsic" {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(not(stage0))]
+    pub fn copy_nonoverlapping<T>(dst: *mut T, src: *const T, count: usize);
+
+    /// dox
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg(stage0)]
     pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
 
     /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
     /// and destination may overlap.
     ///
-    /// `copy_memory` is semantically equivalent to C's `memmove`.
+    /// `copy` is semantically equivalent to C's `memmove`.
     ///
     /// # Safety
     ///
@@ -301,21 +312,34 @@ extern "rust-intrinsic" {
     /// Efficiently create a Rust vector from an unsafe buffer:
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::ptr;
     ///
     /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
     ///     let mut dst = Vec::with_capacity(elts);
     ///     dst.set_len(elts);
-    ///     ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
+    ///     ptr::copy(dst.as_mut_ptr(), ptr, elts);
     ///     dst
     /// }
     /// ```
     ///
+    #[cfg(not(stage0))]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn copy<T>(dst: *mut T, src: *const T, count: usize);
+
+    /// dox
+    #[cfg(stage0)]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize);
 
     /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
     /// bytes of memory starting at `dst` to `c`.
+    #[cfg(not(stage0))]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
+
+    /// dox
+    #[cfg(stage0)]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn set_memory<T>(dst: *mut T, val: u8, count: usize);
 
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 4f8b1c21ab2..5f5b8ef73ef 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -334,6 +334,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let xs = [100, 200, 300];
     /// let mut it = xs.iter().cloned().peekable();
     /// assert_eq!(*it.peek().unwrap(), 100);
@@ -465,6 +466,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let xs = [2, 3];
     /// let ys = [0, 1, 0, 1, 2];
     /// let it = xs.iter().flat_map(|&x| std::iter::count(0, 1).take(x));
@@ -521,6 +523,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::iter::AdditiveIterator;
     ///
     /// let a = [1, 4, 2, 3, 8, 9, 6];
@@ -563,6 +566,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let b: Vec<_> = a.iter().cloned().collect();
     /// assert_eq!(a, b);
@@ -579,6 +583,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// do not.
     ///
     /// ```
+    /// # #![feature(core)]
     /// let vec = vec![1, 2, 3, 4];
     /// let (even, odd): (Vec<_>, Vec<_>) = vec.into_iter().partition(|&n| n % 2 == 0);
     /// assert_eq!(even, [2, 4]);
@@ -648,6 +653,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter();
     /// assert!(it.any(|x| *x == 3));
@@ -668,6 +674,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter();
     /// assert_eq!(it.find(|&x| *x == 3).unwrap(), &3);
@@ -690,6 +697,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [1, 2, 3, 4, 5];
     /// let mut it = a.iter();
     /// assert_eq!(it.position(|x| *x == 3).unwrap(), 2);
@@ -718,6 +726,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [1, 2, 2, 4, 5];
     /// let mut it = a.iter();
     /// assert_eq!(it.rposition(|x| *x == 2).unwrap(), 2);
@@ -795,6 +804,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax};
     ///
     /// let a: [i32; 0] = [];
@@ -860,7 +870,8 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
-    /// use core::num::SignedInt;
+    /// # #![feature(core)]
+    /// use std::num::SignedInt;
     ///
     /// let a = [-3, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
@@ -890,7 +901,8 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
-    /// use core::num::SignedInt;
+    /// # #![feature(core)]
+    /// use std::num::SignedInt;
     ///
     /// let a = [-3, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
@@ -940,6 +952,7 @@ pub trait IteratorExt: Iterator + Sized {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let a = [(1, 2), (3, 4)];
     /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
     /// assert_eq!([1, 3], left);
@@ -1146,6 +1159,7 @@ pub trait AdditiveIterator<A> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::iter::AdditiveIterator;
     ///
     /// let a = [1, 2, 3, 4, 5];
@@ -1188,6 +1202,7 @@ pub trait MultiplicativeIterator<A> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::iter::{count, MultiplicativeIterator};
     ///
     /// fn factorial(n: usize) -> usize {
@@ -1248,6 +1263,7 @@ impl<T: Clone> MinMaxResult<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::iter::MinMaxResult::{self, NoElements, OneElement, MinMax};
     ///
     /// let r: MinMaxResult<i32> = NoElements;
@@ -2292,6 +2308,7 @@ impl<I: RandomAccessIterator, F> RandomAccessIterator for Inspect<I, F>
 /// An iterator that yields sequential Fibonacci numbers, and stops on overflow.
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::iter::Unfold;
 /// use std::num::Int; // For `.checked_add()`
 ///
@@ -2693,6 +2710,7 @@ pub struct RangeStepInclusive<A> {
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::iter::range_step_inclusive;
 ///
 /// for i in range_step_inclusive(0, 10, 2) {
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 29cc11d5a60..a2b13584270 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -56,6 +56,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
+#![doc(test(no_crate_inject))]
 
 #![feature(no_std)]
 #![no_std]
@@ -125,6 +126,7 @@ pub mod ops;
 pub mod cmp;
 pub mod clone;
 pub mod default;
+pub mod convert;
 
 /* Core types and methods on primitives */
 
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index c647b037944..40e32f4171a 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -231,6 +231,7 @@ macro_rules! writeln {
 /// Iterators:
 ///
 /// ```
+/// # #![feature(core)]
 /// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
 ///     for i in std::iter::count(0, 1) {
 ///         if 3*i < i { panic!("u32 overflow"); }
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 1b866501b8e..88c10e3661e 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -39,6 +39,8 @@ pub unsafe trait Send : MarkerTrait {
     // empty.
 }
 
+unsafe impl Send for .. { }
+
 impl<T> !Send for *const T { }
 impl<T> !Send for *mut T { }
 impl !Send for Managed { }
@@ -203,6 +205,8 @@ pub unsafe trait Sync : MarkerTrait {
     // Empty
 }
 
+unsafe impl Sync for .. { }
+
 impl<T> !Sync for *const T { }
 impl<T> !Sync for *mut T { }
 impl !Sync for Managed { }
@@ -270,6 +274,7 @@ macro_rules! impls{
 /// any methods, but instead is used to gate access to data.
 ///
 /// FIXME. Better documentation needed here!
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait MarkerTrait : PhantomFn<Self,Self> { }
 //                                    ~~~~~ <-- FIXME(#22806)?
 //
@@ -319,6 +324,7 @@ impl<T:?Sized> MarkerTrait for T { }
 /// `MarkerTrait`:
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::marker::MarkerTrait;
 /// trait Even : MarkerTrait { }
 /// ```
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index ae1b5f65eeb..d211b0f9928 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -282,7 +282,8 @@ impl Float for f32 {
     /// The fractional part of the number, satisfying:
     ///
     /// ```
-    /// use core::num::Float;
+    /// # #![feature(core)]
+    /// use std::num::Float;
     ///
     /// let x = 1.65f32;
     /// assert!(x == x.trunc() + x.fract())
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 4a73c1e8fcf..1421fdd72f2 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -289,7 +289,8 @@ impl Float for f64 {
     /// The fractional part of the number, satisfying:
     ///
     /// ```
-    /// use core::num::Float;
+    /// # #![feature(core)]
+    /// use std::num::Float;
     ///
     /// let x = 1.65f64;
     /// assert!(x == x.trunc() + x.fract())
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 17ef0ecb1c0..9ca7b48fbe5 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -85,6 +85,7 @@ pub trait Int
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0b01001100u8;
@@ -100,6 +101,7 @@ pub trait Int
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0b01001100u8;
@@ -119,6 +121,7 @@ pub trait Int
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0b0101000u16;
@@ -135,6 +138,7 @@ pub trait Int
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0b0101000u16;
@@ -151,6 +155,7 @@ pub trait Int
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0x0123456789ABCDEFu64;
@@ -168,6 +173,7 @@ pub trait Int
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// let n = 0x0123456789ABCDEFu64;
@@ -392,6 +398,7 @@ pub trait Int
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// use std::num::Int;
     ///
     /// assert_eq!(2.pow(4), 16);
@@ -787,6 +794,7 @@ macro_rules! int_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0b01001100u8;
@@ -803,6 +811,7 @@ macro_rules! int_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0b01001100u8;
@@ -822,6 +831,7 @@ macro_rules! int_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0b0101000u16;
@@ -841,6 +851,7 @@ macro_rules! int_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0b0101000u16;
@@ -860,6 +871,7 @@ macro_rules! int_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0x0123456789ABCDEFu64;
@@ -881,6 +893,7 @@ macro_rules! int_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0x0123456789ABCDEFu64;
@@ -1112,6 +1125,7 @@ macro_rules! int_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// assert_eq!(2.pow(4), 16);
@@ -1277,6 +1291,7 @@ macro_rules! uint_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0b01001100u8;
@@ -1295,6 +1310,7 @@ macro_rules! uint_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0b01001100u8;
@@ -1314,6 +1330,7 @@ macro_rules! uint_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0b0101000u16;
@@ -1333,6 +1350,7 @@ macro_rules! uint_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0b0101000u16;
@@ -1352,6 +1370,7 @@ macro_rules! uint_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0x0123456789ABCDEFu64;
@@ -1375,6 +1394,7 @@ macro_rules! uint_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// let n = 0x0123456789ABCDEFu64;
@@ -1606,6 +1626,7 @@ macro_rules! uint_impl {
         /// # Examples
         ///
         /// ```rust
+        /// # #![feature(core)]
         /// use std::num::Int;
         ///
         /// assert_eq!(2.pow(4), 16);
@@ -2266,6 +2287,7 @@ impl_from_primitive! { f64, to_f64 }
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::num;
 ///
 /// let twenty: f32 = num::cast(0x14).unwrap();
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 6324e8fa874..6e6f97a7af7 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -898,7 +898,7 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
 /// impl Index<Bar> for Foo {
 ///     type Output = Foo;
 ///
-///     fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
+///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
 ///         println!("Indexing!");
 ///         self
 ///     }
@@ -917,8 +917,14 @@ pub trait Index<Idx: ?Sized> {
     type Output: ?Sized;
 
     /// The method for the indexing (`Foo[Bar]`) operation
+    #[cfg(stage0)]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn index<'a>(&'a self, index: &Idx) -> &'a Self::Output;
+
+    /// The method for the indexing (`Foo[Bar]`) operation
+    #[cfg(not(stage0))]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
 }
 
 /// The `IndexMut` trait is used to specify the functionality of indexing
@@ -939,13 +945,13 @@ pub trait Index<Idx: ?Sized> {
 /// impl Index<Bar> for Foo {
 ///     type Output = Foo;
 ///
-///     fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
+///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
 ///         self
 ///     }
 /// }
 ///
 /// impl IndexMut<Bar> for Foo {
-///     fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo {
+///     fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
 ///         println!("Indexing!");
 ///         self
 ///     }
@@ -960,8 +966,14 @@ pub trait Index<Idx: ?Sized> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
     /// The method for the indexing (`Foo[Bar]`) operation
+    #[cfg(stage0)]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn index_mut<'a>(&'a mut self, index: &Idx) -> &'a mut Self::Output;
+
+    /// The method for the indexing (`Foo[Bar]`) operation
+    #[cfg(not(stage0))]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn index_mut<'a>(&'a mut self, index: Idx) -> &'a mut Self::Output;
 }
 
 /// An unbounded range.
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 455c68d4319..a565b137cc8 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -154,6 +154,7 @@ use mem;
 use ops::{Deref, FnOnce};
 use result::Result::{Ok, Err};
 use result::Result;
+#[allow(deprecated)]
 use slice::AsSlice;
 use slice;
 
@@ -275,6 +276,7 @@ impl<T> Option<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let mut x = Some("Diamonds");
     /// {
     ///     let v = x.as_mut_slice();
@@ -470,6 +472,7 @@ impl<T> Option<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let x = Some("foo");
     /// assert_eq!(x.ok_or(0), Ok("foo"));
     ///
@@ -491,6 +494,7 @@ impl<T> Option<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let x = Some("foo");
     /// assert_eq!(x.ok_or_else(|| 0), Ok("foo"));
     ///
@@ -532,6 +536,7 @@ impl<T> Option<T> {
     /// # Examples
     ///
     /// ```
+    /// # #![feature(core)]
     /// let mut x = Some(4);
     /// match x.iter_mut().next() {
     ///     Some(&mut ref mut v) => *v = 42,
@@ -701,6 +706,19 @@ impl<T> Option<T> {
     pub fn take(&mut self) -> Option<T> {
         mem::replace(self, None)
     }
+
+    /// Convert from `Option<T>` to `&[T]` (without copying)
+    #[inline]
+    #[unstable(feature = "as_slice", since = "unsure of the utility here")]
+    pub fn as_slice<'a>(&'a self) -> &'a [T] {
+        match *self {
+            Some(ref x) => slice::ref_slice(x),
+            None => {
+                let result: &[_] = &[];
+                result
+            }
+        }
+    }
 }
 
 impl<'a, T: Clone, D: Deref<Target=T>> Option<D> {
@@ -752,6 +770,9 @@ impl<T: Default> Option<T> {
 
 #[unstable(feature = "core",
            reason = "waiting on the stability of the trait itself")]
+#[deprecated(since = "1.0.0",
+             reason = "use the inherent method instead")]
+#[allow(deprecated)]
 impl<T> AsSlice<T> for Option<T> {
     /// Convert from `Option<T>` to `&[T]` (without copying)
     #[inline]
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index 4bf7f85284c..424829939b9 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -36,6 +36,7 @@ pub use mem::drop;
 pub use char::CharExt;
 pub use clone::Clone;
 pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
+pub use convert::{AsRef, AsMut, Into, From};
 pub use iter::{Extend, IteratorExt};
 pub use iter::{Iterator, DoubleEndedIterator};
 pub use iter::{ExactSizeIterator};
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 1cbea057e88..d92622eeb70 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -15,12 +15,9 @@
 //! Working with unsafe pointers in Rust is uncommon,
 //! typically limited to a few patterns.
 //!
-//! Use the [`null` function](fn.null.html) to create null pointers,
-//! the [`is_null`](trait.PtrExt.html#tymethod.is_null)
-//! methods of the [`PtrExt` trait](trait.PtrExt.html) to check for null.
-//! The `PtrExt` trait is imported by the prelude, so `is_null` etc.
-//! work everywhere. The `PtrExt` also defines the `offset` method,
-//! for pointer math.
+//! Use the [`null` function](fn.null.html) to create null pointers, and
+//! the `is_null` method of the `*const T` type  to check for null.
+//! The `*const T` type also defines the `offset` method, for pointer math.
 //!
 //! # Common ways to create unsafe pointers
 //!
@@ -52,6 +49,7 @@
 //! the raw pointer. It doesn't destroy `T` or deallocate any memory.
 //!
 //! ```
+//! # #![feature(alloc)]
 //! use std::boxed;
 //!
 //! unsafe {
@@ -70,6 +68,7 @@
 //! ## 3. Get it from C.
 //!
 //! ```
+//! # #![feature(libc)]
 //! extern crate libc;
 //!
 //! use std::mem;
@@ -105,27 +104,13 @@ use cmp::Ordering::{self, Less, Equal, Greater};
 // FIXME #19649: intrinsic docs don't render, so these have no docs :(
 
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use intrinsics::copy_nonoverlapping_memory as copy_nonoverlapping;
+pub use intrinsics::copy_nonoverlapping;
 
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use intrinsics::copy_memory as copy;
+pub use intrinsics::copy;
 
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use intrinsics::set_memory as write_bytes;
-
-extern "rust-intrinsic" {
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0", reason = "renamed to `copy_nonoverlapping`")]
-    pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
-    #[unstable(feature = "core")]
-    #[deprecated(since = "1.0.0", reason = "renamed to `copy`")]
-    pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize);
-
-    #[unstable(feature = "core",
-               reason = "uncertain about naming and semantics")]
-    #[deprecated(since = "1.0.0", reason = "renamed to `write_bytes`")]
-    pub fn set_memory<T>(dst: *mut T, val: u8, count: usize);
-}
+pub use intrinsics::write_bytes;
 
 /// Creates a null raw pointer.
 ///
diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs
index 35dfc762687..8502a9c53c4 100644
--- a/src/libcore/raw.rs
+++ b/src/libcore/raw.rs
@@ -48,6 +48,7 @@ use mem;
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::raw::{self, Repr};
 ///
 /// let slice: &[u16] = &[1, 2, 3, 4];
@@ -106,6 +107,7 @@ pub struct Closure {
 /// # Examples
 ///
 /// ```
+/// # #![feature(core)]
 /// use std::mem;
 /// use std::raw;
 ///
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index bc8d53e2a57..62e1bcd827a 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -95,6 +95,7 @@
 //! by the [`Writer`](../io/trait.Writer.html) trait:
 //!
 //! ```
+//! # #![feature(old_io)]
 //! use std::old_io::IoError;
 //!
 //! trait Writer {
@@ -110,6 +111,7 @@
 //! something like this:
 //!
 //! ```{.ignore}
+//! # #![feature(old_io)]
 //! use std::old_io::*;
 //! use std::old_path::Path;
 //!
@@ -129,6 +131,7 @@
 //! a marginally useful message indicating why:
 //!
 //! ```{.no_run}
+//! # #![feature(old_io, old_path)]
 //! use std::old_io::*;
 //! use std::old_path::Path;
 //!
@@ -140,6 +143,7 @@
 //! You might also simply assert success:
 //!
 //! ```{.no_run}
+//! # #![feature(old_io, old_path)]
 //! # use std::old_io::*;
 //! # use std::old_path::Path;
 //!
@@ -151,6 +155,7 @@
 //! Or propagate the error up the call stack with `try!`:
 //!
 //! ```
+//! # #![feature(old_io, old_path)]
 //! # use std::old_io::*;
 //! # use std::old_path::Path;
 //! fn write_message() -> Result<(), IoError> {
@@ -171,6 +176,7 @@
 //! It replaces this:
 //!
 //! ```
+//! # #![feature(old_io, old_path)]
 //! use std::old_io::*;
 //! use std::old_path::Path;
 //!
@@ -196,6 +202,7 @@
 //! With this:
 //!
 //! ```
+//! # #![feature(old_io, old_path)]
 //! use std::old_io::*;
 //! use std::old_path::Path;
 //!
@@ -240,6 +247,7 @@ use iter::{Iterator, IteratorExt, DoubleEndedIterator,
            FromIterator, ExactSizeIterator, IntoIterator};
 use ops::{FnMut, FnOnce};
 use option::Option::{self, None, Some};
+#[allow(deprecated)]
 use slice::AsSlice;
 use slice;
 
@@ -408,9 +416,24 @@ impl<T, E> Result<T, E> {
         }
     }
 
+    /// Convert from `Result<T, E>` to `&[T]` (without copying)
+    #[inline]
+    #[unstable(feature = "as_slice", since = "unsure of the utility here")]
+    pub fn as_slice(&self) -> &[T] {
+        match *self {
+            Ok(ref x) => slice::ref_slice(x),
+            Err(_) => {
+                // work around lack of implicit coercion from fixed-size array to slice
+                let emp: &[_] = &[];
+                emp
+            }
+        }
+    }
+
     /// Convert from `Result<T, E>` to `&mut [T]` (without copying)
     ///
     /// ```
+    /// # #![feature(core)]
     /// let mut x: Result<&str, u32> = Ok("Gold");
     /// {
     ///     let v = x.as_mut_slice();
@@ -452,6 +475,7 @@ impl<T, E> Result<T, E> {
     /// ignoring I/O and parse errors:
     ///
     /// ```
+    /// # #![feature(old_io)]
     /// use std::old_io::*;
     ///
     /// let mut buffer: &[u8] = b"1\n2\n3\n4\n";
@@ -788,10 +812,14 @@ impl<T: fmt::Debug, E> Result<T, E> {
 // Trait implementations
 /////////////////////////////////////////////////////////////////////////////
 
+#[unstable(feature = "core",
+           reason = "waiting on the stability of the trait itself")]
+#[deprecated(since = "1.0.0",
+             reason = "use inherent method instead")]
+#[allow(deprecated)]
 impl<T, E> AsSlice<T> for Result<T, E> {
     /// Convert from `Result<T, E>` to `&[T]` (without copying)
     #[inline]
-    #[stable(feature = "rust1", since = "1.0.0")]
     fn as_slice<'a>(&'a self) -> &'a [T] {
         match *self {
             Ok(ref x) => slice::ref_slice(x),
diff --git a/src/libcore/simd.rs b/src/libcore/simd.rs
index 0058971faf0..21cff3021ab 100644
--- a/src/libcore/simd.rs
+++ b/src/libcore/simd.rs
@@ -19,7 +19,7 @@
 //! provided beyond this module.
 //!
 //! ```rust
-//!
+//! # #![feature(core)]
 //! fn main() {
 //!     use std::simd::f32x4;
 //!     let a = f32x4(40.0, 41.0, 42.0, 43.0);
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 907b2eba80c..fce29abed73 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -263,6 +263,7 @@ impl<T> SliceExt for [T] {
     #[inline]
     fn as_mut_slice(&mut self) -> &mut [T] { self }
 
+    #[cfg(stage0)]
     #[inline]
     fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
         unsafe {
@@ -273,6 +274,17 @@ impl<T> SliceExt for [T] {
         }
     }
 
+    #[cfg(not(stage0))]
+    #[inline]
+    fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
+        unsafe {
+            let self2: &mut [T] = mem::transmute_copy(&self);
+
+            (ops::IndexMut::index_mut(self, ops::RangeTo { end: mid } ),
+             ops::IndexMut::index_mut(self2, ops::RangeFrom { start: mid } ))
+        }
+    }
+
     #[inline]
     fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
         unsafe {
@@ -495,25 +507,45 @@ impl<T> SliceExt for [T] {
 impl<T> ops::Index<usize> for [T] {
     type Output = T;
 
+    #[cfg(stage0)]
     fn index(&self, &index: &usize) -> &T {
         assert!(index < self.len());
 
         unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
     }
+
+    #[cfg(not(stage0))]
+    fn index(&self, index: usize) -> &T {
+        assert!(index < self.len());
+
+        unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<usize> for [T] {
+    #[cfg(stage0)]
+    #[inline]
     fn index_mut(&mut self, &index: &usize) -> &mut T {
         assert!(index < self.len());
 
         unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: usize) -> &mut T {
+        assert!(index < self.len());
+
+        unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::Range<usize>> for [T] {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::Range<usize>) -> &[T] {
         assert!(index.start <= index.end);
@@ -525,34 +557,72 @@ impl<T> ops::Index<ops::Range<usize>> for [T] {
             )
         }
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
+        assert!(index.start <= index.end);
+        assert!(index.end <= self.len());
+        unsafe {
+            from_raw_parts (
+                self.as_ptr().offset(index.start as isize),
+                index.end - index.start
+            )
+        }
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::RangeTo<usize>> for [T] {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
         self.index(&ops::Range{ start: 0, end: index.end })
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
+        self.index(ops::Range{ start: 0, end: index.end })
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<ops::RangeFrom<usize>> for [T] {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
         self.index(&ops::Range{ start: index.start, end: self.len() })
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
+        self.index(ops::Range{ start: index.start, end: self.len() })
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::Index<RangeFull> for [T] {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, _index: &RangeFull) -> &[T] {
         self
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, _index: RangeFull) -> &[T] {
+        self
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
         assert!(index.start <= index.end);
@@ -564,28 +634,64 @@ impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
             )
         }
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
+        assert!(index.start <= index.end);
+        assert!(index.end <= self.len());
+        unsafe {
+            from_raw_parts_mut(
+                self.as_mut_ptr().offset(index.start as isize),
+                index.end - index.start
+            )
+        }
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeTo<usize>> for [T] {
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
         self.index_mut(&ops::Range{ start: 0, end: index.end })
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
+        self.index_mut(ops::Range{ start: 0, end: index.end })
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<ops::RangeFrom<usize>> for [T] {
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
         let len = self.len();
         self.index_mut(&ops::Range{ start: index.start, end: len })
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
+        let len = self.len();
+        self.index_mut(ops::Range{ start: index.start, end: len })
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> ops::IndexMut<RangeFull> for [T] {
+
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
         self
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
+        self
+    }
 }
 
 
@@ -596,24 +702,29 @@ impl<T> ops::IndexMut<RangeFull> for [T] {
 /// Data that is viewable as a slice.
 #[unstable(feature = "core",
            reason = "will be replaced by slice syntax")]
+#[deprecated(since = "1.0.0",
+             reason = "use std::convert::AsRef<[T]> instead")]
 pub trait AsSlice<T> {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a [T];
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
+#[allow(deprecated)]
 impl<T> AsSlice<T> for [T] {
     #[inline(always)]
     fn as_slice<'a>(&'a self) -> &'a [T] { self }
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
+#[allow(deprecated)]
 impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a U {
     #[inline(always)]
     fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
 }
 
 #[unstable(feature = "core", reason = "trait is experimental")]
+#[allow(deprecated)]
 impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a mut U {
     #[inline(always)]
     fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
@@ -763,37 +874,69 @@ unsafe impl<'a, T: Sync> Send for Iter<'a, T> {}
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::Range<usize>> for Iter<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::Range<usize>) -> &[T] {
         self.as_slice().index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
+        self.as_slice().index(index)
+    }
 }
 
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeTo<usize>> for Iter<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
         self.as_slice().index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
+        self.as_slice().index(index)
+    }
 }
 
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeFrom<usize>> for Iter<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
         self.as_slice().index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
+        self.as_slice().index(index)
+    }
 }
 
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<RangeFull> for Iter<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, _index: &RangeFull) -> &[T] {
         self.as_slice()
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, _index: RangeFull) -> &[T] {
+        self.as_slice()
+    }
 }
 
 impl<'a, T> Iter<'a, T> {
@@ -856,63 +999,126 @@ unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::Range<usize>> for IterMut<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::Range<usize>) -> &[T] {
         self.index(&RangeFull).index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::Range<usize>) -> &[T] {
+        self.index(RangeFull).index(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeTo<usize>> for IterMut<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
         self.index(&RangeFull).index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
+        self.index(RangeFull).index(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<ops::RangeFrom<usize>> for IterMut<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
         self.index(&RangeFull).index(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
+        self.index(RangeFull).index(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::Index<RangeFull> for IterMut<'a, T> {
     type Output = [T];
+
+    #[cfg(stage0)]
     #[inline]
     fn index(&self, _index: &RangeFull) -> &[T] {
         make_slice!(T => &[T]: self.ptr, self.end)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index(&self, _index: RangeFull) -> &[T] {
+        make_slice!(T => &[T]: self.ptr, self.end)
+    }
 }
 
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<ops::Range<usize>> for IterMut<'a, T> {
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
         self.index_mut(&RangeFull).index_mut(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
+        self.index_mut(RangeFull).index_mut(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<ops::RangeTo<usize>> for IterMut<'a, T> {
+
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
         self.index_mut(&RangeFull).index_mut(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
+        self.index_mut(RangeFull).index_mut(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<ops::RangeFrom<usize>> for IterMut<'a, T> {
+
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
         self.index_mut(&RangeFull).index_mut(index)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
+        self.index_mut(RangeFull).index_mut(index)
+    }
 }
 #[unstable(feature = "core")]
 impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> {
+
+    #[cfg(stage0)]
     #[inline]
     fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
         make_mut_slice!(T => &mut [T]: self.ptr, self.end)
     }
+
+    #[cfg(not(stage0))]
+    #[inline]
+    fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
+        make_mut_slice!(T => &mut [T]: self.ptr, self.end)
+    }
 }
 
 
@@ -1491,6 +1697,7 @@ pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
 /// # Examples
 ///
 /// ```
+/// #![feature(core)]
 /// use std::slice;
 ///
 /// // manifest a slice out of thin air!
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index e8181395b5c..b7285d30a73 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -111,7 +111,24 @@ macro_rules! delegate_iter {
                 self.0.size_hint()
             }
         }
-    }
+    };
+    (pattern reverse $te:ty : $ti:ty) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a, P: Pattern<'a>> Iterator for $ti
+            where P::Searcher: ReverseSearcher<'a>
+        {
+            type Item = $te;
+
+            #[inline]
+            fn next(&mut self) -> Option<$te> {
+                self.0.next()
+            }
+            #[inline]
+            fn size_hint(&self) -> (usize, Option<usize>) {
+                self.0.size_hint()
+            }
+        }
+    };
 }
 
 /// A trait to abstract the idea of creating a new instance of a type from a
@@ -550,7 +567,26 @@ struct CharSplitsN<'a, P: Pattern<'a>> {
     iter: CharSplits<'a, P>,
     /// The number of splits remaining
     count: usize,
-    invert: bool,
+}
+
+/// An iterator over the substrings of a string, separated by a
+/// pattern, in reverse order.
+struct RCharSplits<'a, P: Pattern<'a>> {
+    /// The slice remaining to be iterated
+    start: usize,
+    end: usize,
+    matcher: P::Searcher,
+    /// Whether an empty string at the end of iteration is allowed
+    allow_final_empty: bool,
+    finished: bool,
+}
+
+/// An iterator over the substrings of a string, separated by a
+/// pattern, splitting at most `count` times, in reverse order.
+struct RCharSplitsN<'a, P: Pattern<'a>> {
+    iter: RCharSplits<'a, P>,
+    /// The number of splits remaining
+    count: usize,
 }
 
 /// An iterator over the lines of a string, separated by `\n`.
@@ -631,21 +667,74 @@ where P::Searcher: DoubleEndedSearcher<'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P>
-where P::Searcher: DoubleEndedSearcher<'a> {
+impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P> {
     type Item = &'a str;
 
     #[inline]
     fn next(&mut self) -> Option<&'a str> {
         if self.count != 0 {
             self.count -= 1;
-            if self.invert { self.iter.next_back() } else { self.iter.next() }
+            self.iter.next()
         } else {
             self.iter.get_end()
         }
     }
 }
 
+impl<'a, P: Pattern<'a>> RCharSplits<'a, P> {
+    #[inline]
+    fn get_remainder(&mut self) -> Option<&'a str> {
+        if !self.finished && (self.allow_final_empty || self.end - self.start > 0) {
+            self.finished = true;
+            unsafe {
+                let string = self.matcher.haystack().slice_unchecked(self.start, self.end);
+                Some(string)
+            }
+        } else {
+            None
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, P: Pattern<'a>> Iterator for RCharSplits<'a, P>
+    where P::Searcher: ReverseSearcher<'a>
+{
+    type Item = &'a str;
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a str> {
+        if self.finished { return None }
+
+        let haystack = self.matcher.haystack();
+        match self.matcher.next_match_back() {
+            Some((a, b)) => unsafe {
+                let elt = haystack.slice_unchecked(b, self.end);
+                self.end = a;
+                Some(elt)
+            },
+            None => self.get_remainder(),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, P: Pattern<'a>> Iterator for RCharSplitsN<'a, P>
+    where P::Searcher: ReverseSearcher<'a>
+{
+    type Item = &'a str;
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a str> {
+        if self.count != 0 {
+            self.count -= 1;
+            self.iter.next()
+        } else {
+            self.iter.get_remainder()
+        }
+    }
+}
+
 /// The internal state of an iterator that searches for matches of a substring
 /// within a larger string using two-way search
 #[derive(Clone)]
@@ -1203,6 +1292,7 @@ mod traits {
     /// // byte 100 is outside the string
     /// // &s[3 .. 100];
     /// ```
+    #[cfg(stage0)]
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::Range<usize>> for str {
         type Output = str;
@@ -1219,6 +1309,49 @@ mod traits {
         }
     }
 
+    /// Returns a slice of the given string from the byte range
+    /// [`begin`..`end`).
+    ///
+    /// This operation is `O(1)`.
+    ///
+    /// Panics when `begin` and `end` do not point to valid characters
+    /// or point beyond the last character of the string.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    /// assert_eq!(&s[0 .. 1], "L");
+    ///
+    /// assert_eq!(&s[1 .. 9], "öwe 老");
+    ///
+    /// // these will panic:
+    /// // byte 2 lies within `ö`:
+    /// // &s[2 ..3];
+    ///
+    /// // byte 8 lies within `老`
+    /// // &s[1 .. 8];
+    ///
+    /// // byte 100 is outside the string
+    /// // &s[3 .. 100];
+    /// ```
+    #[cfg(not(stage0))]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl ops::Index<ops::Range<usize>> for str {
+        type Output = str;
+        #[inline]
+        fn index(&self, index: ops::Range<usize>) -> &str {
+            // is_char_boundary checks that the index is in [0, .len()]
+            if index.start <= index.end &&
+               self.is_char_boundary(index.start) &&
+               self.is_char_boundary(index.end) {
+                unsafe { self.slice_unchecked(index.start, index.end) }
+            } else {
+                super::slice_error_fail(self, index.start, index.end)
+            }
+        }
+    }
+
     /// Returns a slice of the string from the beginning to byte
     /// `end`.
     ///
@@ -1229,6 +1362,8 @@ mod traits {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::RangeTo<usize>> for str {
         type Output = str;
+
+        #[cfg(stage0)]
         #[inline]
         fn index(&self, index: &ops::RangeTo<usize>) -> &str {
             // is_char_boundary checks that the index is in [0, .len()]
@@ -1238,6 +1373,17 @@ mod traits {
                 super::slice_error_fail(self, 0, index.end)
             }
         }
+
+        #[cfg(not(stage0))]
+        #[inline]
+        fn index(&self, index: ops::RangeTo<usize>) -> &str {
+            // is_char_boundary checks that the index is in [0, .len()]
+            if self.is_char_boundary(index.end) {
+                unsafe { self.slice_unchecked(0, index.end) }
+            } else {
+                super::slice_error_fail(self, 0, index.end)
+            }
+        }
     }
 
     /// Returns a slice of the string from `begin` to its end.
@@ -1249,6 +1395,8 @@ mod traits {
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::RangeFrom<usize>> for str {
         type Output = str;
+
+        #[cfg(stage0)]
         #[inline]
         fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
             // is_char_boundary checks that the index is in [0, .len()]
@@ -1258,15 +1406,34 @@ mod traits {
                 super::slice_error_fail(self, index.start, self.len())
             }
         }
+
+        #[cfg(not(stage0))]
+        #[inline]
+        fn index(&self, index: ops::RangeFrom<usize>) -> &str {
+            // is_char_boundary checks that the index is in [0, .len()]
+            if self.is_char_boundary(index.start) {
+                unsafe { self.slice_unchecked(index.start, self.len()) }
+            } else {
+                super::slice_error_fail(self, index.start, self.len())
+            }
+        }
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
     impl ops::Index<ops::RangeFull> for str {
         type Output = str;
+
+        #[cfg(stage0)]
         #[inline]
         fn index(&self, _index: &ops::RangeFull) -> &str {
             self
         }
+
+        #[cfg(not(stage0))]
+        #[inline]
+        fn index(&self, _index: ops::RangeFull) -> &str {
+            self
+        }
     }
 }
 
@@ -1275,16 +1442,20 @@ mod traits {
            reason = "Instead of taking this bound generically, this trait will be \
                      replaced with one of slicing syntax (&foo[..]), deref coercions, or \
                      a more generic conversion trait")]
+#[deprecated(since = "1.0.0",
+             reason = "use std::convert::AsRef<str> instead")]
 pub trait Str {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a str;
 }
 
+#[allow(deprecated)]
 impl Str for str {
     #[inline]
     fn as_slice<'a>(&'a self) -> &'a str { self }
 }
 
+#[allow(deprecated)]
 impl<'a, S: ?Sized> Str for &'a S where S: Str {
     #[inline]
     fn as_slice(&self) -> &str { Str::as_slice(*self) }
@@ -1293,23 +1464,7 @@ impl<'a, S: ?Sized> Str for &'a S where S: Str {
 /// Return type of `StrExt::split`
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Split<'a, P: Pattern<'a>>(CharSplits<'a, P>);
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, P: Pattern<'a>> Iterator for Split<'a, P> {
-    type Item = &'a str;
-
-    #[inline]
-    fn next(&mut self) -> Option<&'a str> {
-        self.0.next()
-    }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, P: Pattern<'a>> DoubleEndedIterator for Split<'a, P>
-where P::Searcher: DoubleEndedSearcher<'a> {
-    #[inline]
-    fn next_back(&mut self) -> Option<&'a str> {
-        self.0.next_back()
-    }
-}
+delegate_iter!{pattern &'a str : Split<'a, P>}
 
 /// Return type of `StrExt::split_terminator`
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1321,10 +1476,15 @@ delegate_iter!{pattern &'a str : SplitTerminator<'a, P>}
 pub struct SplitN<'a, P: Pattern<'a>>(CharSplitsN<'a, P>);
 delegate_iter!{pattern forward &'a str : SplitN<'a, P>}
 
+/// Return type of `StrExt::rsplit`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct RSplit<'a, P: Pattern<'a>>(RCharSplits<'a, P>);
+delegate_iter!{pattern reverse &'a str : RSplit<'a, P>}
+
 /// Return type of `StrExt::rsplitn`
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct RSplitN<'a, P: Pattern<'a>>(CharSplitsN<'a, P>);
-delegate_iter!{pattern forward &'a str : RSplitN<'a, P>}
+pub struct RSplitN<'a, P: Pattern<'a>>(RCharSplitsN<'a, P>);
+delegate_iter!{pattern reverse &'a str : RSplitN<'a, P>}
 
 /// Methods for string slices
 #[allow(missing_docs)]
@@ -1340,7 +1500,10 @@ pub trait StrExt {
     fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P>;
     fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P>;
     fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
-    fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>;
+    fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
+        where P::Searcher: ReverseSearcher<'a>;
+    fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
+        where P::Searcher: ReverseSearcher<'a>;
     fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
     #[allow(deprecated) /* for SplitStr */]
     fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P>;
@@ -1424,7 +1587,6 @@ impl StrExt for str {
         SplitN(CharSplitsN {
             iter: self.split(pat).0,
             count: count,
-            invert: false,
         })
     }
 
@@ -1437,11 +1599,25 @@ impl StrExt for str {
     }
 
     #[inline]
-    fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> {
-        RSplitN(CharSplitsN {
-            iter: self.split(pat).0,
+    fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        RSplit(RCharSplits {
+            start: 0,
+            end: self.len(),
+            matcher: pat.into_searcher(self),
+            allow_final_empty: true,
+            finished: false,
+        })
+    }
+
+    #[inline]
+    fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        RSplitN(RCharSplitsN {
+            iter: self.rsplit(pat).0,
             count: count,
-            invert: true,
         })
     }
 
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index 7bf248917a5..98b6533980d 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -474,22 +474,16 @@ impl<'a, 'b> Pattern<'a> for &'b [char] {
                       s, CharEqPattern(s));
 }
 
+/// A convenience impl that delegates to the impl for `&str`
+impl<'a, 'b> Pattern<'a> for &'b &'b str {
+    type Searcher =   <&'b str as Pattern<'a>>::Searcher;
+    associated_items!(<&'b str as Pattern<'a>>::Searcher,
+                      s, (*s));
+}
+
 /// Searches for chars that match the given predicate
 impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool {
     type Searcher =   <CharEqPattern<Self> as Pattern<'a>>::Searcher;
     associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
                       s, CharEqPattern(s));
 }
-
-// Deref-forward impl
-
-use ops::Deref;
-
-/// Delegates to the next deref coercion of `Self` that implements `Pattern`
-impl<'a, 'b, P: 'b + ?Sized, T: Deref<Target = P> + ?Sized> Pattern<'a> for &'b T
-    where &'b P: Pattern<'a>
-{
-    type Searcher =   <&'b P as Pattern<'a>>::Searcher;
-    associated_items!(<&'b P as Pattern<'a>>::Searcher,
-                      s, (&**s));
-}