diff options
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/array.rs | 32 | ||||
| -rw-r--r-- | src/libcore/char.rs | 12 | ||||
| -rw-r--r-- | src/libcore/cmp_macros.rs | 47 | ||||
| -rw-r--r-- | src/libcore/fmt/mod.rs | 23 | ||||
| -rw-r--r-- | src/libcore/iter.rs | 47 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 13 | ||||
| -rw-r--r-- | src/libcore/macros.rs | 52 | ||||
| -rw-r--r-- | src/libcore/num/f32.rs | 4 | ||||
| -rw-r--r-- | src/libcore/num/f64.rs | 4 | ||||
| -rw-r--r-- | src/libcore/num/flt2dec/mod.rs | 5 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 38 | ||||
| -rw-r--r-- | src/libcore/ops.rs | 8 | ||||
| -rw-r--r-- | src/libcore/slice.rs | 146 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 116 |
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 |
