about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/array.rs32
-rw-r--r--src/libcore/char.rs12
-rw-r--r--src/libcore/cmp_macros.rs47
-rw-r--r--src/libcore/fmt/mod.rs23
-rw-r--r--src/libcore/iter.rs47
-rw-r--r--src/libcore/lib.rs13
-rw-r--r--src/libcore/macros.rs52
-rw-r--r--src/libcore/num/f32.rs4
-rw-r--r--src/libcore/num/f64.rs4
-rw-r--r--src/libcore/num/flt2dec/mod.rs5
-rw-r--r--src/libcore/num/mod.rs38
-rw-r--r--src/libcore/ops.rs8
-rw-r--r--src/libcore/slice.rs146
-rw-r--r--src/libcore/str/mod.rs116
14 files changed, 295 insertions, 252 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 97ad99fe0ff..613ed0d14ee 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -62,6 +62,38 @@ unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
     }
 }
 
+macro_rules! __impl_slice_eq1 {
+    ($Lhs: ty, $Rhs: ty) => {
+        __impl_slice_eq1! { $Lhs, $Rhs, Sized }
+    };
+    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
+            #[inline]
+            fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] }
+            #[inline]
+            fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] }
+        }
+    }
+}
+
+macro_rules! __impl_slice_eq2 {
+    ($Lhs: ty, $Rhs: ty) => {
+        __impl_slice_eq2! { $Lhs, $Rhs, Sized }
+    };
+    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
+        __impl_slice_eq1!($Lhs, $Rhs, $Bound);
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> {
+            #[inline]
+            fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] }
+            #[inline]
+            fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] }
+        }
+    }
+}
+
 // macro for implementing n-ary tuple functions and operations
 macro_rules! array_impls {
     ($($N:expr)+) => {
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 5e13df43280..c02704217a8 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -257,19 +257,25 @@ pub fn from_digit(num: u32, radix: u32) -> Option<char> {
            reason = "the stable interface is `impl char` in later crate",
            issue = "27701")]
 pub trait CharExt {
+    #[stable(feature = "core", since = "1.6.0")]
     fn is_digit(self, radix: u32) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn to_digit(self, radix: u32) -> Option<u32>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn escape_unicode(self) -> EscapeUnicode;
+    #[stable(feature = "core", since = "1.6.0")]
     fn escape_default(self) -> EscapeDefault;
+    #[stable(feature = "core", since = "1.6.0")]
     fn len_utf8(self) -> usize;
+    #[stable(feature = "core", since = "1.6.0")]
     fn len_utf16(self) -> usize;
+    #[stable(feature = "core", since = "1.6.0")]
     fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn encode_utf16(self, dst: &mut [u16]) -> Option<usize>;
 }
 
-#[unstable(feature = "core_char_ext",
-           reason = "the stable interface is `impl char` in later crate",
-           issue = "27701")]
+#[stable(feature = "core", since = "1.6.0")]
 impl CharExt for char {
     #[inline]
     fn is_digit(self, radix: u32) -> bool {
diff --git a/src/libcore/cmp_macros.rs b/src/libcore/cmp_macros.rs
deleted file mode 100644
index 3863f63265b..00000000000
--- a/src/libcore/cmp_macros.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Utility macros for implementing PartialEq on slice-like types
-
-#![doc(hidden)]
-
-#[macro_export]
-macro_rules! __impl_slice_eq1 {
-    ($Lhs: ty, $Rhs: ty) => {
-        __impl_slice_eq1! { $Lhs, $Rhs, Sized }
-    };
-    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, 'b, A: $Bound, B> PartialEq<$Rhs> for $Lhs where A: PartialEq<B> {
-            #[inline]
-            fn eq(&self, other: &$Rhs) -> bool { self[..] == other[..] }
-            #[inline]
-            fn ne(&self, other: &$Rhs) -> bool { self[..] != other[..] }
-        }
-    }
-}
-
-#[macro_export]
-macro_rules! __impl_slice_eq2 {
-    ($Lhs: ty, $Rhs: ty) => {
-        __impl_slice_eq2! { $Lhs, $Rhs, Sized }
-    };
-    ($Lhs: ty, $Rhs: ty, $Bound: ident) => {
-        __impl_slice_eq1!($Lhs, $Rhs, $Bound);
-
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl<'a, 'b, A: $Bound, B> PartialEq<$Lhs> for $Rhs where B: PartialEq<A> {
-            #[inline]
-            fn eq(&self, other: &$Lhs) -> bool { self[..] == other[..] }
-            #[inline]
-            fn ne(&self, other: &$Lhs) -> bool { self[..] != other[..] }
-        }
-    }
-}
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index dfd79895747..04676c0c9c8 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -878,7 +878,7 @@ impl<'a> Formatter<'a> {
 
         let mut prefixed = false;
         if self.alternate() {
-            prefixed = true; width += prefix.char_len();
+            prefixed = true; width += prefix.chars().count();
         }
 
         // Writes the sign if it exists, and then the prefix if it was requested
@@ -942,18 +942,13 @@ impl<'a> Formatter<'a> {
         }
         // The `precision` field can be interpreted as a `max-width` for the
         // string being formatted
-        match self.precision {
-            Some(max) => {
-                // If there's a maximum width and our string is longer than
-                // that, then we must always have truncation. This is the only
-                // case where the maximum length will matter.
-                let char_len = s.char_len();
-                if char_len >= max {
-                    let nchars = ::cmp::min(max, char_len);
-                    return self.buf.write_str(s.slice_chars(0, nchars));
-                }
+        if let Some(max) = self.precision {
+            // If there's a maximum width and our string is longer than
+            // that, then we must always have truncation. This is the only
+            // case where the maximum length will matter.
+            if let Some((i, _)) = s.char_indices().skip(max).next() {
+                return self.buf.write_str(&s[..i])
             }
-            None => {}
         }
         // The `width` field is more of a `min-width` parameter at this point.
         match self.width {
@@ -962,13 +957,13 @@ impl<'a> Formatter<'a> {
             None => self.buf.write_str(s),
             // If we're under the maximum width, check if we're over the minimum
             // width, if so it's as easy as just emitting the string.
-            Some(width) if s.char_len() >= width => {
+            Some(width) if s.chars().count() >= width => {
                 self.buf.write_str(s)
             }
             // If we're under both the maximum and the minimum width, then fill
             // up the minimum width with the specified string + some alignment.
             Some(width) => {
-                self.with_padding(width - s.char_len(), Alignment::Left, |me| {
+                self.with_padding(width - s.chars().count(), Alignment::Left, |me| {
                     me.buf.write_str(s)
                 })
             }
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 8cc7f531c58..86c00a254ca 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -1903,6 +1903,7 @@ pub trait Iterator {
     ///
     /// ```
     /// #![feature(iter_cmp)]
+    /// #![allow(deprecated)]
     ///
     /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
@@ -1911,10 +1912,31 @@ pub trait Iterator {
     #[unstable(feature = "iter_cmp",
                reason = "may want to produce an Ordering directly; see #15311",
                issue = "27724")]
+    #[rustc_deprecated(reason = "renamed to max_by_key", since = "1.6.0")]
     fn max_by<B: Ord, F>(self, f: F) -> Option<Self::Item> where
         Self: Sized,
         F: FnMut(&Self::Item) -> B,
     {
+        self.max_by_key(f)
+    }
+
+    /// Returns the element that gives the maximum value from the
+    /// specified function.
+    ///
+    /// Returns the rightmost element if the comparison determines two elements
+    /// to be equally maximum.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(*a.iter().max_by_key(|x| x.abs()).unwrap(), -10);
+    /// ```
+    #[inline]
+    #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
+    fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
+        where Self: Sized, F: FnMut(&Self::Item) -> B,
+    {
         select_fold1(self,
                      f,
                      // switch to y even if it is only equal, to preserve
@@ -1933,6 +1955,7 @@ pub trait Iterator {
     ///
     /// ```
     /// #![feature(iter_cmp)]
+    /// #![allow(deprecated)]
     ///
     /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
@@ -1941,10 +1964,30 @@ pub trait Iterator {
     #[unstable(feature = "iter_cmp",
                reason = "may want to produce an Ordering directly; see #15311",
                issue = "27724")]
+    #[rustc_deprecated(reason = "renamed to min_by_key", since = "1.6.0")]
     fn min_by<B: Ord, F>(self, f: F) -> Option<Self::Item> where
         Self: Sized,
         F: FnMut(&Self::Item) -> B,
     {
+        self.min_by_key(f)
+    }
+
+    /// Returns the element that gives the minimum value from the
+    /// specified function.
+    ///
+    /// Returns the latest element if the comparison determines two elements
+    /// to be equally minimum.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let a = [-3_i32, 0, 1, 5, -10];
+    /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0);
+    /// ```
+    #[stable(feature = "iter_cmp_by_key", since = "1.6.0")]
+    fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
+        where Self: Sized, F: FnMut(&Self::Item) -> B,
+    {
         select_fold1(self,
                      f,
                      // only switch to y if it is strictly smaller, to
@@ -3588,7 +3631,7 @@ impl<I: Iterator> Peekable<I> {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(core)]
+    /// #![feature(peekable_is_empty)]
     ///
     /// let xs = [1, 2, 3];
     ///
@@ -3604,7 +3647,7 @@ impl<I: Iterator> Peekable<I> {
     ///
     /// assert_eq!(iter.is_empty(), true);
     /// ```
-    #[unstable(feature = "core", issue = "27701")]
+    #[unstable(feature = "peekable_is_empty", issue = "27701")]
     #[inline]
     pub fn is_empty(&mut self) -> bool {
         self.peek().is_none()
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index f8bda4b6b2b..86f2e3bcec3 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -52,18 +52,16 @@
 // Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
 #![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "core"]
-#![unstable(feature = "core",
-            reason = "the libcore library has not yet been scrutinized for \
-                      stabilization in terms of structure and naming",
-            issue = "27701")]
+#![stable(feature = "core", since = "1.6.0")]
 #![cfg_attr(stage0, staged_api)]
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
        html_playground_url = "https://play.rust-lang.org/",
-       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
-#![doc(test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
+       issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
+       test(no_crate_inject, attr(deny(warnings))),
+       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
 
 #![no_core]
 #![deny(missing_docs)]
@@ -91,9 +89,6 @@
 #[macro_use]
 mod macros;
 
-#[macro_use]
-mod cmp_macros;
-
 #[path = "num/float_macros.rs"]
 #[macro_use]
 mod float_macros;
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index bc8656b32b8..03d3cb11b3e 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -11,6 +11,7 @@
 /// Entry point of thread panic, for details, see std::macros
 #[macro_export]
 #[allow_internal_unstable]
+#[stable(feature = "core", since = "1.6.0")]
 macro_rules! panic {
     () => (
         panic!("explicit panic")
@@ -154,21 +155,47 @@ macro_rules! debug_assert {
 /// debug_assert_eq!(a, b);
 /// ```
 #[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! debug_assert_eq {
     ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
 }
 
-/// Short circuiting evaluation on Err
+/// Helper macro for unwrapping `Result` values while returning early with an
+/// error if the value of the expression is `Err`. Can only be used in
+/// functions that return `Result` because of the early return of `Err` that
+/// it provides.
+///
+/// # Examples
 ///
-/// `libstd` contains a more general `try!` macro that uses `From<E>`.
+/// ```
+/// use std::io;
+/// use std::fs::File;
+/// use std::io::prelude::*;
+///
+/// fn write_to_file_using_try() -> Result<(), io::Error> {
+///     let mut file = try!(File::create("my_best_friends.txt"));
+///     try!(file.write_all(b"This is a list of my best friends."));
+///     println!("I wrote to the file");
+///     Ok(())
+/// }
+/// // This is equivalent to:
+/// fn write_to_file_using_match() -> Result<(), io::Error> {
+///     let mut file = try!(File::create("my_best_friends.txt"));
+///     match file.write_all(b"This is a list of my best friends.") {
+///         Ok(_) => (),
+///         Err(e) => return Err(e),
+///     }
+///     println!("I wrote to the file");
+///     Ok(())
+/// }
+/// ```
 #[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! try {
-    ($e:expr) => ({
-        use $crate::result::Result::{Ok, Err};
-
-        match $e {
-            Ok(e) => e,
-            Err(e) => return Err(e),
+    ($expr:expr) => (match $expr {
+        $crate::result::Result::Ok(val) => val,
+        $crate::result::Result::Err(err) => {
+            return $crate::result::Result::Err($crate::convert::From::from(err))
         }
     })
 }
@@ -194,6 +221,7 @@ macro_rules! try {
 /// assert_eq!(w, b"testformatted arguments");
 /// ```
 #[macro_export]
+#[stable(feature = "core", since = "1.6.0")]
 macro_rules! write {
     ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*)))
 }
@@ -271,9 +299,7 @@ macro_rules! writeln {
 /// }
 /// ```
 #[macro_export]
-#[unstable(feature = "core",
-           reason = "relationship with panic is unclear",
-           issue = "27701")]
+#[stable(feature = "core", since = "1.6.0")]
 macro_rules! unreachable {
     () => ({
         panic!("internal error: entered unreachable code")
@@ -334,9 +360,7 @@ macro_rules! unreachable {
 /// }
 /// ```
 #[macro_export]
-#[unstable(feature = "core",
-           reason = "relationship with panic is unclear",
-           issue = "27701")]
+#[stable(feature = "core", since = "1.6.0")]
 macro_rules! unimplemented {
     () => (panic!("not yet implemented"))
 }
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 1261bd0388c..359d15640f9 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -243,14 +243,14 @@ impl Float for f32 {
     /// Returns `true` if `self` is positive, including `+0.0` and
     /// `Float::infinity()`.
     #[inline]
-    fn is_positive(self) -> bool {
+    fn is_sign_positive(self) -> bool {
         self > 0.0 || (1.0 / self) == Float::infinity()
     }
 
     /// Returns `true` if `self` is negative, including `-0.0` and
     /// `Float::neg_infinity()`.
     #[inline]
-    fn is_negative(self) -> bool {
+    fn is_sign_negative(self) -> bool {
         self < 0.0 || (1.0 / self) == Float::neg_infinity()
     }
 
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index c4a24631552..1a6acc5f4ab 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -243,14 +243,14 @@ impl Float for f64 {
     /// Returns `true` if `self` is positive, including `+0.0` and
     /// `Float::infinity()`.
     #[inline]
-    fn is_positive(self) -> bool {
+    fn is_sign_positive(self) -> bool {
         self > 0.0 || (1.0 / self) == Float::infinity()
     }
 
     /// Returns `true` if `self` is negative, including `-0.0` and
     /// `Float::neg_infinity()`.
     #[inline]
-    fn is_negative(self) -> bool {
+    fn is_sign_negative(self) -> bool {
         self < 0.0 || (1.0 / self) == Float::neg_infinity()
     }
 
diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs
index 57d4bccbfa6..46f3c463ff0 100644
--- a/src/libcore/num/flt2dec/mod.rs
+++ b/src/libcore/num/flt2dec/mod.rs
@@ -132,7 +132,6 @@ functions.
 
 use prelude::v1::*;
 use i16;
-use slice::bytes;
 pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded};
 
 pub mod estimator;
@@ -211,7 +210,7 @@ impl<'a> Part<'a> {
                     }
                 }
                 Part::Copy(buf) => {
-                    bytes::copy_memory(buf, out);
+                    out.clone_from_slice(buf);
                 }
             }
             Some(len)
@@ -246,7 +245,7 @@ impl<'a> Formatted<'a> {
     /// (It may still leave partially written bytes in the buffer; do not rely on that.)
     pub fn write(&self, out: &mut [u8]) -> Option<usize> {
         if out.len() < self.sign.len() { return None; }
-        bytes::copy_memory(self.sign, out);
+        out.clone_from_slice(self.sign);
 
         let mut written = self.sign.len();
         for part in self.parts {
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index fdff49b1a57..e1e5c01adb7 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1748,62 +1748,96 @@ pub enum FpCategory {
            issue = "27702")]
 pub trait Float: Sized {
     /// Returns the NaN value.
+    #[unstable(feature = "float_extras", reason = "needs removal",
+               issue = "27752")]
     fn nan() -> Self;
     /// Returns the infinite value.
+    #[unstable(feature = "float_extras", reason = "needs removal",
+               issue = "27752")]
     fn infinity() -> Self;
     /// Returns the negative infinite value.
+    #[unstable(feature = "float_extras", reason = "needs removal",
+               issue = "27752")]
     fn neg_infinity() -> Self;
     /// Returns -0.0.
+    #[unstable(feature = "float_extras", reason = "needs removal",
+               issue = "27752")]
     fn neg_zero() -> Self;
     /// Returns 0.0.
+    #[unstable(feature = "float_extras", reason = "needs removal",
+               issue = "27752")]
     fn zero() -> Self;
     /// Returns 1.0.
+    #[unstable(feature = "float_extras", reason = "needs removal",
+               issue = "27752")]
     fn one() -> Self;
     /// Parses the string `s` with the radix `r` as a float.
+    #[unstable(feature = "float_from_str_radix", reason = "recently moved API",
+               issue = "27736")]
+    #[rustc_deprecated(since = "1.4.0",
+                 reason = "unclear how useful or correct this is")]
     fn from_str_radix(s: &str, r: u32) -> Result<Self, ParseFloatError>;
 
     /// Returns true if this value is NaN and false otherwise.
+    #[stable(feature = "core", since = "1.6.0")]
     fn is_nan(self) -> bool;
     /// Returns true if this value is positive infinity or negative infinity and
     /// false otherwise.
+    #[stable(feature = "core", since = "1.6.0")]
     fn is_infinite(self) -> bool;
     /// Returns true if this number is neither infinite nor NaN.
+    #[stable(feature = "core", since = "1.6.0")]
     fn is_finite(self) -> bool;
     /// Returns true if this number is neither zero, infinite, denormal, or NaN.
+    #[stable(feature = "core", since = "1.6.0")]
     fn is_normal(self) -> bool;
     /// Returns the category that this number falls into.
+    #[stable(feature = "core", since = "1.6.0")]
     fn classify(self) -> FpCategory;
 
     /// Returns the mantissa, exponent and sign as integers, respectively.
+    #[unstable(feature = "float_extras", reason = "signature is undecided",
+               issue = "27752")]
     fn integer_decode(self) -> (u64, i16, i8);
 
     /// Computes the absolute value of `self`. Returns `Float::nan()` if the
     /// number is `Float::nan()`.
+    #[stable(feature = "core", since = "1.6.0")]
     fn abs(self) -> Self;
     /// Returns a number that represents the sign of `self`.
     ///
     /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
     /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
     /// - `Float::nan()` if the number is `Float::nan()`
+    #[stable(feature = "core", since = "1.6.0")]
     fn signum(self) -> Self;
+
     /// Returns `true` if `self` is positive, including `+0.0` and
     /// `Float::infinity()`.
-    fn is_positive(self) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
+    fn is_sign_positive(self) -> bool;
     /// Returns `true` if `self` is negative, including `-0.0` and
     /// `Float::neg_infinity()`.
-    fn is_negative(self) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
+    fn is_sign_negative(self) -> bool;
 
     /// Take the reciprocal (inverse) of a number, `1/x`.
+    #[stable(feature = "core", since = "1.6.0")]
     fn recip(self) -> Self;
 
     /// Raise a number to an integer power.
     ///
     /// Using this function is generally faster than using `powf`
+    #[stable(feature = "core", since = "1.6.0")]
     fn powi(self, n: i32) -> Self;
 
     /// Convert radians to degrees.
+    #[unstable(feature = "float_extras", reason = "desirability is unclear",
+               issue = "27752")]
     fn to_degrees(self) -> Self;
     /// Convert degrees to radians.
+    #[unstable(feature = "float_extras", reason = "desirability is unclear",
+               issue = "27752")]
     fn to_radians(self) -> Self;
 }
 
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index c379b8744ac..0abbd70762d 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -1732,7 +1732,7 @@ impl<'a, T: ?Sized> DerefMut for &'a mut T {
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 pub trait Fn<Args> : FnMut<Args> {
     /// This is called when the call operator is used.
-    #[unstable(feature = "core", issue = "27701")]
+    #[unstable(feature = "fn_traits", issue = "29625")]
     extern "rust-call" fn call(&self, args: Args) -> Self::Output;
 }
 
@@ -1743,7 +1743,7 @@ pub trait Fn<Args> : FnMut<Args> {
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 pub trait FnMut<Args> : FnOnce<Args> {
     /// This is called when the call operator is used.
-    #[unstable(feature = "core", issue = "27701")]
+    #[unstable(feature = "fn_traits", issue = "29625")]
     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
 }
 
@@ -1754,11 +1754,11 @@ pub trait FnMut<Args> : FnOnce<Args> {
 #[fundamental] // so that regex can rely that `&str: !FnMut`
 pub trait FnOnce<Args> {
     /// The returned type after the call operator is used.
-    #[unstable(feature = "core", issue = "27701")]
+    #[unstable(feature = "fn_traits", issue = "29625")]
     type Output;
 
     /// This is called when the call operator is used.
-    #[unstable(feature = "core", issue = "27701")]
+    #[unstable(feature = "fn_traits", issue = "29625")]
     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
 }
 
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index f92692a9d71..70175086147 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -61,72 +61,98 @@ use raw::Slice as RawSlice;
 //
 
 /// Extension methods for slices.
-#[allow(missing_docs)] // docs in libcollections
-#[doc(hidden)]
 #[unstable(feature = "core_slice_ext",
            reason = "stable interface provided by `impl [T]` in later crates",
            issue = "27701")]
+#[allow(missing_docs)] // documented elsewhere
 pub trait SliceExt {
     type Item;
 
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_at(&self, mid: usize) -> (&[Self::Item], &[Self::Item]);
+    #[stable(feature = "core", since = "1.6.0")]
     fn iter(&self) -> Iter<Self::Item>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn split<P>(&self, pred: P) -> Split<Self::Item, P>
                     where P: FnMut(&Self::Item) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn splitn<P>(&self, n: usize, pred: P) -> SplitN<Self::Item, P>
                      where P: FnMut(&Self::Item) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn rsplitn<P>(&self,  n: usize, pred: P) -> RSplitN<Self::Item, P>
                       where P: FnMut(&Self::Item) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn windows(&self, size: usize) -> Windows<Self::Item>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn chunks(&self, size: usize) -> Chunks<Self::Item>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn get(&self, index: usize) -> Option<&Self::Item>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn first(&self) -> Option<&Self::Item>;
-    fn tail(&self) -> &[Self::Item];
-    fn init(&self) -> &[Self::Item];
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_first(&self) -> Option<(&Self::Item, &[Self::Item])>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn last(&self) -> Option<&Self::Item>;
+    #[stable(feature = "core", since = "1.6.0")]
     unsafe fn get_unchecked(&self, index: usize) -> &Self::Item;
+    #[stable(feature = "core", since = "1.6.0")]
     fn as_ptr(&self) -> *const Self::Item;
-    fn binary_search_by<F>(&self, f: F) -> Result<usize, usize> where
-        F: FnMut(&Self::Item) -> Ordering;
+    #[stable(feature = "core", since = "1.6.0")]
+    fn binary_search(&self, x: &Self::Item) -> Result<usize, usize>
+        where Self::Item: Ord;
+    #[stable(feature = "core", since = "1.6.0")]
+    fn binary_search_by<F>(&self, f: F) -> Result<usize, usize>
+        where F: FnMut(&Self::Item) -> Ordering;
+    #[stable(feature = "core", since = "1.6.0")]
     fn len(&self) -> usize;
+    #[stable(feature = "core", since = "1.6.0")]
     fn is_empty(&self) -> bool { self.len() == 0 }
+    #[stable(feature = "core", since = "1.6.0")]
     fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn iter_mut(&mut self) -> IterMut<Self::Item>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn first_mut(&mut self) -> Option<&mut Self::Item>;
-    fn tail_mut(&mut self) -> &mut [Self::Item];
-    fn init_mut(&mut self) -> &mut [Self::Item];
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_first_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_last_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn last_mut(&mut self) -> Option<&mut Self::Item>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_mut<P>(&mut self, pred: P) -> SplitMut<Self::Item, P>
                         where P: FnMut(&Self::Item) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<Self::Item, P>
                      where P: FnMut(&Self::Item) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn rsplitn_mut<P>(&mut self,  n: usize, pred: P) -> RSplitNMut<Self::Item, P>
                       where P: FnMut(&Self::Item) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<Self::Item>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn swap(&mut self, a: usize, b: usize);
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_at_mut(&mut self, mid: usize) -> (&mut [Self::Item], &mut [Self::Item]);
+    #[stable(feature = "core", since = "1.6.0")]
     fn reverse(&mut self);
+    #[stable(feature = "core", since = "1.6.0")]
     unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut Self::Item;
+    #[stable(feature = "core", since = "1.6.0")]
     fn as_mut_ptr(&mut self) -> *mut Self::Item;
 
-    fn position_elem(&self, t: &Self::Item) -> Option<usize> where Self::Item: PartialEq;
-
-    fn rposition_elem(&self, t: &Self::Item) -> Option<usize> where Self::Item: PartialEq;
-
+    #[stable(feature = "core", since = "1.6.0")]
     fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
 
+    #[stable(feature = "core", since = "1.6.0")]
     fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
 
+    #[stable(feature = "core", since = "1.6.0")]
     fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
 
-    fn binary_search(&self, x: &Self::Item) -> Result<usize, usize> where Self::Item: Ord;
-    fn next_permutation(&mut self) -> bool where Self::Item: Ord;
-    fn prev_permutation(&mut self) -> bool where Self::Item: Ord;
-
+    #[unstable(feature = "clone_from_slice", issue= "27750")]
     fn clone_from_slice(&mut self, &[Self::Item]) -> usize where Self::Item: Clone;
 }
 
@@ -242,17 +268,11 @@ impl<T> SliceExt for [T] {
     }
 
     #[inline]
-    fn tail(&self) -> &[T] { &self[1..] }
-
-    #[inline]
     fn split_first(&self) -> Option<(&T, &[T])> {
         if self.is_empty() { None } else { Some((&self[0], &self[1..])) }
     }
 
     #[inline]
-    fn init(&self) -> &[T] { &self[..self.len() - 1] }
-
-    #[inline]
     fn split_last(&self) -> Option<(&T, &[T])> {
         let len = self.len();
         if len == 0 { None } else { Some((&self[len - 1], &self[..(len - 1)])) }
@@ -347,9 +367,6 @@ impl<T> SliceExt for [T] {
     }
 
     #[inline]
-    fn tail_mut(&mut self) -> &mut [T] { &mut self[1 ..] }
-
-    #[inline]
     fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
         if self.is_empty() { None } else {
             let split = self.split_at_mut(1);
@@ -358,12 +375,6 @@ impl<T> SliceExt for [T] {
     }
 
     #[inline]
-    fn init_mut(&mut self) -> &mut [T] {
-        let len = self.len();
-        &mut self[.. (len - 1)]
-    }
-
-    #[inline]
     fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
         let len = self.len();
         if len == 0 { None } else {
@@ -445,16 +456,6 @@ impl<T> SliceExt for [T] {
     }
 
     #[inline]
-    fn position_elem(&self, x: &T) -> Option<usize> where T: PartialEq {
-        self.iter().position(|y| *x == *y)
-    }
-
-    #[inline]
-    fn rposition_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
-        self.iter().rposition(|x| *x == *t)
-    }
-
-    #[inline]
     fn contains(&self, x: &T) -> bool where T: PartialEq {
         self.iter().any(|elt| *x == *elt)
     }
@@ -475,66 +476,6 @@ impl<T> SliceExt for [T] {
         self.binary_search_by(|p| p.cmp(x))
     }
 
-    fn next_permutation(&mut self) -> bool where T: Ord {
-        // These cases only have 1 permutation each, so we can't do anything.
-        if self.len() < 2 { return false; }
-
-        // Step 1: Identify the longest, rightmost weakly decreasing part of the vector
-        let mut i = self.len() - 1;
-        while i > 0 && self[i-1] >= self[i] {
-            i -= 1;
-        }
-
-        // If that is the entire vector, this is the last-ordered permutation.
-        if i == 0 {
-            return false;
-        }
-
-        // Step 2: Find the rightmost element larger than the pivot (i-1)
-        let mut j = self.len() - 1;
-        while j >= i && self[j] <= self[i-1]  {
-            j -= 1;
-        }
-
-        // Step 3: Swap that element with the pivot
-        self.swap(j, i-1);
-
-        // Step 4: Reverse the (previously) weakly decreasing part
-        self[i..].reverse();
-
-        true
-    }
-
-    fn prev_permutation(&mut self) -> bool where T: Ord {
-        // These cases only have 1 permutation each, so we can't do anything.
-        if self.len() < 2 { return false; }
-
-        // Step 1: Identify the longest, rightmost weakly increasing part of the vector
-        let mut i = self.len() - 1;
-        while i > 0 && self[i-1] <= self[i] {
-            i -= 1;
-        }
-
-        // If that is the entire vector, this is the first-ordered permutation.
-        if i == 0 {
-            return false;
-        }
-
-        // Step 2: Reverse the weakly increasing part
-        self[i..].reverse();
-
-        // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
-        let mut j = self.len() - 1;
-        while j >= i && self[j-1] < self[i-1]  {
-            j -= 1;
-        }
-
-        // Step 4: Swap that element with the pivot
-        self.swap(i-1, j);
-
-        true
-    }
-
     #[inline]
     fn clone_from_slice(&mut self, src: &[T]) -> usize where T: Clone {
         let min = cmp::min(self.len(), src.len());
@@ -1514,6 +1455,9 @@ pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
 /// Operations on `[u8]`.
 #[unstable(feature = "slice_bytes", reason = "needs review",
            issue = "27740")]
+#[rustc_deprecated(reason = "unidiomatic functions not pulling their weight",
+                   since = "1.6.0")]
+#[allow(deprecated)]
 pub mod bytes {
     use ptr;
     use slice::SliceExt;
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 127c4287f32..7aacdbeb768 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1385,58 +1385,120 @@ pub trait StrExt {
     // NB there are no docs here are they're all located on the StrExt trait in
     // libcollections, not here.
 
+    #[stable(feature = "core", since = "1.6.0")]
     fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
-    fn contains_char<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn chars(&self) -> Chars;
+    #[stable(feature = "core", since = "1.6.0")]
     fn bytes(&self) -> Bytes;
+    #[stable(feature = "core", since = "1.6.0")]
     fn char_indices(&self) -> CharIndices;
+    #[stable(feature = "core", since = "1.6.0")]
     fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
         where P::Searcher: ReverseSearcher<'a>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
         where P::Searcher: ReverseSearcher<'a>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
         where P::Searcher: ReverseSearcher<'a>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
         where P::Searcher: ReverseSearcher<'a>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
         where P::Searcher: ReverseSearcher<'a>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn lines(&self) -> Lines;
+    #[stable(feature = "core", since = "1.6.0")]
+    #[rustc_deprecated(since = "1.6.0", reason = "use lines() instead now")]
     #[allow(deprecated)]
     fn lines_any(&self) -> LinesAny;
-    fn char_len(&self) -> usize;
-    fn slice_chars(&self, begin: usize, end: usize) -> &str;
+    #[stable(feature = "core", since = "1.6.0")]
     unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str;
+    #[stable(feature = "core", since = "1.6.0")]
     unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str;
+    #[stable(feature = "core", since = "1.6.0")]
     fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
         where P::Searcher: ReverseSearcher<'a>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
         where P::Searcher: DoubleEndedSearcher<'a>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str;
+    #[stable(feature = "core", since = "1.6.0")]
     fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
         where P::Searcher: ReverseSearcher<'a>;
+    #[unstable(feature = "str_char",
+               reason = "it is unclear whether this method pulls its weight \
+                         with the existence of the char_indices iterator or \
+                         this method may want to be replaced with checked \
+                         slicing",
+               issue = "27754")]
     fn is_char_boundary(&self, index: usize) -> bool;
+    #[unstable(feature = "str_char",
+               reason = "often replaced by char_indices, this method may \
+                         be removed in favor of just char_at() or eventually \
+                         removed altogether",
+               issue = "27754")]
     fn char_range_at(&self, start: usize) -> CharRange;
+    #[unstable(feature = "str_char",
+               reason = "often replaced by char_indices, this method may \
+                         be removed in favor of just char_at_reverse() or \
+                         eventually removed altogether",
+               issue = "27754")]
     fn char_range_at_reverse(&self, start: usize) -> CharRange;
+    #[unstable(feature = "str_char",
+               reason = "frequently replaced by the chars() iterator, this \
+                         method may be removed or possibly renamed in the \
+                         future; it is normally replaced by chars/char_indices \
+                         iterators or by getting the first char from a \
+                         subslice",
+               issue = "27754")]
     fn char_at(&self, i: usize) -> char;
+    #[unstable(feature = "str_char",
+               reason = "see char_at for more details, but reverse semantics \
+                         are also somewhat unclear, especially with which \
+                         cases generate panics",
+               issue = "27754")]
     fn char_at_reverse(&self, i: usize) -> char;
+    #[stable(feature = "core", since = "1.6.0")]
     fn as_bytes(&self) -> &[u8];
+    #[stable(feature = "core", since = "1.6.0")]
     fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
         where P::Searcher: ReverseSearcher<'a>;
     fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_at(&self, mid: usize) -> (&str, &str);
+    #[stable(feature = "core", since = "1.6.0")]
     fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str);
+    #[unstable(feature = "str_char",
+               reason = "awaiting conventions about shifting and slices and \
+                         may not be warranted with the existence of the chars \
+                         and/or char_indices iterators",
+               issue = "27754")]
     fn slice_shift_char(&self) -> Option<(char, &str)>;
-    fn subslice_offset(&self, inner: &str) -> usize;
+    #[stable(feature = "core", since = "1.6.0")]
     fn as_ptr(&self) -> *const u8;
+    #[stable(feature = "core", since = "1.6.0")]
     fn len(&self) -> usize;
+    #[stable(feature = "core", since = "1.6.0")]
     fn is_empty(&self) -> bool;
+    #[stable(feature = "core", since = "1.6.0")]
     fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
 }
 
@@ -1448,9 +1510,7 @@ fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
           begin, end, s);
 }
 
-#[unstable(feature = "core_str_ext",
-           reason = "stable interface provided by `impl str` in later crates",
-           issue = "27701")]
+#[stable(feature = "core", since = "1.6.0")]
 impl StrExt for str {
     #[inline]
     fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
@@ -1458,11 +1518,6 @@ impl StrExt for str {
     }
 
     #[inline]
-    fn contains_char<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
-        pat.is_contained_in(self)
-    }
-
-    #[inline]
     fn chars(&self) -> Chars {
         Chars{iter: self.as_bytes().iter()}
     }
@@ -1560,32 +1615,6 @@ impl StrExt for str {
     }
 
     #[inline]
-    fn char_len(&self) -> usize { self.chars().count() }
-
-    fn slice_chars(&self, begin: usize, end: usize) -> &str {
-        assert!(begin <= end);
-        let mut count = 0;
-        let mut begin_byte = None;
-        let mut end_byte = None;
-
-        // This could be even more efficient by not decoding,
-        // only finding the char boundaries
-        for (idx, _) in self.char_indices() {
-            if count == begin { begin_byte = Some(idx); }
-            if count == end { end_byte = Some(idx); break; }
-            count += 1;
-        }
-        if begin_byte.is_none() && count == begin { begin_byte = Some(self.len()) }
-        if end_byte.is_none() && count == end { end_byte = Some(self.len()) }
-
-        match (begin_byte, end_byte) {
-            (None, _) => panic!("slice_chars: `begin` is beyond end of string"),
-            (_, None) => panic!("slice_chars: `end` is beyond end of string"),
-            (Some(a), Some(b)) => unsafe { self.slice_unchecked(a, b) }
-        }
-    }
-
-    #[inline]
     unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
         mem::transmute(Slice {
             data: self.as_ptr().offset(begin as isize),
@@ -1774,17 +1803,6 @@ impl StrExt for str {
         }
     }
 
-    fn subslice_offset(&self, inner: &str) -> usize {
-        let a_start = self.as_ptr() as usize;
-        let a_end = a_start + self.len();
-        let b_start = inner.as_ptr() as usize;
-        let b_end = b_start + inner.len();
-
-        assert!(a_start <= b_start);
-        assert!(b_end <= a_end);
-        b_start - a_start
-    }
-
     #[inline]
     fn as_ptr(&self) -> *const u8 {
         self.repr().data