about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2017-04-04 08:10:22 -0700
committerEsteban Küber <esteban@kuber.com.ar>2017-04-04 08:13:27 -0700
commitdedb7bbbbf272226f327b8cda8aaa12cf6325eca (patch)
tree9c7c7b656750a53b5ca4f7646ee1dfe60829b271 /src/libcore
parentb477682dca3343eb89a467f0d3c73986a53d49d9 (diff)
parent5309a3e31d88def1f3ea966162ed4f81f161d500 (diff)
downloadrust-dedb7bbbbf272226f327b8cda8aaa12cf6325eca.tar.gz
rust-dedb7bbbbf272226f327b8cda8aaa12cf6325eca.zip
Merge branch 'master' into issue-32540
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/char.rs2
-rw-r--r--src/libcore/cmp.rs44
-rw-r--r--src/libcore/iter/traits.rs6
-rw-r--r--src/libcore/macros.rs54
-rw-r--r--src/libcore/num/dec2flt/algorithm.rs4
-rw-r--r--src/libcore/ops.rs44
-rw-r--r--src/libcore/result.rs2
-rw-r--r--src/libcore/slice/mod.rs52
-rw-r--r--src/libcore/slice/sort.rs62
-rw-r--r--src/libcore/str/mod.rs398
-rw-r--r--src/libcore/sync/atomic.rs66
11 files changed, 564 insertions, 170 deletions
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 19e69ca296d..b27c801cf89 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -187,7 +187,7 @@ impl From<char> for u32 {
 /// with the character encoding that IANA calls ISO-8859-1.
 /// This encoding is compatible with ASCII.
 ///
-/// Note that this is different from ISO/IEC 8859-1 a.k.a. ISO 8859-1 (with one less hypen),
+/// Note that this is different from ISO/IEC 8859-1 a.k.a. ISO 8859-1 (with one less hyphen),
 /// which leaves some "blanks", byte values that are not assigned to any character.
 /// ISO-8859-1 (the IANA one) assigns them to the C0 and C1 control codes.
 ///
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 7db35359a1f..74ded948b18 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -322,6 +322,50 @@ impl Ordering {
     }
 }
 
+/// A helper struct for reverse ordering.
+///
+/// This struct is a helper to be used with functions like `Vec::sort_by_key` and
+/// can be used to reverse order a part of a key.
+///
+/// Example usage:
+///
+/// ```
+/// #![feature(reverse_cmp_key)]
+/// use std::cmp::Reverse;
+///
+/// let mut v = vec![1, 2, 3, 4, 5, 6];
+/// v.sort_by_key(|&num| (num > 3, Reverse(num)));
+/// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
+/// ```
+#[derive(PartialEq, Eq, Debug)]
+#[unstable(feature = "reverse_cmp_key", issue = "40893")]
+pub struct Reverse<T>(pub T);
+
+#[unstable(feature = "reverse_cmp_key", issue = "40893")]
+impl<T: PartialOrd> PartialOrd for Reverse<T> {
+    #[inline]
+    fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
+        other.0.partial_cmp(&self.0)
+    }
+
+    #[inline]
+    fn lt(&self, other: &Self) -> bool { other.0 < self.0 }
+    #[inline]
+    fn le(&self, other: &Self) -> bool { other.0 <= self.0 }
+    #[inline]
+    fn ge(&self, other: &Self) -> bool { other.0 >= self.0 }
+    #[inline]
+    fn gt(&self, other: &Self) -> bool { other.0 > self.0 }
+}
+
+#[unstable(feature = "reverse_cmp_key", issue = "40893")]
+impl<T: Ord> Ord for Reverse<T> {
+    #[inline]
+    fn cmp(&self, other: &Reverse<T>) -> Ordering {
+        other.0.cmp(&self.0)
+    }
+}
+
 /// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
 ///
 /// An order is a total order if it is (for all `a`, `b` and `c`):
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 3415b0eea9b..34f14ef53f8 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -536,9 +536,9 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
 /// #     }
 /// # }
 /// impl ExactSizeIterator for Counter {
-///     // We already have the number of iterations, so we can use it directly.
+///     // We can easily calculate the remaining number of iterations.
 ///     fn len(&self) -> usize {
-///         self.count
+///         5 - self.count
 ///     }
 /// }
 ///
@@ -546,7 +546,7 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
 ///
 /// let counter = Counter::new();
 ///
-/// assert_eq!(0, counter.len());
+/// assert_eq!(5, counter.len());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait ExactSizeIterator: Iterator {
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 021079f85f6..2a28d108df7 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -337,27 +337,20 @@ macro_rules! try {
 
 /// Write formatted data into a buffer
 ///
-/// This macro accepts a 'writer' (any value with a `write_fmt` method), a format string, and a
-/// list of arguments to format.
+/// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be
+/// formatted according to the specified format string and the result will be passed to the writer.
+/// The writer may be any value with a `write_fmt` method; generally this comes from an
+/// implementation of either the [`std::fmt::Write`] or the [`std::io::Write`] trait. The macro
+/// returns whatever the 'write_fmt' method returns; commonly a [`std::fmt::Result`], or an
+/// [`io::Result`].
 ///
-/// The `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write]
-/// or [`std::io::Write`][io_write] traits. The term 'writer' refers to an implementation of one of
-/// these two traits.
+/// See [`std::fmt`] for more information on the format string syntax.
 ///
-/// Passed arguments will be formatted according to the specified format string and the resulting
-/// string will be passed to the writer.
-///
-/// See [`std::fmt`][fmt] for more information on format syntax.
-///
-/// `write!` returns whatever the 'write_fmt' method returns.
-///
-/// Common return values include: [`fmt::Result`][fmt_result], [`io::Result`][io_result]
-///
-/// [fmt]: ../std/fmt/index.html
-/// [fmt_write]: ../std/fmt/trait.Write.html
-/// [io_write]: ../std/io/trait.Write.html
-/// [fmt_result]: ../std/fmt/type.Result.html
-/// [io_result]: ../std/io/type.Result.html
+/// [`std::fmt`]: ../std/fmt/index.html
+/// [`std::fmt::Write`]: ../std/fmt/trait.Write.html
+/// [`std::io::Write`]: ../std/io/trait.Write.html
+/// [`std::fmt::Result`]: ../std/fmt/type.Result.html
+/// [`io::Result`]: ../std/io/type.Result.html
 ///
 /// # Examples
 ///
@@ -396,27 +389,12 @@ macro_rules! write {
 /// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
 /// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
 ///
-/// This macro accepts a 'writer' (any value with a `write_fmt` method), a format string, and a
-/// list of arguments to format.
-///
-/// The `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write]
-/// or [`std::io::Write`][io_write] traits. The term 'writer' refers to an implementation of one of
-/// these two traits.
-///
-/// Passed arguments will be formatted according to the specified format string and the resulting
-/// string will be passed to the writer, along with the appended newline.
-///
-/// See [`std::fmt`][fmt] for more information on format syntax.
-///
-/// `write!` returns whatever the 'write_fmt' method returns.
+/// For more information, see [`write!`]. For information on the format string syntax, see
+/// [`std::fmt`].
 ///
-/// Common return values include: [`fmt::Result`][fmt_result], [`io::Result`][io_result]
+/// [`write!`]: macro.write.html
+/// [`std::fmt`]: ../std/fmt/index.html
 ///
-/// [fmt]: ../std/fmt/index.html
-/// [fmt_write]: ../std/fmt/trait.Write.html
-/// [io_write]: ../std/io/trait.Write.html
-/// [fmt_result]: ../std/fmt/type.Result.html
-/// [io_result]: ../std/io/type.Result.html
 ///
 /// # Examples
 ///
diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs
index 604bc7c10de..60dab943a3a 100644
--- a/src/libcore/num/dec2flt/algorithm.rs
+++ b/src/libcore/num/dec2flt/algorithm.rs
@@ -141,7 +141,7 @@ pub fn fast_path<T: RawFloat>(integral: &[u8], fractional: &[u8], e: i64) -> Opt
 ///
 /// It rounds ``f`` to a float with 64 bit significand and multiplies it by the best approximation
 /// of `10^e` (in the same floating point format). This is often enough to get the correct result.
-/// However, when the result is close to halfway between two adjecent (ordinary) floats, the
+/// However, when the result is close to halfway between two adjacent (ordinary) floats, the
 /// compound rounding error from multiplying two approximation means the result may be off by a
 /// few bits. When this happens, the iterative Algorithm R fixes things up.
 ///
@@ -392,7 +392,7 @@ fn underflow<T: RawFloat>(x: Big, v: Big, rem: Big) -> T {
     //
     // Therefore, when the rounded-off bits are != 0.5 ULP, they decide the rounding
     // on their own. When they are equal and the remainder is non-zero, the value still
-    // needs to be rounded up. Only when the rounded off bits are 1/2 and the remainer
+    // needs to be rounded up. Only when the rounded off bits are 1/2 and the remainder
     // is zero, we have a half-to-even situation.
     let bits = x.bit_length();
     let lsb = bits - T::sig_bits() as usize;
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 686cc21eba1..d203b68c0df 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -196,7 +196,7 @@ pub trait Drop {
     fn drop(&mut self);
 }
 
-/// The `Add` trait is used to specify the functionality of `+`.
+/// The addition operator `+`.
 ///
 /// # Examples
 ///
@@ -269,7 +269,7 @@ macro_rules! add_impl {
 
 add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `Sub` trait is used to specify the functionality of `-`.
+/// The subtraction operator `-`.
 ///
 /// # Examples
 ///
@@ -342,7 +342,7 @@ macro_rules! sub_impl {
 
 sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `Mul` trait is used to specify the functionality of `*`.
+/// The multiplication operator `*`.
 ///
 /// # Examples
 ///
@@ -464,7 +464,7 @@ macro_rules! mul_impl {
 
 mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `Div` trait is used to specify the functionality of `/`.
+/// The division operator `/`.
 ///
 /// # Examples
 ///
@@ -609,7 +609,7 @@ macro_rules! div_impl_float {
 
 div_impl_float! { f32 f64 }
 
-/// The `Rem` trait is used to specify the functionality of `%`.
+/// The remainder operator `%`.
 ///
 /// # Examples
 ///
@@ -689,7 +689,7 @@ macro_rules! rem_impl_float {
 
 rem_impl_float! { f32 f64 }
 
-/// The `Neg` trait is used to specify the functionality of unary `-`.
+/// The unary negation operator `-`.
 ///
 /// # Examples
 ///
@@ -768,7 +768,7 @@ macro_rules! neg_impl_unsigned {
 // neg_impl_unsigned! { usize u8 u16 u32 u64 }
 neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `Not` trait is used to specify the functionality of unary `!`.
+/// The unary logical negation operator `!`.
 ///
 /// # Examples
 ///
@@ -826,7 +826,7 @@ macro_rules! not_impl {
 
 not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitAnd` trait is used to specify the functionality of `&`.
+/// The bitwise AND operator `&`.
 ///
 /// # Examples
 ///
@@ -909,7 +909,7 @@ macro_rules! bitand_impl {
 
 bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitOr` trait is used to specify the functionality of `|`.
+/// The bitwise OR operator `|`.
 ///
 /// # Examples
 ///
@@ -992,7 +992,7 @@ macro_rules! bitor_impl {
 
 bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitXor` trait is used to specify the functionality of `^`.
+/// The bitwise XOR operator `^`.
 ///
 /// # Examples
 ///
@@ -1078,7 +1078,7 @@ macro_rules! bitxor_impl {
 
 bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `Shl` trait is used to specify the functionality of `<<`.
+/// The left shift operator `<<`.
 ///
 /// # Examples
 ///
@@ -1181,7 +1181,7 @@ macro_rules! shl_impl_all {
 
 shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
 
-/// The `Shr` trait is used to specify the functionality of `>>`.
+/// The right shift operator `>>`.
 ///
 /// # Examples
 ///
@@ -1284,7 +1284,7 @@ macro_rules! shr_impl_all {
 
 shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
 
-/// The `AddAssign` trait is used to specify the functionality of `+=`.
+/// The addition assignment operator `+=`.
 ///
 /// # Examples
 ///
@@ -1340,7 +1340,7 @@ macro_rules! add_assign_impl {
 
 add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `SubAssign` trait is used to specify the functionality of `-=`.
+/// The subtraction assignment operator `-=`.
 ///
 /// # Examples
 ///
@@ -1396,7 +1396,7 @@ macro_rules! sub_assign_impl {
 
 sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `MulAssign` trait is used to specify the functionality of `*=`.
+/// The multiplication assignment operator `*=`.
 ///
 /// # Examples
 ///
@@ -1441,7 +1441,7 @@ macro_rules! mul_assign_impl {
 
 mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `DivAssign` trait is used to specify the functionality of `/=`.
+/// The division assignment operator `/=`.
 ///
 /// # Examples
 ///
@@ -1485,7 +1485,7 @@ macro_rules! div_assign_impl {
 
 div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `RemAssign` trait is used to specify the functionality of `%=`.
+/// The remainder assignment operator `%=`.
 ///
 /// # Examples
 ///
@@ -1529,7 +1529,7 @@ macro_rules! rem_assign_impl {
 
 rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
 
-/// The `BitAndAssign` trait is used to specify the functionality of `&=`.
+/// The bitwise AND assignment operator `&=`.
 ///
 /// # Examples
 ///
@@ -1615,7 +1615,7 @@ macro_rules! bitand_assign_impl {
 
 bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitOrAssign` trait is used to specify the functionality of `|=`.
+/// The bitwise OR assignment operator `|=`.
 ///
 /// # Examples
 ///
@@ -1659,7 +1659,7 @@ macro_rules! bitor_assign_impl {
 
 bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `BitXorAssign` trait is used to specify the functionality of `^=`.
+/// The bitwise XOR assignment operator `^=`.
 ///
 /// # Examples
 ///
@@ -1703,7 +1703,7 @@ macro_rules! bitxor_assign_impl {
 
 bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
-/// The `ShlAssign` trait is used to specify the functionality of `<<=`.
+/// The left shift assignment operator `<<=`.
 ///
 /// # Examples
 ///
@@ -1768,7 +1768,7 @@ macro_rules! shl_assign_impl_all {
 
 shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
 
-/// The `ShrAssign` trait is used to specify the functionality of `>>=`.
+/// The right shift assignment operator `>>=`.
 ///
 /// # Examples
 ///
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 6ec8a37dfa4..c46b0c1324d 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -838,10 +838,10 @@ impl<T: Default, E> Result<T, E> {
     ///
     /// assert_eq!(1909, good_year);
     /// assert_eq!(0, bad_year);
+    /// ```
     ///
     /// [`parse`]: ../../std/primitive.str.html#method.parse
     /// [`FromStr`]: ../../std/str/trait.FromStr.html
-    /// ```
     #[inline]
     #[stable(feature = "result_unwrap_or_default", since = "1.16.0")]
     pub fn unwrap_or_default(self) -> T {
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index af492b3c639..45667bb4299 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -97,8 +97,7 @@ pub trait SliceExt {
 
     #[stable(feature = "core", since = "1.6.0")]
     fn get<I>(&self, index: I) -> Option<&I::Output>
-        where I: SliceIndex<Self::Item>;
-
+        where I: SliceIndex<Self>;
     #[stable(feature = "core", since = "1.6.0")]
     fn first(&self) -> Option<&Self::Item>;
 
@@ -113,8 +112,7 @@ pub trait SliceExt {
 
     #[stable(feature = "core", since = "1.6.0")]
     unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
-        where I: SliceIndex<Self::Item>;
-
+        where I: SliceIndex<Self>;
     #[stable(feature = "core", since = "1.6.0")]
     fn as_ptr(&self) -> *const Self::Item;
 
@@ -141,8 +139,7 @@ pub trait SliceExt {
 
     #[stable(feature = "core", since = "1.6.0")]
     fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
-        where I: SliceIndex<Self::Item>;
-
+        where I: SliceIndex<Self>;
     #[stable(feature = "core", since = "1.6.0")]
     fn iter_mut(&mut self) -> IterMut<Self::Item>;
 
@@ -184,8 +181,7 @@ pub trait SliceExt {
 
     #[stable(feature = "core", since = "1.6.0")]
     unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
-        where I: SliceIndex<Self::Item>;
-
+        where I: SliceIndex<Self>;
     #[stable(feature = "core", since = "1.6.0")]
     fn as_mut_ptr(&mut self) -> *mut Self::Item;
 
@@ -337,7 +333,7 @@ impl<T> SliceExt for [T] {
 
     #[inline]
     fn get<I>(&self, index: I) -> Option<&I::Output>
-        where I: SliceIndex<T>
+        where I: SliceIndex<[T]>
     {
         index.get(self)
     }
@@ -365,7 +361,7 @@ impl<T> SliceExt for [T] {
 
     #[inline]
     unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
-        where I: SliceIndex<T>
+        where I: SliceIndex<[T]>
     {
         index.get_unchecked(self)
     }
@@ -406,7 +402,7 @@ impl<T> SliceExt for [T] {
 
     #[inline]
     fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
-        where I: SliceIndex<T>
+        where I: SliceIndex<[T]>
     {
         index.get_mut(self)
     }
@@ -538,7 +534,7 @@ impl<T> SliceExt for [T] {
 
     #[inline]
     unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
-        where I: SliceIndex<T>
+        where I: SliceIndex<[T]>
     {
         index.get_unchecked_mut(self)
     }
@@ -631,7 +627,7 @@ impl<T> SliceExt for [T] {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
 impl<T, I> ops::Index<I> for [T]
-    where I: SliceIndex<T>
+    where I: SliceIndex<[T]>
 {
     type Output = I::Output;
 
@@ -644,7 +640,7 @@ impl<T, I> ops::Index<I> for [T]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
 impl<T, I> ops::IndexMut<I> for [T]
-    where I: SliceIndex<T>
+    where I: SliceIndex<[T]>
 {
     #[inline]
     fn index_mut(&mut self, index: I) -> &mut I::Output {
@@ -667,37 +663,37 @@ fn slice_index_order_fail(index: usize, end: usize) -> ! {
 /// A helper trait used for indexing operations.
 #[unstable(feature = "slice_get_slice", issue = "35729")]
 #[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
-pub trait SliceIndex<T> {
+pub trait SliceIndex<T: ?Sized> {
     /// The output type returned by methods.
     type Output: ?Sized;
 
     /// Returns a shared reference to the output at this location, if in
     /// bounds.
-    fn get(self, slice: &[T]) -> Option<&Self::Output>;
+    fn get(self, slice: &T) -> Option<&Self::Output>;
 
     /// Returns a mutable reference to the output at this location, if in
     /// bounds.
-    fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output>;
+    fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
 
     /// Returns a shared reference to the output at this location, without
     /// performing any bounds checking.
-    unsafe fn get_unchecked(self, slice: &[T]) -> &Self::Output;
+    unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
 
     /// Returns a mutable reference to the output at this location, without
     /// performing any bounds checking.
-    unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut Self::Output;
+    unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
 
     /// Returns a shared reference to the output at this location, panicking
     /// if out of bounds.
-    fn index(self, slice: &[T]) -> &Self::Output;
+    fn index(self, slice: &T) -> &Self::Output;
 
     /// Returns a mutable reference to the output at this location, panicking
     /// if out of bounds.
-    fn index_mut(self, slice: &mut [T]) -> &mut Self::Output;
+    fn index_mut(self, slice: &mut T) -> &mut Self::Output;
 }
 
 #[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
-impl<T> SliceIndex<T> for usize {
+impl<T> SliceIndex<[T]> for usize {
     type Output = T;
 
     #[inline]
@@ -746,7 +742,7 @@ impl<T> SliceIndex<T> for usize {
 }
 
 #[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
-impl<T> SliceIndex<T> for  ops::Range<usize> {
+impl<T> SliceIndex<[T]> for  ops::Range<usize> {
     type Output = [T];
 
     #[inline]
@@ -807,7 +803,7 @@ impl<T> SliceIndex<T> for  ops::Range<usize> {
 }
 
 #[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
-impl<T> SliceIndex<T> for ops::RangeTo<usize> {
+impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
     type Output = [T];
 
     #[inline]
@@ -842,7 +838,7 @@ impl<T> SliceIndex<T> for ops::RangeTo<usize> {
 }
 
 #[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
-impl<T> SliceIndex<T> for ops::RangeFrom<usize> {
+impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
     type Output = [T];
 
     #[inline]
@@ -877,7 +873,7 @@ impl<T> SliceIndex<T> for ops::RangeFrom<usize> {
 }
 
 #[stable(feature = "slice-get-slice-impls", since = "1.15.0")]
-impl<T> SliceIndex<T> for ops::RangeFull {
+impl<T> SliceIndex<[T]> for ops::RangeFull {
     type Output = [T];
 
     #[inline]
@@ -913,7 +909,7 @@ impl<T> SliceIndex<T> for ops::RangeFull {
 
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-impl<T> SliceIndex<T> for ops::RangeInclusive<usize> {
+impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
     type Output = [T];
 
     #[inline]
@@ -976,7 +972,7 @@ impl<T> SliceIndex<T> for ops::RangeInclusive<usize> {
 }
 
 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
-impl<T> SliceIndex<T> for ops::RangeToInclusive<usize> {
+impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
     type Output = [T];
 
     #[inline]
diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs
index d13d537d993..7065fdb79fc 100644
--- a/src/libcore/slice/sort.rs
+++ b/src/libcore/slice/sort.rs
@@ -152,8 +152,8 @@ fn partial_insertion_sort<T, F>(v: &mut [T], is_less: &mut F) -> bool
 fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F)
     where F: FnMut(&T, &T) -> bool
 {
-    for i in 2..v.len()+1 {
-        shift_tail(&mut v[..i], is_less);
+    for i in 1..v.len() {
+        shift_tail(&mut v[..i+1], is_less);
     }
 }
 
@@ -498,32 +498,42 @@ fn partition_equal<T, F>(v: &mut [T], pivot: usize, is_less: &mut F) -> usize
 #[cold]
 fn break_patterns<T>(v: &mut [T]) {
     let len = v.len();
-
     if len >= 8 {
-        // A random number will be taken modulo this one. The modulus is a power of two so that we
-        // can simply take bitwise "and", thus avoiding costly CPU operations.
-        let modulus = (len / 4).next_power_of_two();
-        debug_assert!(modulus >= 1 && modulus <= len / 2);
-
-        // Pseudorandom number generation from the "Xorshift RNGs" paper by George Marsaglia.
-        let mut random = len;
-        random ^= random << 13;
-        random ^= random >> 17;
-        random ^= random << 5;
-        random &= modulus - 1;
-        debug_assert!(random < len / 2);
-
-        // The first index.
-        let a = len / 4 * 2;
-        debug_assert!(a >= 1 && a < len - 2);
-
-        // The second index.
-        let b = len / 4 + random;
-        debug_assert!(b >= 1 && b < len - 2);
-
-        // Swap neighbourhoods of `a` and `b`.
+        // Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia.
+        let mut random = len as u32;
+        let mut gen_u32 = || {
+            random ^= random << 13;
+            random ^= random >> 17;
+            random ^= random << 5;
+            random
+        };
+        let mut gen_usize = || {
+            if mem::size_of::<usize>() <= 4 {
+                gen_u32() as usize
+            } else {
+                (((gen_u32() as u64) << 32) | (gen_u32() as u64)) as usize
+            }
+        };
+
+        // Take random numbers modulo this number.
+        // The number fits into `usize` because `len` is not greater than `isize::MAX`.
+        let modulus = len.next_power_of_two();
+
+        // Some pivot candidates will be in the nearby of this index. Let's randomize them.
+        let pos = len / 4 * 2;
+
         for i in 0..3 {
-            v.swap(a - 1 + i, b - 1 + i);
+            // Generate a random number modulo `len`. However, in order to avoid costly operations
+            // we first take it modulo a power of two, and then decrease by `len` until it fits
+            // into the range `[0, len - 1]`.
+            let mut other = gen_usize() & (modulus - 1);
+
+            // `other` is guaranteed to be less than `2 * len`.
+            if other >= len {
+                other -= len;
+            }
+
+            v.swap(pos - 1 + i, other);
         }
     }
 }
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index dfb6936da6b..f75a1f7ab6e 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -22,7 +22,7 @@ use convert::TryFrom;
 use fmt;
 use iter::{Map, Cloned, FusedIterator};
 use mem;
-use slice;
+use slice::{self, SliceIndex};
 
 pub mod pattern;
 
@@ -35,6 +35,39 @@ pub mod pattern;
 /// [`from_str`]: #tymethod.from_str
 /// [`str`]: ../../std/primitive.str.html
 /// [`parse`]: ../../std/primitive.str.html#method.parse
+///
+/// # Examples
+///
+/// Basic implementation of `FromStr` on an example `Point` type:
+///
+/// ```
+/// use std::str::FromStr;
+/// use std::num::ParseIntError;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Point {
+///     x: i32,
+///     y: i32
+/// }
+///
+/// impl FromStr for Point {
+///     type Err = ParseIntError;
+///
+///     fn from_str(s: &str) -> Result<Self, Self::Err> {
+///         let coords: Vec<&str> = s.trim_matches(|p| p == '(' || p == ')' )
+///                                  .split(",")
+///                                  .collect();
+///
+///         let x_fromstr = coords[0].parse::<i32>()?;
+///         let y_fromstr = coords[1].parse::<i32>()?;
+///
+///         Ok(Point { x: x_fromstr, y: y_fromstr })
+///     }
+/// }
+///
+/// let p = Point::from_str("(1,2)");
+/// assert_eq!(p.unwrap(), Point{ x: 1, y: 2} )
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait FromStr: Sized {
     /// The associated error which can be returned from parsing.
@@ -101,7 +134,9 @@ impl FromStr for bool {
     }
 }
 
-/// An error returned when parsing a `bool` from a string fails.
+/// An error returned when parsing a `bool` using [`from_str`] fails
+///
+/// [`from_str`]: ../../std/primitive.bool.html#method.from_str
 #[derive(Debug, Clone, PartialEq, Eq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ParseBoolError { _priv: () }
@@ -292,7 +327,9 @@ unsafe fn from_raw_parts_mut<'a>(p: *mut u8, len: usize) -> &'a mut str {
 ///
 /// This function is unsafe because it does not check that the bytes passed to
 /// it are valid UTF-8. If this constraint is violated, undefined behavior
-/// results, as the rest of Rust assumes that `&str`s are valid UTF-8.
+/// results, as the rest of Rust assumes that [`&str`]s are valid UTF-8.
+///
+/// [`&str`]: ../../std/primitive.str.html
 ///
 /// # Examples
 ///
@@ -332,11 +369,15 @@ impl fmt::Display for Utf8Error {
 Section: Iterators
 */
 
-/// Iterator for the char (representing *Unicode Scalar Values*) of a string.
+/// An iterator over the [`char`]s of a string slice.
+///
+/// [`char`]: ../../std/primitive.char.html
 ///
-/// Created with the method [`chars`].
+/// This struct is created by the [`chars`] method on [`str`].
+/// See its documentation for more.
 ///
 /// [`chars`]: ../../std/primitive.str.html#method.chars
+/// [`str`]: ../../std/primitive.str.html
 #[derive(Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Chars<'a> {
@@ -516,7 +557,15 @@ impl<'a> Chars<'a> {
     }
 }
 
-/// Iterator for a string's characters and their byte offsets.
+/// An iterator over the [`char`]s of a string slice, and their positions.
+///
+/// [`char`]: ../../std/primitive.char.html
+///
+/// This struct is created by the [`char_indices`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`char_indices`]: ../../std/primitive.str.html#method.char_indices
+/// [`str`]: ../../std/primitive.str.html
 #[derive(Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct CharIndices<'a> {
@@ -588,12 +637,13 @@ impl<'a> CharIndices<'a> {
     }
 }
 
-/// External iterator for a string's bytes.
-/// Use with the `std::iter` module.
+/// An iterator over the bytes of a string slice.
 ///
-/// Created with the method [`bytes`].
+/// This struct is created by the [`bytes`] method on [`str`].
+/// See its documentation for more.
 ///
 /// [`bytes`]: ../../std/primitive.str.html#method.bytes
+/// [`str`]: ../../std/primitive.str.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone, Debug)]
 pub struct Bytes<'a>(Cloned<slice::Iter<'a, u8>>);
@@ -1124,9 +1174,13 @@ generate_pattern_iterators! {
     delegate double ended;
 }
 
-/// Created with the method [`lines`].
+/// An iterator over the lines of a string, as string slices.
+///
+/// This struct is created with the [`lines`] method on [`str`].
+/// See its documentation for more.
 ///
 /// [`lines`]: ../../std/primitive.str.html#method.lines
+/// [`str`]: ../../std/primitive.str.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone, Debug)]
 pub struct Lines<'a>(Map<SplitTerminator<'a, char>, LinesAnyMap>);
@@ -1408,6 +1462,8 @@ Section: Trait implementations
 mod traits {
     use cmp::Ordering;
     use ops;
+    use mem;
+    use slice::{self, SliceIndex};
     use str::eq_slice;
 
     /// Implements ordering of strings.
@@ -1490,14 +1546,7 @@ mod traits {
         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)
-            }
+            index.index(self)
         }
     }
 
@@ -1519,14 +1568,7 @@ mod traits {
     impl ops::IndexMut<ops::Range<usize>> for str {
         #[inline]
         fn index_mut(&mut self, index: ops::Range<usize>) -> &mut 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_mut_unchecked(index.start, index.end) }
-            } else {
-                super::slice_error_fail(self, index.start, index.end)
-            }
+            index.index_mut(self)
         }
     }
 
@@ -1694,8 +1736,276 @@ mod traits {
             self.index_mut(0...index.end)
         }
     }
+
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    impl SliceIndex<str> for ops::RangeFull {
+        type Output = str;
+        #[inline]
+        fn get(self, slice: &str) -> Option<&Self::Output> {
+            Some(slice)
+        }
+        #[inline]
+        fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+            Some(slice)
+        }
+        #[inline]
+        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+            slice
+        }
+        #[inline]
+        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+            slice
+        }
+        #[inline]
+        fn index(self, slice: &str) -> &Self::Output {
+            slice
+        }
+        #[inline]
+        fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+            slice
+        }
+    }
+
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    impl SliceIndex<str> for ops::Range<usize> {
+        type Output = str;
+        #[inline]
+        fn get(self, slice: &str) -> Option<&Self::Output> {
+            if self.start <= self.end &&
+               slice.is_char_boundary(self.start) &&
+               slice.is_char_boundary(self.end) {
+                Some(unsafe { self.get_unchecked(slice) })
+            } else {
+                None
+            }
+        }
+        #[inline]
+        fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+            if self.start <= self.end &&
+               slice.is_char_boundary(self.start) &&
+               slice.is_char_boundary(self.end) {
+                Some(unsafe { self.get_unchecked_mut(slice) })
+            } else {
+                None
+            }
+        }
+        #[inline]
+        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+            let ptr = slice.as_ptr().offset(self.start as isize);
+            let len = self.end - self.start;
+            super::from_utf8_unchecked(slice::from_raw_parts(ptr, len))
+        }
+        #[inline]
+        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+            let ptr = slice.as_ptr().offset(self.start as isize);
+            let len = self.end - self.start;
+            mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, len))
+        }
+        #[inline]
+        fn index(self, slice: &str) -> &Self::Output {
+            let (start, end) = (self.start, self.end);
+            self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, start, end))
+        }
+        #[inline]
+        fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+            // is_char_boundary checks that the index is in [0, .len()]
+            // canot reuse `get` as above, because of NLL trouble
+            if self.start <= self.end &&
+               slice.is_char_boundary(self.start) &&
+               slice.is_char_boundary(self.end) {
+                unsafe { self.get_unchecked_mut(slice) }
+            } else {
+                super::slice_error_fail(slice, self.start, self.end)
+            }
+        }
+    }
+
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    impl SliceIndex<str> for ops::RangeTo<usize> {
+        type Output = str;
+        #[inline]
+        fn get(self, slice: &str) -> Option<&Self::Output> {
+            if slice.is_char_boundary(self.end) {
+                Some(unsafe { self.get_unchecked(slice) })
+            } else {
+                None
+            }
+        }
+        #[inline]
+        fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+            if slice.is_char_boundary(self.end) {
+                Some(unsafe { self.get_unchecked_mut(slice) })
+            } else {
+                None
+            }
+        }
+        #[inline]
+        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+            let ptr = slice.as_ptr();
+            super::from_utf8_unchecked(slice::from_raw_parts(ptr, self.end))
+        }
+        #[inline]
+        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+            let ptr = slice.as_ptr();
+            mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, self.end))
+        }
+        #[inline]
+        fn index(self, slice: &str) -> &Self::Output {
+            let end = self.end;
+            self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, 0, end))
+        }
+        #[inline]
+        fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+            if slice.is_char_boundary(self.end) {
+                unsafe { self.get_unchecked_mut(slice) }
+            } else {
+                super::slice_error_fail(slice, 0, self.end)
+            }
+        }
+    }
+
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    impl SliceIndex<str> for ops::RangeFrom<usize> {
+        type Output = str;
+        #[inline]
+        fn get(self, slice: &str) -> Option<&Self::Output> {
+            if slice.is_char_boundary(self.start) {
+                Some(unsafe { self.get_unchecked(slice) })
+            } else {
+                None
+            }
+        }
+        #[inline]
+        fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+            if slice.is_char_boundary(self.start) {
+                Some(unsafe { self.get_unchecked_mut(slice) })
+            } else {
+                None
+            }
+        }
+        #[inline]
+        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+            let ptr = slice.as_ptr().offset(self.start as isize);
+            let len = slice.len() - self.start;
+            super::from_utf8_unchecked(slice::from_raw_parts(ptr, len))
+        }
+        #[inline]
+        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+            let ptr = slice.as_ptr().offset(self.start as isize);
+            let len = slice.len() - self.start;
+            mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, len))
+        }
+        #[inline]
+        fn index(self, slice: &str) -> &Self::Output {
+            let (start, end) = (self.start, slice.len());
+            self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, start, end))
+        }
+        #[inline]
+        fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+            if slice.is_char_boundary(self.start) {
+                unsafe { self.get_unchecked_mut(slice) }
+            } else {
+                super::slice_error_fail(slice, self.start, slice.len())
+            }
+        }
+    }
+
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    impl SliceIndex<str> for ops::RangeInclusive<usize> {
+        type Output = str;
+        #[inline]
+        fn get(self, slice: &str) -> Option<&Self::Output> {
+            match self {
+                ops::RangeInclusive::Empty { .. } => 0..0,
+                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
+            }.get(slice)
+        }
+        #[inline]
+        fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+            match self {
+                ops::RangeInclusive::Empty { .. } => 0..0,
+                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
+            }.get_mut(slice)
+        }
+        #[inline]
+        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+            match self {
+                ops::RangeInclusive::Empty { .. } => 0..0,
+                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
+            }.get_unchecked(slice)
+        }
+        #[inline]
+        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+            match self {
+                ops::RangeInclusive::Empty { .. } => 0..0,
+                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
+            }.get_unchecked_mut(slice)
+        }
+        #[inline]
+        fn index(self, slice: &str) -> &Self::Output {
+            match self {
+                ops::RangeInclusive::Empty { .. } => 0..0,
+                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
+            }.index(slice)
+        }
+        #[inline]
+        fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+            match self {
+                ops::RangeInclusive::Empty { .. } => 0..0,
+                ops::RangeInclusive::NonEmpty { start, end } => start..end+1,
+            }.index_mut(slice)
+        }
+    }
+
+
+
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    impl SliceIndex<str> for ops::RangeToInclusive<usize> {
+        type Output = str;
+        #[inline]
+        fn get(self, slice: &str) -> Option<&Self::Output> {
+            if slice.is_char_boundary(self.end + 1) {
+                Some(unsafe { self.get_unchecked(slice) })
+            } else {
+                None
+            }
+        }
+        #[inline]
+        fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> {
+            if slice.is_char_boundary(self.end + 1) {
+                Some(unsafe { self.get_unchecked_mut(slice) })
+            } else {
+                None
+            }
+        }
+        #[inline]
+        unsafe fn get_unchecked(self, slice: &str) -> &Self::Output {
+            let ptr = slice.as_ptr();
+            super::from_utf8_unchecked(slice::from_raw_parts(ptr, self.end + 1))
+        }
+        #[inline]
+        unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
+            let ptr = slice.as_ptr();
+            mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, self.end + 1))
+        }
+        #[inline]
+        fn index(self, slice: &str) -> &Self::Output {
+            let end = self.end + 1;
+            self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, 0, end))
+        }
+        #[inline]
+        fn index_mut(self, slice: &mut str) -> &mut Self::Output {
+            if slice.is_char_boundary(self.end) {
+                unsafe { self.get_unchecked_mut(slice) }
+            } else {
+                super::slice_error_fail(slice, 0, self.end + 1)
+            }
+        }
+    }
+
 }
 
+
 /// Methods for string slices
 #[allow(missing_docs)]
 #[doc(hidden)]
@@ -1745,6 +2055,14 @@ pub trait StrExt {
     #[rustc_deprecated(since = "1.6.0", reason = "use lines() instead now")]
     #[allow(deprecated)]
     fn lines_any(&self) -> LinesAny;
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output>;
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output>;
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output;
+    #[unstable(feature = "str_checked_slicing", issue = "39932")]
+    unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output;
     #[stable(feature = "core", since = "1.6.0")]
     unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str;
     #[stable(feature = "core", since = "1.6.0")]
@@ -1935,17 +2253,33 @@ impl StrExt for str {
     }
 
     #[inline]
+    fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
+        i.get(self)
+    }
+
+    #[inline]
+    fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
+        i.get_mut(self)
+    }
+
+    #[inline]
+    unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
+        i.get_unchecked(self)
+    }
+
+    #[inline]
+    unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
+        i.get_unchecked_mut(self)
+    }
+
+    #[inline]
     unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
-        let ptr = self.as_ptr().offset(begin as isize);
-        let len = end - begin;
-        from_utf8_unchecked(slice::from_raw_parts(ptr, len))
+        (begin..end).get_unchecked(self)
     }
 
     #[inline]
     unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
-        let ptr = self.as_ptr().offset(begin as isize);
-        let len = end - begin;
-        mem::transmute(slice::from_raw_parts_mut(ptr as *mut u8, len))
+        (begin..end).get_unchecked_mut(self)
     }
 
     #[inline]
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 743e3c41170..ae47e6fdfa9 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -15,27 +15,37 @@
 //! types.
 //!
 //! This module defines atomic versions of a select number of primitive
-//! types, including `AtomicBool`, `AtomicIsize`, and `AtomicUsize`.
+//! types, including [`AtomicBool`], [`AtomicIsize`], and [`AtomicUsize`].
 //! Atomic types present operations that, when used correctly, synchronize
 //! updates between threads.
 //!
-//! Each method takes an `Ordering` which represents the strength of
+//! [`AtomicBool`]: struct.AtomicBool.html
+//! [`AtomicIsize`]: struct.AtomicIsize.html
+//! [`AtomicUsize`]: struct.AtomicUsize.html
+//!
+//! Each method takes an [`Ordering`] which represents the strength of
 //! the memory barrier for that operation. These orderings are the
 //! same as [LLVM atomic orderings][1]. For more information see the [nomicon][2].
 //!
+//! [`Ordering`]: enum.Ordering.html
+//!
 //! [1]: http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations
 //! [2]: ../../../nomicon/atomics.html
 //!
-//! Atomic variables are safe to share between threads (they implement `Sync`)
+//! Atomic variables are safe to share between threads (they implement [`Sync`])
 //! but they do not themselves provide the mechanism for sharing and follow the
 //! [threading model](../../../std/thread/index.html#the-threading-model) of rust.
-//! The most common way to share an atomic variable is to put it into an `Arc` (an
+//! The most common way to share an atomic variable is to put it into an [`Arc`][arc] (an
 //! atomically-reference-counted shared pointer).
 //!
+//! [`Sync`]: ../../marker/trait.Sync.html
+//! [arc]: ../../../std/sync/struct.Arc.html
+//!
 //! Most atomic types may be stored in static variables, initialized using
-//! the provided static initializers like `ATOMIC_BOOL_INIT`. Atomic statics
+//! the provided static initializers like [`ATOMIC_BOOL_INIT`]. Atomic statics
 //! are often used for lazy global initialization.
 //!
+//! [`ATOMIC_BOOL_INIT`]: constant.ATOMIC_BOOL_INIT.html
 //!
 //! # Examples
 //!
@@ -148,22 +158,32 @@ unsafe impl<T> Sync for AtomicPtr<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Copy, Clone, Debug)]
 pub enum Ordering {
-    /// No ordering constraints, only atomic operations. Corresponds to LLVM's
-    /// `Monotonic` ordering.
+    /// No ordering constraints, only atomic operations.
+    ///
+    /// Corresponds to LLVM's [`Monotonic`] ordering.
+    ///
+    /// [`Monotonic`]: http://llvm.org/docs/Atomics.html#monotonic
     #[stable(feature = "rust1", since = "1.0.0")]
     Relaxed,
     /// When coupled with a store, all previous writes become visible
-    /// to the other threads that perform a load with `Acquire` ordering
+    /// to the other threads that perform a load with [`Acquire`] ordering
     /// on the same value.
+    ///
+    /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire
     #[stable(feature = "rust1", since = "1.0.0")]
     Release,
     /// When coupled with a load, all subsequent loads will see data
-    /// written before a store with `Release` ordering on the same value
+    /// written before a store with [`Release`] ordering on the same value
     /// in other threads.
+    ///
+    /// [`Release`]: http://llvm.org/docs/Atomics.html#release
     #[stable(feature = "rust1", since = "1.0.0")]
     Acquire,
-    /// When coupled with a load, uses `Acquire` ordering, and with a store
-    /// `Release` ordering.
+    /// When coupled with a load, uses [`Acquire`] ordering, and with a store
+    /// [`Release`] ordering.
+    ///
+    /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire
+    /// [`Release`]: http://llvm.org/docs/Atomics.html#release
     #[stable(feature = "rust1", since = "1.0.0")]
     AcqRel,
     /// Like `AcqRel` with the additional guarantee that all threads see all
@@ -176,7 +196,9 @@ pub enum Ordering {
     __Nonexhaustive,
 }
 
-/// An `AtomicBool` initialized to `false`.
+/// An [`AtomicBool`] initialized to `false`.
+///
+/// [`AtomicBool`]: struct.AtomicBool.html
 #[cfg(target_has_atomic = "8")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false);
@@ -250,7 +272,7 @@ impl AtomicBool {
     ///
     /// [`Ordering`]: enum.Ordering.html
     /// [`Release`]: enum.Ordering.html#variant.Release
-    /// [`AcqRel`]: enum.Ordering.html#variant.Release
+    /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
     ///
     /// # Examples
     ///
@@ -287,7 +309,10 @@ impl AtomicBool {
     ///
     /// # Panics
     ///
-    /// Panics if `order` is `Acquire` or `AcqRel`.
+    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
+    ///
+    /// [`Acquire`]: enum.Ordering.html#variant.Acquire
+    /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn store(&self, val: bool, order: Ordering) {
@@ -404,7 +429,7 @@ impl AtomicBool {
 
     /// Stores a value into the `bool` if the current value is the same as the `current` value.
     ///
-    /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the
+    /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even when the
     /// comparison succeeds, which can result in more efficient code on some platforms. The
     /// return value is a result indicating whether the new value was written and containing the
     /// previous value.
@@ -415,6 +440,7 @@ impl AtomicBool {
     /// failure ordering can't be [`Release`] or [`AcqRel`] and must be equivalent or
     /// weaker than the success ordering.
     ///
+    /// [`compare_exchange`]: #method.compare_exchange
     /// [`Ordering`]: enum.Ordering.html
     /// [`Release`]: enum.Ordering.html#variant.Release
     /// [`AcqRel`]: enum.Ordering.html#variant.Release
@@ -694,7 +720,10 @@ impl<T> AtomicPtr<T> {
     ///
     /// # Panics
     ///
-    /// Panics if `order` is `Acquire` or `AcqRel`.
+    /// Panics if `order` is [`Acquire`] or [`AcqRel`].
+    ///
+    /// [`Acquire`]: enum.Ordering.html#variant.Acquire
+    /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn store(&self, ptr: *mut T, order: Ordering) {
@@ -1008,7 +1037,10 @@ macro_rules! atomic_int {
             ///
             /// # Panics
             ///
-            /// Panics if `order` is `Acquire` or `AcqRel`.
+            /// Panics if `order` is [`Acquire`] or [`AcqRel`].
+            ///
+            /// [`Acquire`]: enum.Ordering.html#variant.Acquire
+            /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
             #[inline]
             #[$stable]
             pub fn store(&self, val: $int_type, order: Ordering) {