summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-04-22 00:01:29 +0000
committerbors <bors@rust-lang.org>2018-04-22 00:01:29 +0000
commitd5616e1f18abb46071581d096994a0ff6581e3f9 (patch)
treeaddedaf5480f673bd54b0b0ff553b89ca5f1a572
parentaa7ce896f2c41550f7f6cf3dadb21bacc69cc912 (diff)
parent70fdd1b5c0f6a0673fcf924b3d8880af034bdee0 (diff)
downloadrust-d5616e1f18abb46071581d096994a0ff6581e3f9.tar.gz
Auto merge of #49896 - SimonSapin:inherent, r=alexcrichton
Add inherent methods in libcore for [T], [u8], str, f32, and f64 # Background Primitive types are defined by the language, they don’t have a type definition like `pub struct Foo { … }` in any crate. So they don’t “belong” to any crate as far as `impl` coherence is concerned, and on principle no crate would be able to define inherent methods for them, without a trait. Since we want these types to have inherent methods anyway, the standard library (with cooperation from the compiler) bends this rule with code like [`#[lang = "u8"] impl u8 { /*…*/ }`](https://github.com/rust-lang/rust/blob/1.25.0/src/libcore/num/mod.rs#L2244-L2245). The `#[lang]` attribute is permanently-unstable and never intended to be used outside of the standard library. Each lang item can only be defined once. Before this PR there is one impl-coherence-rule-bending lang item per primitive type (plus one for `[u8]`, which overlaps with `[T]`). And so one `impl` block each. These blocks for `str`, `[T]` and `[u8]` are in liballoc rather than libcore because *some* of the methods (like `<[T]>::to_vec(&self) -> Vec<T> where T: Clone`) need a global memory allocator which we don’t want to make a requirement in libcore. Similarly, `impl f32` and `impl f64` are in libstd because some of the methods are based on FFI calls to C’s `libm` and we want, as much as possible, libcore not to require “runtime support”. In libcore, the methods of `str` and `[T]` that don’t allocate are made available through two **unstable traits** `StrExt` and `SliceExt` (so the traits can’t be *named* by programs on the Stable release channel) that have **stable methods** and are re-exported in the libcore prelude (so that programs on Stable can *call* these methods anyway). Non-allocating `[u8]` methods are not available in libcore: https://github.com/rust-lang/rust/issues/45803. Some `f32` and `f64` methods are in an unstable `core::num::Float` trait with stable methods, but that one is **not in the libcore prelude**. (So as far as Stable programs are concerns it doesn’t exist, and I don’t know what the point was to mark these methods `#[stable]`.) https://github.com/rust-lang/rust/issues/32110 is the tracking issue for these unstable traits. # High-level proposal Since the standard library is already bending the rules, why not bend them *a little more*? By defining a few additional lang items, the compiler can allow the standard library to have *two* `impl` blocks (in different crates) for some primitive types. The `StrExt` and `SliceExt` traits still exist for now so that we can bootstrap from a previous-version compiler that doesn’t have these lang items yet, but they can be removed in next release cycle. (`Float` is used internally and needs to be public for libcore unit tests, but was already `#[doc(hidden)]`.) I don’t know if https://github.com/rust-lang/rust/issues/32110 should be closed by this PR, or only when the traits are entirely removed after we make a new bootstrap compiler. # Float methods Among the methods of the `core::num::Float` trait, three are based on LLVM intrinsics: `abs`, `signum`, and `powi`. PR https://github.com/rust-lang/rust/pull/27823 “Remove dependencies on libm functions from libcore” moved a bunch of `core::num::Float` methods back to libstd, but left these three behind. However they aren’t specifically discussed in the PR thread. The `compiler_builtins` crate defines `__powisf2` and `__powidf2` functions that look like implementations of `powi`, but I couldn’t find a connection with the `llvm.powi.f32` and `llvm.powi.f32` intrinsics by grepping through LLVM’s code. In discussion starting at https://github.com/rust-lang/rust/issues/32110#issuecomment-370647922 Alex says that we do not want methods in libcore that require “runtime support”, but it’s not clear whether that applies to these `abs`, `signum`, or `powi`. In doubt, I’ve **removed** them for the trait and moved them to inherent methods in libstd for now. We can move them back later (or in this PR) if we decide that’s appropriate. # Change details For users on the Stable release channel: * I believe this PR does not make any breaking change * Some methods for `[u8]`, `f32`, and `f64` are newly available to `#![no_std]` users (fixes https://github.com/rust-lang/rust/issues/45803) * There should be no visible change for `std` users in terms of what programs compile or what their behavior is. (Only in compiler error messages, possibly.) For Nightly users, additionally: * The unstable `StrExt` and `SliceExt` traits are gone * Their methods are now inherent methods of `str` and `[T]` (so only code that explicitly named the traits should be affected, not "normal" method calls) * The `abs`, `signum` and `powi` methods of the `Float` trait are gone * The `Float` trait’s unstable feature name changed to `float_internals` with no associated tracking issue, to reflect it being a permanently unstable implementation detail rather than a public API on a path to stabilization. * Its remaining methods are now inherent methods of `f32` and `f64`. ----- CC @rust-lang/libs for the API changes, @rust-lang/compiler for the new lang items
-rw-r--r--src/liballoc/lib.rs4
-rw-r--r--src/liballoc/slice.rs1454
-rw-r--r--src/liballoc/str.rs1731
-rw-r--r--src/liballoc/vec.rs1
-rw-r--r--src/libcore/internal_macros.rs13
-rw-r--r--src/libcore/lib.rs5
-rw-r--r--src/libcore/num/f32.rs311
-rw-r--r--src/libcore/num/f64.rs323
-rw-r--r--src/libcore/num/mod.rs49
-rw-r--r--src/libcore/prelude/v1.rs2
-rw-r--r--src/libcore/slice/mod.rs1476
-rw-r--r--src/libcore/str/mod.rs1770
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/librustc/middle/lang_items.rs5
-rw-r--r--src/librustc_typeck/check/method/probe.rs15
-rw-r--r--src/librustc_typeck/coherence/inherent_impls.rs28
-rw-r--r--src/librustc_typeck/diagnostics.rs10
-rw-r--r--src/librustdoc/clean/inline.rs5
-rw-r--r--src/libstd/f32.rs294
-rw-r--r--src/libstd/f64.rs302
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libstd/sys_common/wtf8.rs14
-rw-r--r--src/test/compile-fail/single-primitive-inherent-impl.rs2
-rw-r--r--src/test/rustdoc/issue-23511.rs2
-rw-r--r--src/test/ui/impl-trait/method-suggestion-no-duplication.stderr4
-rw-r--r--src/test/ui/macros/macro-backtrace-invalid-internals.rs4
-rw-r--r--src/test/ui/macros/macro-backtrace-invalid-internals.stderr16
-rw-r--r--src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs8
-rw-r--r--src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr14
29 files changed, 3980 insertions, 3886 deletions
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 163aef61b43..6399be98cd5 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -75,7 +75,7 @@
#![deny(missing_debug_implementations)]
#![cfg_attr(test, allow(deprecated))] // rand
-#![cfg_attr(not(test), feature(core_float))]
+#![cfg_attr(all(not(test), stage0), feature(float_internals))]
#![cfg_attr(not(test), feature(exact_size_is_empty))]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(rand, test))]
@@ -90,6 +90,8 @@
#![feature(collections_range)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
+#![cfg_attr(stage0, feature(core_slice_ext))]
+#![cfg_attr(stage0, feature(core_str_ext))]
#![feature(custom_attribute)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 33e652856e8..4594263c01f 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -101,7 +101,7 @@ use core::cmp::Ordering::{self, Less};
use core::mem::size_of;
use core::mem;
use core::ptr;
-use core::slice as core_slice;
+#[cfg(stage0)] use core::slice::SliceExt;
use core::{u8, u16, u32};
use borrow::{Borrow, BorrowMut, ToOwned};
@@ -171,1059 +171,12 @@ mod hack {
}
}
-#[lang = "slice"]
+#[cfg_attr(stage0, lang = "slice")]
+#[cfg_attr(not(stage0), lang = "slice_alloc")]
#[cfg(not(test))]
impl<T> [T] {
- /// Returns the number of elements in the slice.
- ///
- /// # Examples
- ///
- /// ```
- /// let a = [1, 2, 3];
- /// assert_eq!(a.len(), 3);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn len(&self) -> usize {
- core_slice::SliceExt::len(self)
- }
-
- /// Returns `true` if the slice has a length of 0.
- ///
- /// # Examples
- ///
- /// ```
- /// let a = [1, 2, 3];
- /// assert!(!a.is_empty());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_empty(&self) -> bool {
- core_slice::SliceExt::is_empty(self)
- }
-
- /// Returns the first element of the slice, or `None` if it is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = [10, 40, 30];
- /// assert_eq!(Some(&10), v.first());
- ///
- /// let w: &[i32] = &[];
- /// assert_eq!(None, w.first());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn first(&self) -> Option<&T> {
- core_slice::SliceExt::first(self)
- }
-
- /// Returns a mutable pointer to the first element of the slice, or `None` if it is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &mut [0, 1, 2];
- ///
- /// if let Some(first) = x.first_mut() {
- /// *first = 5;
- /// }
- /// assert_eq!(x, &[5, 1, 2]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn first_mut(&mut self) -> Option<&mut T> {
- core_slice::SliceExt::first_mut(self)
- }
-
- /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &[0, 1, 2];
- ///
- /// if let Some((first, elements)) = x.split_first() {
- /// assert_eq!(first, &0);
- /// assert_eq!(elements, &[1, 2]);
- /// }
- /// ```
- #[stable(feature = "slice_splits", since = "1.5.0")]
- #[inline]
- pub fn split_first(&self) -> Option<(&T, &[T])> {
- core_slice::SliceExt::split_first(self)
- }
-
- /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &mut [0, 1, 2];
- ///
- /// if let Some((first, elements)) = x.split_first_mut() {
- /// *first = 3;
- /// elements[0] = 4;
- /// elements[1] = 5;
- /// }
- /// assert_eq!(x, &[3, 4, 5]);
- /// ```
- #[stable(feature = "slice_splits", since = "1.5.0")]
- #[inline]
- pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
- core_slice::SliceExt::split_first_mut(self)
- }
-
- /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &[0, 1, 2];
- ///
- /// if let Some((last, elements)) = x.split_last() {
- /// assert_eq!(last, &2);
- /// assert_eq!(elements, &[0, 1]);
- /// }
- /// ```
- #[stable(feature = "slice_splits", since = "1.5.0")]
- #[inline]
- pub fn split_last(&self) -> Option<(&T, &[T])> {
- core_slice::SliceExt::split_last(self)
-
- }
-
- /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &mut [0, 1, 2];
- ///
- /// if let Some((last, elements)) = x.split_last_mut() {
- /// *last = 3;
- /// elements[0] = 4;
- /// elements[1] = 5;
- /// }
- /// assert_eq!(x, &[4, 5, 3]);
- /// ```
- #[stable(feature = "slice_splits", since = "1.5.0")]
- #[inline]
- pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
- core_slice::SliceExt::split_last_mut(self)
- }
-
- /// Returns the last element of the slice, or `None` if it is empty.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = [10, 40, 30];
- /// assert_eq!(Some(&30), v.last());
- ///
- /// let w: &[i32] = &[];
- /// assert_eq!(None, w.last());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn last(&self) -> Option<&T> {
- core_slice::SliceExt::last(self)
- }
-
- /// Returns a mutable pointer to the last item in the slice.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &mut [0, 1, 2];
- ///
- /// if let Some(last) = x.last_mut() {
- /// *last = 10;
- /// }
- /// assert_eq!(x, &[0, 1, 10]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn last_mut(&mut self) -> Option<&mut T> {
- core_slice::SliceExt::last_mut(self)
- }
-
- /// Returns a reference to an element or subslice depending on the type of
- /// index.
- ///
- /// - If given a position, returns a reference to the element at that
- /// position or `None` if out of bounds.
- /// - If given a range, returns the subslice corresponding to that range,
- /// or `None` if out of bounds.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = [10, 40, 30];
- /// assert_eq!(Some(&40), v.get(1));
- /// assert_eq!(Some(&[10, 40][..]), v.get(0..2));
- /// assert_eq!(None, v.get(3));
- /// assert_eq!(None, v.get(0..4));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn get<I>(&self, index: I) -> Option<&I::Output>
- where I: SliceIndex<Self>
- {
- core_slice::SliceExt::get(self, index)
- }
-
- /// Returns a mutable reference to an element or subslice depending on the
- /// type of index (see [`get`]) or `None` if the index is out of bounds.
- ///
- /// [`get`]: #method.get
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &mut [0, 1, 2];
- ///
- /// if let Some(elem) = x.get_mut(1) {
- /// *elem = 42;
- /// }
- /// assert_eq!(x, &[0, 42, 2]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
- where I: SliceIndex<Self>
- {
- core_slice::SliceExt::get_mut(self, index)
- }
-
- /// Returns a reference to an element or subslice, without doing bounds
- /// checking.
- ///
- /// This is generally not recommended, use with caution! For a safe
- /// alternative see [`get`].
- ///
- /// [`get`]: #method.get
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &[1, 2, 4];
- ///
- /// unsafe {
- /// assert_eq!(x.get_unchecked(1), &2);
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
- where I: SliceIndex<Self>
- {
- core_slice::SliceExt::get_unchecked(self, index)
- }
-
- /// Returns a mutable reference to an element or subslice, without doing
- /// bounds checking.
- ///
- /// This is generally not recommended, use with caution! For a safe
- /// alternative see [`get_mut`].
- ///
- /// [`get_mut`]: #method.get_mut
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &mut [1, 2, 4];
- ///
- /// unsafe {
- /// let elem = x.get_unchecked_mut(1);
- /// *elem = 13;
- /// }
- /// assert_eq!(x, &[1, 13, 4]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
- where I: SliceIndex<Self>
- {
- core_slice::SliceExt::get_unchecked_mut(self, index)
- }
-
- /// Returns a raw pointer to the slice's buffer.
- ///
- /// The caller must ensure that the slice outlives the pointer this
- /// function returns, or else it will end up pointing to garbage.
- ///
- /// Modifying the container referenced by this slice may cause its buffer
- /// to be reallocated, which would also make any pointers to it invalid.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &[1, 2, 4];
- /// let x_ptr = x.as_ptr();
- ///
- /// unsafe {
- /// for i in 0..x.len() {
- /// assert_eq!(x.get_unchecked(i), &*x_ptr.offset(i as isize));
- /// }
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn as_ptr(&self) -> *const T {
- core_slice::SliceExt::as_ptr(self)
- }
-
- /// Returns an unsafe mutable pointer to the slice's buffer.
- ///
- /// The caller must ensure that the slice outlives the pointer this
- /// function returns, or else it will end up pointing to garbage.
- ///
- /// Modifying the container referenced by this slice may cause its buffer
- /// to be reallocated, which would also make any pointers to it invalid.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &mut [1, 2, 4];
- /// let x_ptr = x.as_mut_ptr();
- ///
- /// unsafe {
- /// for i in 0..x.len() {
- /// *x_ptr.offset(i as isize) += 2;
- /// }
- /// }
- /// assert_eq!(x, &[3, 4, 6]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn as_mut_ptr(&mut self) -> *mut T {
- core_slice::SliceExt::as_mut_ptr(self)
- }
-
- /// Swaps two elements in the slice.
- ///
- /// # Arguments
- ///
- /// * a - The index of the first element
- /// * b - The index of the second element
- ///
- /// # Panics
- ///
- /// Panics if `a` or `b` are out of bounds.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = ["a", "b", "c", "d"];
- /// v.swap(1, 3);
- /// assert!(v == ["a", "d", "c", "b"]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn swap(&mut self, a: usize, b: usize) {
- core_slice::SliceExt::swap(self, a, b)
- }
-
- /// Reverses the order of elements in the slice, in place.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = [1, 2, 3];
- /// v.reverse();
- /// assert!(v == [3, 2, 1]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn reverse(&mut self) {
- core_slice::SliceExt::reverse(self)
- }
-
- /// Returns an iterator over the slice.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &[1, 2, 4];
- /// let mut iterator = x.iter();
- ///
- /// assert_eq!(iterator.next(), Some(&1));
- /// assert_eq!(iterator.next(), Some(&2));
- /// assert_eq!(iterator.next(), Some(&4));
- /// assert_eq!(iterator.next(), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn iter(&self) -> Iter<T> {
- core_slice::SliceExt::iter(self)
- }
-
- /// Returns an iterator that allows modifying each value.
- ///
- /// # Examples
- ///
- /// ```
- /// let x = &mut [1, 2, 4];
- /// for elem in x.iter_mut() {
- /// *elem += 2;
- /// }
- /// assert_eq!(x, &[3, 4, 6]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn iter_mut(&mut self) -> IterMut<T> {
- core_slice::SliceExt::iter_mut(self)
- }
-
- /// Returns an iterator over all contiguous windows of length
- /// `size`. The windows overlap. If the slice is shorter than
- /// `size`, the iterator returns no values.
- ///
- /// # Panics
- ///
- /// Panics if `size` is 0.
- ///
- /// # Examples
- ///
- /// ```
- /// let slice = ['r', 'u', 's', 't'];
- /// let mut iter = slice.windows(2);
- /// assert_eq!(iter.next().unwrap(), &['r', 'u']);
- /// assert_eq!(iter.next().unwrap(), &['u', 's']);
- /// assert_eq!(iter.next().unwrap(), &['s', 't']);
- /// assert!(iter.next().is_none());
- /// ```
- ///
- /// If the slice is shorter than `size`:
- ///
- /// ```
- /// let slice = ['f', 'o', 'o'];
- /// let mut iter = slice.windows(4);
- /// assert!(iter.next().is_none());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn windows(&self, size: usize) -> Windows<T> {
- core_slice::SliceExt::windows(self, size)
- }
-
- /// Returns an iterator over `chunk_size` elements of the slice at a
- /// time. The chunks are slices and do not overlap. If `chunk_size` does
- /// not divide the length of the slice, then the last chunk will
- /// not have length `chunk_size`.
- ///
- /// See [`exact_chunks`] for a variant of this iterator that returns chunks
- /// of always exactly `chunk_size` elements.
- ///
- /// # Panics
- ///
- /// Panics if `chunk_size` is 0.
- ///
- /// # Examples
- ///
- /// ```
- /// let slice = ['l', 'o', 'r', 'e', 'm'];
- /// let mut iter = slice.chunks(2);
- /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
- /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
- /// assert_eq!(iter.next().unwrap(), &['m']);
- /// assert!(iter.next().is_none());
- /// ```
- ///
- /// [`exact_chunks`]: #method.exact_chunks
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn chunks(&self, chunk_size: usize) -> Chunks<T> {
- core_slice::SliceExt::chunks(self, chunk_size)
- }
-
- /// Returns an iterator over `chunk_size` elements of the slice at a
- /// time. The chunks are slices and do not overlap. If `chunk_size` does
- /// not divide the length of the slice, then the last up to `chunk_size-1`
- /// elements will be omitted.
- ///
- /// Due to each chunk having exactly `chunk_size` elements, the compiler
- /// can often optimize the resulting code better than in the case of
- /// [`chunks`].
- ///
- /// # Panics
- ///
- /// Panics if `chunk_size` is 0.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(exact_chunks)]
- ///
- /// let slice = ['l', 'o', 'r', 'e', 'm'];
- /// let mut iter = slice.exact_chunks(2);
- /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
- /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
- /// assert!(iter.next().is_none());
- /// ```
- ///
- /// [`chunks`]: #method.chunks
- #[unstable(feature = "exact_chunks", issue = "47115")]
- #[inline]
- pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
- core_slice::SliceExt::exact_chunks(self, chunk_size)
- }
-
- /// Returns an iterator over `chunk_size` elements of the slice at a time.
- /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
- /// not divide the length of the slice, then the last chunk will not
- /// have length `chunk_size`.
- ///
- /// See [`exact_chunks_mut`] for a variant of this iterator that returns chunks
- /// of always exactly `chunk_size` elements.
- ///
- /// # Panics
- ///
- /// Panics if `chunk_size` is 0.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = &mut [0, 0, 0, 0, 0];
- /// let mut count = 1;
- ///
- /// for chunk in v.chunks_mut(2) {
- /// for elem in chunk.iter_mut() {
- /// *elem += count;
- /// }
- /// count += 1;
- /// }
- /// assert_eq!(v, &[1, 1, 2, 2, 3]);
- /// ```
- ///
- /// [`exact_chunks_mut`]: #method.exact_chunks_mut
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
- core_slice::SliceExt::chunks_mut(self, chunk_size)
- }
-
- /// Returns an iterator over `chunk_size` elements of the slice at a time.
- /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
- /// not divide the length of the slice, then the last up to `chunk_size-1`
- /// elements will be omitted.
- ///
- ///
- /// Due to each chunk having exactly `chunk_size` elements, the compiler
- /// can often optimize the resulting code better than in the case of
- /// [`chunks_mut`].
- ///
- /// # Panics
- ///
- /// Panics if `chunk_size` is 0.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(exact_chunks)]
- ///
- /// let v = &mut [0, 0, 0, 0, 0];
- /// let mut count = 1;
- ///
- /// for chunk in v.exact_chunks_mut(2) {
- /// for elem in chunk.iter_mut() {
- /// *elem += count;
- /// }
- /// count += 1;
- /// }
- /// assert_eq!(v, &[1, 1, 2, 2, 0]);
- /// ```
- ///
- /// [`chunks_mut`]: #method.chunks_mut
- #[unstable(feature = "exact_chunks", issue = "47115")]
- #[inline]
- pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
- core_slice::SliceExt::exact_chunks_mut(self, chunk_size)
- }
-
- /// Divides one slice into two at an index.
- ///
- /// The first will contain all indices from `[0, mid)` (excluding
- /// the index `mid` itself) and the second will contain all
- /// indices from `[mid, len)` (excluding the index `len` itself).
- ///
- /// # Panics
- ///
- /// Panics if `mid > len`.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = [1, 2, 3, 4, 5, 6];
- ///
- /// {
- /// let (left, right) = v.split_at(0);
- /// assert!(left == []);
- /// assert!(right == [1, 2, 3, 4, 5, 6]);
- /// }
- ///
- /// {
- /// let (left, right) = v.split_at(2);
- /// assert!(left == [1, 2]);
- /// assert!(right == [3, 4, 5, 6]);
- /// }
- ///
- /// {
- /// let (left, right) = v.split_at(6);
- /// assert!(left == [1, 2, 3, 4, 5, 6]);
- /// assert!(right == []);
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
- core_slice::SliceExt::split_at(self, mid)
- }
-
- /// Divides one mutable slice into two at an index.
- ///
- /// The first will contain all indices from `[0, mid)` (excluding
- /// the index `mid` itself) and the second will contain all
- /// indices from `[mid, len)` (excluding the index `len` itself).
- ///
- /// # Panics
- ///
- /// Panics if `mid > len`.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = [1, 0, 3, 0, 5, 6];
- /// // scoped to restrict the lifetime of the borrows
- /// {
- /// let (left, right) = v.split_at_mut(2);
- /// assert!(left == [1, 0]);
- /// assert!(right == [3, 0, 5, 6]);
- /// left[1] = 2;
- /// right[1] = 4;
- /// }
- /// assert!(v == [1, 2, 3, 4, 5, 6]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
- core_slice::SliceExt::split_at_mut(self, mid)
- }
-
- /// Returns an iterator over subslices separated by elements that match
- /// `pred`. The matched element is not contained in the subslices.
- ///
- /// # Examples
- ///
- /// ```
- /// let slice = [10, 40, 33, 20];
- /// let mut iter = slice.split(|num| num % 3 == 0);
- ///
- /// assert_eq!(iter.next().unwrap(), &[10, 40]);
- /// assert_eq!(iter.next().unwrap(), &[20]);
- /// assert!(iter.next().is_none());
- /// ```
- ///
- /// If the first element is matched, an empty slice will be the first item
- /// returned by the iterator. Similarly, if the last element in the slice
- /// is matched, an empty slice will be the last item returned by the
- /// iterator:
- ///
- /// ```
- /// let slice = [10, 40, 33];
- /// let mut iter = slice.split(|num| num % 3 == 0);
- ///
- /// assert_eq!(iter.next().unwrap(), &[10, 40]);
- /// assert_eq!(iter.next().unwrap(), &[]);
- /// assert!(iter.next().is_none());
- /// ```
- ///
- /// If two matched elements are directly adjacent, an empty slice will be
- /// present between them:
- ///
- /// ```
- /// let slice = [10, 6, 33, 20];
- /// let mut iter = slice.split(|num| num % 3 == 0);
- ///
- /// assert_eq!(iter.next().unwrap(), &[10]);
- /// assert_eq!(iter.next().unwrap(), &[]);
- /// assert_eq!(iter.next().unwrap(), &[20]);
- /// assert!(iter.next().is_none());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn split<F>(&self, pred: F) -> Split<T, F>
- where F: FnMut(&T) -> bool
- {
- core_slice::SliceExt::split(self, pred)
- }
-
- /// Returns an iterator over mutable subslices separated by elements that
- /// match `pred`. The matched element is not contained in the subslices.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = [10, 40, 30, 20, 60, 50];
- ///
- /// for group in v.split_mut(|num| *num % 3 == 0) {
- /// group[0] = 1;
- /// }
- /// assert_eq!(v, [1, 40, 30, 1, 60, 1]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
- where F: FnMut(&T) -> bool
- {
- core_slice::SliceExt::split_mut(self, pred)
- }
-
- /// Returns an iterator over subslices separated by elements that match
- /// `pred`, starting at the end of the slice and working backwards.
- /// The matched element is not contained in the subslices.
- ///
- /// # Examples
- ///
- /// ```
- ///
- /// let slice = [11, 22, 33, 0, 44, 55];
- /// let mut iter = slice.rsplit(|num| *num == 0);
- ///
- /// assert_eq!(iter.next().unwrap(), &[44, 55]);
- /// assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
- /// assert_eq!(iter.next(), None);
- /// ```
- ///
- /// As with `split()`, if the first or last element is matched, an empty
- /// slice will be the first (or last) item returned by the iterator.
- ///
- /// ```
- /// let v = &[0, 1, 1, 2, 3, 5, 8];
- /// let mut it = v.rsplit(|n| *n % 2 == 0);
- /// assert_eq!(it.next().unwrap(), &[]);
- /// assert_eq!(it.next().unwrap(), &[3, 5]);
- /// assert_eq!(it.next().unwrap(), &[1, 1]);
- /// assert_eq!(it.next().unwrap(), &[]);
- /// assert_eq!(it.next(), None);
- /// ```
- #[stable(feature = "slice_rsplit", since = "1.27.0")]
- #[inline]
- pub fn rsplit<F>(&self, pred: F) -> RSplit<T, F>
- where F: FnMut(&T) -> bool
- {
- core_slice::SliceExt::rsplit(self, pred)
- }
-
- /// Returns an iterator over mutable subslices separated by elements that
- /// match `pred`, starting at the end of the slice and working
- /// backwards. The matched element is not contained in the subslices.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = [100, 400, 300, 200, 600, 500];
- ///
- /// let mut count = 0;
- /// for group in v.rsplit_mut(|num| *num % 3 == 0) {
- /// count += 1;
- /// group[0] = count;
- /// }
- /// assert_eq!(v, [3, 400, 300, 2, 600, 1]);
- /// ```
- ///
- #[stable(feature = "slice_rsplit", since = "1.27.0")]
- #[inline]
- pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<T, F>
- where F: FnMut(&T) -> bool
- {
- core_slice::SliceExt::rsplit_mut(self, pred)
- }
-
- /// Returns an iterator over subslices separated by elements that match
- /// `pred`, limited to returning at most `n` items. The matched element is
- /// not contained in the subslices.
- ///
- /// The last element returned, if any, will contain the remainder of the
- /// slice.
- ///
- /// # Examples
- ///
- /// Print the slice split once by numbers divisible by 3 (i.e. `[10, 40]`,
- /// `[20, 60, 50]`):
- ///
- /// ```
- /// let v = [10, 40, 30, 20, 60, 50];
- ///
- /// for group in v.splitn(2, |num| *num % 3 == 0) {
- /// println!("{:?}", group);
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, F>
- where F: FnMut(&T) -> bool
- {
- core_slice::SliceExt::splitn(self, n, pred)
- }
-
- /// Returns an iterator over subslices separated by elements that match
- /// `pred`, limited to returning at most `n` items. The matched element is
- /// not contained in the subslices.
- ///
- /// The last element returned, if any, will contain the remainder of the
- /// slice.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = [10, 40, 30, 20, 60, 50];
- ///
- /// for group in v.splitn_mut(2, |num| *num % 3 == 0) {
- /// group[0] = 1;
- /// }
- /// assert_eq!(v, [1, 40, 30, 1, 60, 50]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, F>
- where F: FnMut(&T) -> bool
- {
- core_slice::SliceExt::splitn_mut(self, n, pred)
- }
-
- /// Returns an iterator over subslices separated by elements that match
- /// `pred` limited to returning at most `n` items. This starts at the end of
- /// the slice and works backwards. The matched element is not contained in
- /// the subslices.
- ///
- /// The last element returned, if any, will contain the remainder of the
- /// slice.
- ///
- /// # Examples
- ///
- /// Print the slice split once, starting from the end, by numbers divisible
- /// by 3 (i.e. `[50]`, `[10, 40, 30, 20]`):
- ///
- /// ```
- /// let v = [10, 40, 30, 20, 60, 50];
- ///
- /// for group in v.rsplitn(2, |num| *num % 3 == 0) {
- /// println!("{:?}", group);
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, F>
- where F: FnMut(&T) -> bool
- {
- core_slice::SliceExt::rsplitn(self, n, pred)
- }
-
- /// Returns an iterator over subslices separated by elements that match
- /// `pred` limited to returning at most `n` items. This starts at the end of
- /// the slice and works backwards. The matched element is not contained in
- /// the subslices.
- ///
- /// The last element returned, if any, will contain the remainder of the
- /// slice.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut s = [10, 40, 30, 20, 60, 50];
- ///
- /// for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
- /// group[0] = 1;
- /// }
- /// assert_eq!(s, [1, 40, 30, 20, 60, 1]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<T, F>
- where F: FnMut(&T) -> bool
- {
- core_slice::SliceExt::rsplitn_mut(self, n, pred)
- }
-
- /// Returns `true` if the slice contains an element with the given value.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = [10, 40, 30];
- /// assert!(v.contains(&30));
- /// assert!(!v.contains(&50));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn contains(&self, x: &T) -> bool
- where T: PartialEq
- {
- core_slice::SliceExt::contains(self, x)
- }
-
- /// Returns `true` if `needle` is a prefix of the slice.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = [10, 40, 30];
- /// assert!(v.starts_with(&[10]));
- /// assert!(v.starts_with(&[10, 40]));
- /// assert!(!v.starts_with(&[50]));
- /// assert!(!v.starts_with(&[10, 50]));
- /// ```
- ///
- /// Always returns `true` if `needle` is an empty slice:
- ///
- /// ```
- /// let v = &[10, 40, 30];
- /// assert!(v.starts_with(&[]));
- /// let v: &[u8] = &[];
- /// assert!(v.starts_with(&[]));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn starts_with(&self, needle: &[T]) -> bool
- where T: PartialEq
- {
- core_slice::SliceExt::starts_with(self, needle)
- }
-
- /// Returns `true` if `needle` is a suffix of the slice.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = [10, 40, 30];
- /// assert!(v.ends_with(&[30]));
- /// assert!(v.ends_with(&[40, 30]));
- /// assert!(!v.ends_with(&[50]));
- /// assert!(!v.ends_with(&[50, 30]));
- /// ```
- ///
- /// Always returns `true` if `needle` is an empty slice:
- ///
- /// ```
- /// let v = &[10, 40, 30];
- /// assert!(v.ends_with(&[]));
- /// let v: &[u8] = &[];
- /// assert!(v.ends_with(&[]));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn ends_with(&self, needle: &[T]) -> bool
- where T: PartialEq
- {
- core_slice::SliceExt::ends_with(self, needle)
- }
-
- /// Binary searches this sorted slice for a given element.
- ///
- /// If the value is found then `Ok` is returned, containing the
- /// index of the matching element; if the value is not found then
- /// `Err` is returned, containing the index where a matching
- /// element could be inserted while maintaining sorted order.
- ///
- /// # Examples
- ///
- /// Looks up a series of four elements. The first is found, with a
- /// uniquely determined position; the second and third are not
- /// found; the fourth could match any position in `[1, 4]`.
- ///
- /// ```
- /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
- ///
- /// assert_eq!(s.binary_search(&13), Ok(9));
- /// assert_eq!(s.binary_search(&4), Err(7));
- /// assert_eq!(s.binary_search(&100), Err(13));
- /// let r = s.binary_search(&1);
- /// assert!(match r { Ok(1...4) => true, _ => false, });
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn binary_search(&self, x: &T) -> Result<usize, usize>
- where T: Ord
- {
- core_slice::SliceExt::binary_search(self, x)
- }
-
- /// Binary searches this sorted slice with a comparator function.
- ///
- /// The comparator function should implement an order consistent
- /// with the sort order of the underlying slice, returning an
- /// order code that indicates whether its argument is `Less`,
- /// `Equal` or `Greater` the desired target.
- ///
- /// If a matching value is found then returns `Ok`, containing
- /// the index for the matched element; if no match is found then
- /// `Err` is returned, containing the index where a matching
- /// element could be inserted while maintaining sorted order.
- ///
- /// # Examples
- ///
- /// Looks up a series of four elements. The first is found, with a
- /// uniquely determined position; the second and third are not
- /// found; the fourth could match any position in `[1, 4]`.
- ///
- /// ```
- /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
- ///
- /// let seek = 13;
- /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
- /// let seek = 4;
- /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
- /// let seek = 100;
- /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
- /// let seek = 1;
- /// let r = s.binary_search_by(|probe| probe.cmp(&seek));
- /// assert!(match r { Ok(1...4) => true, _ => false, });
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
- where F: FnMut(&'a T) -> Ordering
- {
- core_slice::SliceExt::binary_search_by(self, f)
- }
-
- /// Binary searches this sorted slice with a key extraction function.
- ///
- /// Assumes that the slice is sorted by the key, for instance with
- /// [`sort_by_key`] using the same key extraction function.
- ///
- /// If a matching value is found then returns `Ok`, containing the
- /// index for the matched element; if no match is found then `Err`
- /// is returned, containing the index where a matching element could
- /// be inserted while maintaining sorted order.
- ///
- /// [`sort_by_key`]: #method.sort_by_key
- ///
- /// # Examples
- ///
- /// Looks up a series of four elements in a slice of pairs sorted by
- /// their second elements. The first is found, with a uniquely
- /// determined position; the second and third are not found; the
- /// fourth could match any position in `[1, 4]`.
- ///
- /// ```
- /// let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
- /// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
- /// (1, 21), (2, 34), (4, 55)];
- ///
- /// assert_eq!(s.binary_search_by_key(&13, |&(a,b)| b), Ok(9));
- /// assert_eq!(s.binary_search_by_key(&4, |&(a,b)| b), Err(7));
- /// assert_eq!(s.binary_search_by_key(&100, |&(a,b)| b), Err(13));
- /// let r = s.binary_search_by_key(&1, |&(a,b)| b);
- /// assert!(match r { Ok(1...4) => true, _ => false, });
- /// ```
- #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
- #[inline]
- pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<usize, usize>
- where F: FnMut(&'a T) -> B,
- B: Ord
- {
- core_slice::SliceExt::binary_search_by_key(self, b, f)
- }
+ #[cfg(stage0)]
+ slice_core_methods!();
/// Sorts the slice.
///
@@ -1402,345 +355,6 @@ impl<T> [T] {
sort_by_key!(usize, self, f)
}
- /// Sorts the slice, but may not preserve the order of equal elements.
- ///
- /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
- /// and `O(n log n)` worst-case.
- ///
- /// # Current implementation
- ///
- /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters,
- /// which combines the fast average case of randomized quicksort with the fast worst case of
- /// heapsort, while achieving linear time on slices with certain patterns. It uses some
- /// randomization to avoid degenerate cases, but with a fixed seed to always provide
- /// deterministic behavior.
- ///
- /// It is typically faster than stable sorting, except in a few special cases, e.g. when the
- /// slice consists of several concatenated sorted sequences.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = [-5, 4, 1, -3, 2];
- ///
- /// v.sort_unstable();
- /// assert!(v == [-5, -3, 1, 2, 4]);
- /// ```
- ///
- /// [pdqsort]: https://github.com/orlp/pdqsort
- #[stable(feature = "sort_unstable", since = "1.20.0")]
- #[inline]
- pub fn sort_unstable(&mut self)
- where T: Ord
- {
- core_slice::SliceExt::sort_unstable(self);
- }
-
- /// Sorts the slice with a comparator function, but may not preserve the order of equal
- /// elements.
- ///
- /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
- /// and `O(n log n)` worst-case.
- ///
- /// # Current implementation
- ///
- /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters,
- /// which combines the fast average case of randomized quicksort with the fast worst case of
- /// heapsort, while achieving linear time on slices with certain patterns. It uses some
- /// randomization to avoid degenerate cases, but with a fixed seed to always provide
- /// deterministic behavior.
- ///
- /// It is typically faster than stable sorting, except in a few special cases, e.g. when the
- /// slice consists of several concatenated sorted sequences.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = [5, 4, 1, 3, 2];
- /// v.sort_unstable_by(|a, b| a.cmp(b));
- /// assert!(v == [1, 2, 3, 4, 5]);
- ///
- /// // reverse sorting
- /// v.sort_unstable_by(|a, b| b.cmp(a));
- /// assert!(v == [5, 4, 3, 2, 1]);
- /// ```
- ///
- /// [pdqsort]: https://github.com/orlp/pdqsort
- #[stable(feature = "sort_unstable", since = "1.20.0")]
- #[inline]
- pub fn sort_unstable_by<F>(&mut self, compare: F)
- where F: FnMut(&T, &T) -> Ordering
- {
- core_slice::SliceExt::sort_unstable_by(self, compare);
- }
-
- /// Sorts the slice with a key extraction function, but may not preserve the order of equal
- /// elements.
- ///
- /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
- /// and `O(m n log(m n))` worst-case, where the key function is `O(m)`.
- ///
- /// # Current implementation
- ///
- /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters,
- /// which combines the fast average case of randomized quicksort with the fast worst case of
- /// heapsort, while achieving linear time on slices with certain patterns. It uses some
- /// randomization to avoid degenerate cases, but with a fixed seed to always provide
- /// deterministic behavior.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = [-5i32, 4, 1, -3, 2];
- ///
- /// v.sort_unstable_by_key(|k| k.abs());
- /// assert!(v == [1, 2, -3, 4, -5]);
- /// ```
- ///
- /// [pdqsort]: https://github.com/orlp/pdqsort
- #[stable(feature = "sort_unstable", since = "1.20.0")]
- #[inline]
- pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
- where F: FnMut(&T) -> K, K: Ord
- {
- core_slice::SliceExt::sort_unstable_by_key(self, f);
- }
-
- /// Rotates the slice in-place such that the first `mid` elements of the
- /// slice move to the end while the last `self.len() - mid` elements move to
- /// the front. After calling `rotate_left`, the element previously at index
- /// `mid` will become the first element in the slice.
- ///
- /// # Panics
- ///
- /// This function will panic if `mid` is greater than the length of the
- /// slice. Note that `mid == self.len()` does _not_ panic and is a no-op
- /// rotation.
- ///
- /// # Complexity
- ///
- /// Takes linear (in `self.len()`) time.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
- /// a.rotate_left(2);
- /// assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
- /// ```
- ///
- /// Rotating a subslice:
- ///
- /// ```
- /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
- /// a[1..5].rotate_left(1);
- /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
- /// ```
- #[stable(feature = "slice_rotate", since = "1.26.0")]
- pub fn rotate_left(&mut self, mid: usize) {
- core_slice::SliceExt::rotate_left(self, mid);
- }
-
- /// Rotates the slice in-place such that the first `self.len() - k`
- /// elements of the slice move to the end while the last `k` elements move
- /// to the front. After calling `rotate_right`, the element previously at
- /// index `self.len() - k` will become the first element in the slice.
- ///
- /// # Panics
- ///
- /// This function will panic if `k` is greater than the length of the
- /// slice. Note that `k == self.len()` does _not_ panic and is a no-op
- /// rotation.
- ///
- /// # Complexity
- ///
- /// Takes linear (in `self.len()`) time.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
- /// a.rotate_right(2);
- /// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
- /// ```
- ///
- /// Rotate a subslice:
- ///
- /// ```
- /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
- /// a[1..5].rotate_right(1);
- /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
- /// ```
- #[stable(feature = "slice_rotate", since = "1.26.0")]
- pub fn rotate_right(&mut self, k: usize) {
- core_slice::SliceExt::rotate_right(self, k);
- }
-
- /// Copies the elements from `src` into `self`.
- ///
- /// The length of `src` must be the same as `self`.
- ///
- /// If `src` implements `Copy`, it can be more performant to use
- /// [`copy_from_slice`].
- ///
- /// # Panics
- ///
- /// This function will panic if the two slices have different lengths.
- ///
- /// # Examples
- ///
- /// Cloning two elements from a slice into another:
- ///
- /// ```
- /// let src = [1, 2, 3, 4];
- /// let mut dst = [0, 0];
- ///
- /// dst.clone_from_slice(&src[2..]);
- ///
- /// assert_eq!(src, [1, 2, 3, 4]);
- /// assert_eq!(dst, [3, 4]);
- /// ```
- ///
- /// Rust enforces that there can only be one mutable reference with no
- /// immutable references to a particular piece of data in a particular
- /// scope. Because of this, attempting to use `clone_from_slice` on a
- /// single slice will result in a compile failure:
- ///
- /// ```compile_fail
- /// let mut slice = [1, 2, 3, 4, 5];
- ///
- /// slice[..2].clone_from_slice(&slice[3..]); // compile fail!
- /// ```
- ///
- /// To work around this, we can use [`split_at_mut`] to create two distinct
- /// sub-slices from a slice:
- ///
- /// ```
- /// let mut slice = [1, 2, 3, 4, 5];
- ///
- /// {
- /// let (left, right) = slice.split_at_mut(2);
- /// left.clone_from_slice(&right[1..]);
- /// }
- ///
- /// assert_eq!(slice, [4, 5, 3, 4, 5]);
- /// ```
- ///
- /// [`copy_from_slice`]: #method.copy_from_slice
- /// [`split_at_mut`]: #method.split_at_mut
- #[stable(feature = "clone_from_slice", since = "1.7.0")]
- pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
- core_slice::SliceExt::clone_from_slice(self, src)
- }
-
- /// Copies all elements from `src` into `self`, using a memcpy.
- ///
- /// The length of `src` must be the same as `self`.
- ///
- /// If `src` does not implement `Copy`, use [`clone_from_slice`].
- ///
- /// # Panics
- ///
- /// This function will panic if the two slices have different lengths.
- ///
- /// # Examples
- ///
- /// Copying two elements from a slice into another:
- ///
- /// ```
- /// let src = [1, 2, 3, 4];
- /// let mut dst = [0, 0];
- ///
- /// dst.copy_from_slice(&src[2..]);
- ///
- /// assert_eq!(src, [1, 2, 3, 4]);
- /// assert_eq!(dst, [3, 4]);
- /// ```
- ///
- /// Rust enforces that there can only be one mutable reference with no
- /// immutable references to a particular piece of data in a particular
- /// scope. Because of this, attempting to use `copy_from_slice` on a
- /// single slice will result in a compile failure:
- ///
- /// ```compile_fail
- /// let mut slice = [1, 2, 3, 4, 5];
- ///
- /// slice[..2].copy_from_slice(&slice[3..]); // compile fail!
- /// ```
- ///
- /// To work around this, we can use [`split_at_mut`] to create two distinct
- /// sub-slices from a slice:
- ///
- /// ```
- /// let mut slice = [1, 2, 3, 4, 5];
- ///
- /// {
- /// let (left, right) = slice.split_at_mut(2);
- /// left.copy_from_slice(&right[1..]);
- /// }
- ///
- /// assert_eq!(slice, [4, 5, 3, 4, 5]);
- /// ```
- ///
- /// [`clone_from_slice`]: #method.clone_from_slice
- /// [`split_at_mut`]: #method.split_at_mut
- #[stable(feature = "copy_from_slice", since = "1.9.0")]
- pub fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
- core_slice::SliceExt::copy_from_slice(self, src)
- }
-
- /// Swaps all elements in `self` with those in `other`.
- ///
- /// The length of `other` must be the same as `self`.
- ///
- /// # Panics
- ///
- /// This function will panic if the two slices have different lengths.
- ///
- /// # Example
- ///
- /// Swapping two elements across slices:
- ///
- /// ```
- /// let mut slice1 = [0, 0];
- /// let mut slice2 = [1, 2, 3, 4];
- ///
- /// slice1.swap_with_slice(&mut slice2[2..]);
- ///
- /// assert_eq!(slice1, [3, 4]);
- /// assert_eq!(slice2, [1, 2, 0, 0]);
- /// ```
- ///
- /// Rust enforces that there can only be one mutable reference to a
- /// particular piece of data in a particular scope. Because of this,
- /// attempting to use `swap_with_slice` on a single slice will result in
- /// a compile failure:
- ///
- /// ```compile_fail
- /// let mut slice = [1, 2, 3, 4, 5];
- /// slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
- /// ```
- ///
- /// To work around this, we can use [`split_at_mut`] to create two distinct
- /// mutable sub-slices from a slice:
- ///
- /// ```
- /// let mut slice = [1, 2, 3, 4, 5];
- ///
- /// {
- /// let (left, right) = slice.split_at_mut(2);
- /// left.swap_with_slice(&mut right[1..]);
- /// }
- ///
- /// assert_eq!(slice, [4, 5, 3, 1, 2]);
- /// ```
- ///
- /// [`split_at_mut`]: #method.split_at_mut
- #[stable(feature = "swap_with_slice", since = "1.27.0")]
- pub fn swap_with_slice(&mut self, other: &mut [T]) {
- core_slice::SliceExt::swap_with_slice(self, other)
- }
-
/// Copies `self` into a new `Vec`.
///
/// # Examples
@@ -1782,16 +396,10 @@ impl<T> [T] {
}
}
-#[lang = "slice_u8"]
+#[cfg_attr(stage0, lang = "slice_u8")]
+#[cfg_attr(not(stage0), lang = "slice_u8_alloc")]
#[cfg(not(test))]
impl [u8] {
- /// Checks if all bytes in this slice are within the ASCII range.
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn is_ascii(&self) -> bool {
- self.iter().all(|b| b.is_ascii())
- }
-
/// Returns a vector containing a copy of this slice where each byte
/// is mapped to its ASCII upper case equivalent.
///
@@ -1826,52 +434,8 @@ impl [u8] {
me
}
- /// Checks that two slices are an ASCII case-insensitive match.
- ///
- /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
- /// but without allocating and copying temporaries.
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
- self.len() == other.len() &&
- self.iter().zip(other).all(|(a, b)| {
- a.eq_ignore_ascii_case(b)
- })
- }
-
- /// Converts this slice to its ASCII upper case equivalent in-place.
- ///
- /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
- /// but non-ASCII letters are unchanged.
- ///
- /// To return a new uppercased value without modifying the existing one, use
- /// [`to_ascii_uppercase`].
- ///
- /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn make_ascii_uppercase(&mut self) {
- for byte in self {
- byte.make_ascii_uppercase();
- }
- }
-
- /// Converts this slice to its ASCII lower case equivalent in-place.
- ///
- /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
- /// but non-ASCII letters are unchanged.
- ///
- /// To return a new lowercased value without modifying the existing one, use
- /// [`to_ascii_lowercase`].
- ///
- /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn make_ascii_lowercase(&mut self) {
- for byte in self {
- byte.make_ascii_lowercase();
- }
- }
+ #[cfg(stage0)]
+ slice_u8_core_methods!();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 686a0408a7c..82ba2f45711 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -40,6 +40,7 @@
use core::fmt;
use core::str as core_str;
+#[cfg(stage0)] use core::str::StrExt;
use core::str::pattern::Pattern;
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
use core::mem;
@@ -76,7 +77,8 @@ pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError
pub use core::str::SplitWhitespace;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::str::pattern;
-
+#[stable(feature = "encode_utf16", since = "1.8.0")]
+pub use core::str::EncodeUtf16;
#[unstable(feature = "slice_concat_ext",
reason = "trait should not have to exist",
@@ -133,64 +135,6 @@ impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
}
}
-/// An iterator of [`u16`] over the string encoded as UTF-16.
-///
-/// [`u16`]: ../../std/primitive.u16.html
-///
-/// This struct is created by the [`encode_utf16`] method on [`str`].
-/// See its documentation for more.
-///
-/// [`encode_utf16`]: ../../std/primitive.str.html#method.encode_utf16
-/// [`str`]: ../../std/primitive.str.html
-#[derive(Clone)]
-#[stable(feature = "encode_utf16", since = "1.8.0")]
-pub struct EncodeUtf16<'a> {
- chars: Chars<'a>,
- extra: u16,
-}
-
-#[stable(feature = "collection_debug", since = "1.17.0")]
-impl<'a> fmt::Debug for EncodeUtf16<'a> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.pad("EncodeUtf16 { .. }")
- }
-}
-
-#[stable(feature = "encode_utf16", since = "1.8.0")]
-impl<'a> Iterator for EncodeUtf16<'a> {
- type Item = u16;
-
- #[inline]
- fn next(&mut self) -> Option<u16> {
- if self.extra != 0 {
- let tmp = self.extra;
- self.extra = 0;
- return Some(tmp);
- }
-
- let mut buf = [0; 2];
- self.chars.next().map(|ch| {
- let n = ch.encode_utf16(&mut buf).len();
- if n == 2 {
- self.extra = buf[1];
- }
- buf[0]
- })
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let (low, high) = self.chars.size_hint();
- // every char gets either one u16 or two u16,
- // so this iterator is between 1 or 2 times as
- // long as the underlying iterator.
- (low, high.and_then(|n| n.checked_mul(2)))
- }
-}
-
-#[stable(feature = "fused", since = "1.26.0")]
-impl<'a> FusedIterator for EncodeUtf16<'a> {}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<str> for String {
#[inline]
@@ -214,1605 +158,12 @@ impl ToOwned for str {
}
/// Methods for string slices.
-#[lang = "str"]
+#[cfg_attr(stage0, lang = "str")]
+#[cfg_attr(not(stage0), lang = "str_alloc")]
#[cfg(not(test))]
impl str {
- /// Returns the length of `self`.
- ///
- /// This length is in bytes, not [`char`]s or graphemes. In other words,
- /// it may not be what a human considers the length of the string.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let len = "foo".len();
- /// assert_eq!(3, len);
- ///
- /// let len = "ƒoo".len(); // fancy f!
- /// assert_eq!(4, len);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn len(&self) -> usize {
- core_str::StrExt::len(self)
- }
-
- /// Returns `true` if `self` has a length of zero bytes.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let s = "";
- /// assert!(s.is_empty());
- ///
- /// let s = "not empty";
- /// assert!(!s.is_empty());
- /// ```
- #[inline]
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn is_empty(&self) -> bool {
- core_str::StrExt::is_empty(self)
- }
-
- /// Checks that `index`-th byte lies at the start and/or end of a
- /// UTF-8 code point sequence.
- ///
- /// The start and end of the string (when `index == self.len()`) are
- /// considered to be
- /// boundaries.
- ///
- /// Returns `false` if `index` is greater than `self.len()`.
- ///
- /// # Examples
- ///
- /// ```
- /// let s = "Löwe 老虎 Léopard";
- /// assert!(s.is_char_boundary(0));
- /// // start of `老`
- /// assert!(s.is_char_boundary(6));
- /// assert!(s.is_char_boundary(s.len()));
- ///
- /// // second byte of `ö`
- /// assert!(!s.is_char_boundary(2));
- ///
- /// // third byte of `老`
- /// assert!(!s.is_char_boundary(8));
- /// ```
- #[stable(feature = "is_char_boundary", since = "1.9.0")]
- #[inline]
- pub fn is_char_boundary(&self, index: usize) -> bool {
- core_str::StrExt::is_char_boundary(self, index)
- }
-
- /// Converts a string slice to a byte slice. To convert the byte slice back
- /// into a string slice, use the [`str::from_utf8`] function.
- ///
- /// [`str::from_utf8`]: ./str/fn.from_utf8.html
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let bytes = "bors".as_bytes();
- /// assert_eq!(b"bors", bytes);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline(always)]
- pub fn as_bytes(&self) -> &[u8] {
- core_str::StrExt::as_bytes(self)
- }
-
- /// Converts a mutable string slice to a mutable byte slice. To convert the
- /// mutable byte slice back into a mutable string slice, use the
- /// [`str::from_utf8_mut`] function.
- ///
- /// [`str::from_utf8_mut`]: ./str/fn.from_utf8_mut.html
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let mut s = String::from("Hello");
- /// let bytes = unsafe { s.as_bytes_mut() };
- ///
- /// assert_eq!(b"Hello", bytes);
- /// ```
- ///
- /// Mutability:
- ///
- /// ```
- /// let mut s = String::from("🗻∈🌏");
- ///
- /// unsafe {
- /// let bytes = s.as_bytes_mut();
- ///
- /// bytes[0] = 0xF0;
- /// bytes[1] = 0x9F;
- /// bytes[2] = 0x8D;
- /// bytes[3] = 0x94;
- /// }
- ///
- /// assert_eq!("🍔∈🌏", s);
- /// ```
- #[stable(feature = "str_mut_extras", since = "1.20.0")]
- #[inline(always)]
- pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
- core_str::StrExt::as_bytes_mut(self)
- }
-
- /// Converts a string slice to a raw pointer.
- ///
- /// As string slices are a slice of bytes, the raw pointer points to a
- /// [`u8`]. This pointer will be pointing to the first byte of the string
- /// slice.
- ///
- /// [`u8`]: primitive.u8.html
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let s = "Hello";
- /// let ptr = s.as_ptr();
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn as_ptr(&self) -> *const u8 {
- core_str::StrExt::as_ptr(self)
- }
-
- /// Returns a subslice of `str`.
- ///
- /// This is the non-panicking alternative to indexing the `str`. Returns
- /// [`None`] whenever equivalent indexing operation would panic.
- ///
- /// [`None`]: option/enum.Option.html#variant.None
- ///
- /// # Examples
- ///
- /// ```
- /// let v = String::from("🗻∈🌏");
- ///
- /// assert_eq!(Some("🗻"), v.get(0..4));
- ///
- /// // indices not on UTF-8 sequence boundaries
- /// assert!(v.get(1..).is_none());
- /// assert!(v.get(..8).is_none());
- ///
- /// // out of bounds
- /// assert!(v.get(..42).is_none());
- /// ```
- #[stable(feature = "str_checked_slicing", since = "1.20.0")]
- #[inline]
- pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
- core_str::StrExt::get(self, i)
- }
-
- /// Returns a mutable subslice of `str`.
- ///
- /// This is the non-panicking alternative to indexing the `str`. Returns
- /// [`None`] whenever equivalent indexing operation would panic.
- ///
- /// [`None`]: option/enum.Option.html#variant.None
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = String::from("hello");
- /// // correct length
- /// assert!(v.get_mut(0..5).is_some());
- /// // out of bounds
- /// assert!(v.get_mut(..42).is_none());
- /// assert_eq!(Some("he"), v.get_mut(0..2).map(|v| &*v));
- ///
- /// assert_eq!("hello", v);
- /// {
- /// let s = v.get_mut(0..2);
- /// let s = s.map(|s| {
- /// s.make_ascii_uppercase();
- /// &*s
- /// });
- /// assert_eq!(Some("HE"), s);
- /// }
- /// assert_eq!("HEllo", v);
- /// ```
- #[stable(feature = "str_checked_slicing", since = "1.20.0")]
- #[inline]
- pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
- core_str::StrExt::get_mut(self, i)
- }
-
- /// Returns a unchecked subslice of `str`.
- ///
- /// This is the unchecked alternative to indexing the `str`.
- ///
- /// # Safety
- ///
- /// Callers of this function are responsible that these preconditions are
- /// satisfied:
- ///
- /// * The starting index must come before the ending index;
- /// * Indexes must be within bounds of the original slice;
- /// * Indexes must lie on UTF-8 sequence boundaries.
- ///
- /// Failing that, the returned string slice may reference invalid memory or
- /// violate the invariants communicated by the `str` type.
- ///
- /// # Examples
- ///
- /// ```
- /// let v = "🗻∈🌏";
- /// unsafe {
- /// assert_eq!("🗻", v.get_unchecked(0..4));
- /// assert_eq!("∈", v.get_unchecked(4..7));
- /// assert_eq!("🌏", v.get_unchecked(7..11));
- /// }
- /// ```
- #[stable(feature = "str_checked_slicing", since = "1.20.0")]
- #[inline]
- pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
- core_str::StrExt::get_unchecked(self, i)
- }
-
- /// Returns a mutable, unchecked subslice of `str`.
- ///
- /// This is the unchecked alternative to indexing the `str`.
- ///
- /// # Safety
- ///
- /// Callers of this function are responsible that these preconditions are
- /// satisfied:
- ///
- /// * The starting index must come before the ending index;
- /// * Indexes must be within bounds of the original slice;
- /// * Indexes must lie on UTF-8 sequence boundaries.
- ///
- /// Failing that, the returned string slice may reference invalid memory or
- /// violate the invariants communicated by the `str` type.
- ///
- /// # Examples
- ///
- /// ```
- /// let mut v = String::from("🗻∈🌏");
- /// unsafe {
- /// assert_eq!("🗻", v.get_unchecked_mut(0..4));
- /// assert_eq!("∈", v.get_unchecked_mut(4..7));
- /// assert_eq!("🌏", v.get_unchecked_mut(7..11));
- /// }
- /// ```
- #[stable(feature = "str_checked_slicing", since = "1.20.0")]
- #[inline]
- pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
- core_str::StrExt::get_unchecked_mut(self, i)
- }
-
- /// Creates a string slice from another string slice, bypassing safety
- /// checks.
- ///
- /// This is generally not recommended, use with caution! For a safe
- /// alternative see [`str`] and [`Index`].
- ///
- /// [`str`]: primitive.str.html
- /// [`Index`]: ops/trait.Index.html
- ///
- /// This new slice goes from `begin` to `end`, including `begin` but
- /// excluding `end`.
- ///
- /// To get a mutable string slice instead, see the
- /// [`slice_mut_unchecked`] method.
- ///
- /// [`slice_mut_unchecked`]: #method.slice_mut_unchecked
- ///
- /// # Safety
- ///
- /// Callers of this function are responsible that three preconditions are
- /// satisfied:
- ///
- /// * `begin` must come before `end`.
- /// * `begin` and `end` must be byte positions within the string slice.
- /// * `begin` and `end` must lie on UTF-8 sequence boundaries.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let s = "Löwe 老虎 Léopard";
- ///
- /// unsafe {
- /// assert_eq!("Löwe 老虎 Léopard", s.slice_unchecked(0, 21));
- /// }
- ///
- /// let s = "Hello, world!";
- ///
- /// unsafe {
- /// assert_eq!("world", s.slice_unchecked(7, 12));
- /// }
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
- core_str::StrExt::slice_unchecked(self, begin, end)
- }
-
- /// Creates a string slice from another string slice, bypassing safety
- /// checks.
- /// This is generally not recommended, use with caution! For a safe
- /// alternative see [`str`] and [`IndexMut`].
- ///
- /// [`str`]: primitive.str.html
- /// [`IndexMut`]: ops/trait.IndexMut.html
- ///
- /// This new slice goes from `begin` to `end`, including `begin` but
- /// excluding `end`.
- ///
- /// To get an immutable string slice instead, see the
- /// [`slice_unchecked`] method.
- ///
- /// [`slice_unchecked`]: #method.slice_unchecked
- ///
- /// # Safety
- ///
- /// Callers of this function are responsible that three preconditions are
- /// satisfied:
- ///
- /// * `begin` must come before `end`.
- /// * `begin` and `end` must be byte positions within the string slice.
- /// * `begin` and `end` must lie on UTF-8 sequence boundaries.
- #[stable(feature = "str_slice_mut", since = "1.5.0")]
- #[inline]
- pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
- core_str::StrExt::slice_mut_unchecked(self, begin, end)
- }
-
- /// Divide one string slice into two at an index.
- ///
- /// The argument, `mid`, should be a byte offset from the start of the
- /// string. It must also be on the boundary of a UTF-8 code point.
- ///
- /// The two slices returned go from the start of the string slice to `mid`,
- /// and from `mid` to the end of the string slice.
- ///
- /// To get mutable string slices instead, see the [`split_at_mut`]
- /// method.
- ///
- /// [`split_at_mut`]: #method.split_at_mut
- ///
- /// # Panics
- ///
- /// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
- /// beyond the last code point of the string slice.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let s = "Per Martin-Löf";
- ///
- /// let (first, last) = s.split_at(3);
- ///
- /// assert_eq!("Per", first);
- /// assert_eq!(" Martin-Löf", last);
- /// ```
- #[inline]
- #[stable(feature = "str_split_at", since = "1.4.0")]
- pub fn split_at(&self, mid: usize) -> (&str, &str) {
- core_str::StrExt::split_at(self, mid)
- }
-
- /// Divide one mutable string slice into two at an index.
- ///
- /// The argument, `mid`, should be a byte offset from the start of the
- /// string. It must also be on the boundary of a UTF-8 code point.
- ///
- /// The two slices returned go from the start of the string slice to `mid`,
- /// and from `mid` to the end of the string slice.
- ///
- /// To get immutable string slices instead, see the [`split_at`] method.
- ///
- /// [`split_at`]: #method.split_at
- ///
- /// # Panics
- ///
- /// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
- /// beyond the last code point of the string slice.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let mut s = "Per Martin-Löf".to_string();
- /// {
- /// let (first, last) = s.split_at_mut(3);
- /// first.make_ascii_uppercase();
- /// assert_eq!("PER", first);
- /// assert_eq!(" Martin-Löf", last);
- /// }
- /// assert_eq!("PER Martin-Löf", s);
- /// ```
- #[inline]
- #[stable(feature = "str_split_at", since = "1.4.0")]
- pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
- core_str::StrExt::split_at_mut(self, mid)
- }
-
- /// Returns an iterator over the [`char`]s of a string slice.
- ///
- /// As a string slice consists of valid UTF-8, we can iterate through a
- /// string slice by [`char`]. This method returns such an iterator.
- ///
- /// It's important to remember that [`char`] represents a Unicode Scalar
- /// Value, and may not match your idea of what a 'character' is. Iteration
- /// over grapheme clusters may be what you actually want.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let word = "goodbye";
- ///
- /// let count = word.chars().count();
- /// assert_eq!(7, count);
- ///
- /// let mut chars = word.chars();
- ///
- /// assert_eq!(Some('g'), chars.next());
- /// assert_eq!(Some('o'), chars.next());
- /// assert_eq!(Some('o'), chars.next());
- /// assert_eq!(Some('d'), chars.next());
- /// assert_eq!(Some('b'), chars.next());
- /// assert_eq!(Some('y'), chars.next());
- /// assert_eq!(Some('e'), chars.next());
- ///
- /// assert_eq!(None, chars.next());
- /// ```
- ///
- /// Remember, [`char`]s may not match your human intuition about characters:
- ///
- /// ```
- /// let y = "y̆";
- ///
- /// let mut chars = y.chars();
- ///
- /// assert_eq!(Some('y'), chars.next()); // not 'y̆'
- /// assert_eq!(Some('\u{0306}'), chars.next());
- ///
- /// assert_eq!(None, chars.next());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn chars(&self) -> Chars {
- core_str::StrExt::chars(self)
- }
- /// Returns an iterator over the [`char`]s of a string slice, and their
- /// positions.
- ///
- /// As a string slice consists of valid UTF-8, we can iterate through a
- /// string slice by [`char`]. This method returns an iterator of both
- /// these [`char`]s, as well as their byte positions.
- ///
- /// The iterator yields tuples. The position is first, the [`char`] is
- /// second.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let word = "goodbye";
- ///
- /// let count = word.char_indices().count();
- /// assert_eq!(7, count);
- ///
- /// let mut char_indices = word.char_indices();
- ///
- /// assert_eq!(Some((0, 'g')), char_indices.next());
- /// assert_eq!(Some((1, 'o')), char_indices.next());
- /// assert_eq!(Some((2, 'o')), char_indices.next());
- /// assert_eq!(Some((3, 'd')), char_indices.next());
- /// assert_eq!(Some((4, 'b')), char_indices.next());
- /// assert_eq!(Some((5, 'y')), char_indices.next());
- /// assert_eq!(Some((6, 'e')), char_indices.next());
- ///
- /// assert_eq!(None, char_indices.next());
- /// ```
- ///
- /// Remember, [`char`]s may not match your human intuition about characters:
- ///
- /// ```
- /// let yes = "y̆es";
- ///
- /// let mut char_indices = yes.char_indices();
- ///
- /// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆')
- /// assert_eq!(Some((1, '\u{0306}')), char_indices.next());
- ///
- /// // note the 3 here - the last character took up two bytes
- /// assert_eq!(Some((3, 'e')), char_indices.next());
- /// assert_eq!(Some((4, 's')), char_indices.next());
- ///
- /// assert_eq!(None, char_indices.next());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn char_indices(&self) -> CharIndices {
- core_str::StrExt::char_indices(self)
- }
-
- /// An iterator over the bytes of a string slice.
- ///
- /// As a string slice consists of a sequence of bytes, we can iterate
- /// through a string slice by byte. This method returns such an iterator.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let mut bytes = "bors".bytes();
- ///
- /// assert_eq!(Some(b'b'), bytes.next());
- /// assert_eq!(Some(b'o'), bytes.next());
- /// assert_eq!(Some(b'r'), bytes.next());
- /// assert_eq!(Some(b's'), bytes.next());
- ///
- /// assert_eq!(None, bytes.next());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn bytes(&self) -> Bytes {
- core_str::StrExt::bytes(self)
- }
-
- /// Split a string slice by whitespace.
- ///
- /// The iterator returned will return string slices that are sub-slices of
- /// the original string slice, separated by any amount of whitespace.
- ///
- /// 'Whitespace' is defined according to the terms of the Unicode Derived
- /// Core Property `White_Space`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let mut iter = "A few words".split_whitespace();
- ///
- /// assert_eq!(Some("A"), iter.next());
- /// assert_eq!(Some("few"), iter.next());
- /// assert_eq!(Some("words"), iter.next());
- ///
- /// assert_eq!(None, iter.next());
- /// ```
- ///
- /// All kinds of whitespace are considered:
- ///
- /// ```
- /// let mut iter = " Mary had\ta\u{2009}little \n\t lamb".split_whitespace();
- /// assert_eq!(Some("Mary"), iter.next());
- /// assert_eq!(Some("had"), iter.next());
- /// assert_eq!(Some("a"), iter.next());
- /// assert_eq!(Some("little"), iter.next());
- /// assert_eq!(Some("lamb"), iter.next());
- ///
- /// assert_eq!(None, iter.next());
- /// ```
- #[stable(feature = "split_whitespace", since = "1.1.0")]
- #[inline]
- pub fn split_whitespace(&self) -> SplitWhitespace {
- StrExt::split_whitespace(self)
- }
-
- /// An iterator over the lines of a string, as string slices.
- ///
- /// Lines are ended with either a newline (`\n`) or a carriage return with
- /// a line feed (`\r\n`).
- ///
- /// The final line ending is optional.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let text = "foo\r\nbar\n\nbaz\n";
- /// let mut lines = text.lines();
- ///
- /// assert_eq!(Some("foo"), lines.next());
- /// assert_eq!(Some("bar"), lines.next());
- /// assert_eq!(Some(""), lines.next());
- /// assert_eq!(Some("baz"), lines.next());
- ///
- /// assert_eq!(None, lines.next());
- /// ```
- ///
- /// The final line ending isn't required:
- ///
- /// ```
- /// let text = "foo\nbar\n\r\nbaz";
- /// let mut lines = text.lines();
- ///
- /// assert_eq!(Some("foo"), lines.next());
- /// assert_eq!(Some("bar"), lines.next());
- /// assert_eq!(Some(""), lines.next());
- /// assert_eq!(Some("baz"), lines.next());
- ///
- /// assert_eq!(None, lines.next());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn lines(&self) -> Lines {
- core_str::StrExt::lines(self)
- }
-
- /// An iterator over the lines of a string.
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_deprecated(since = "1.4.0", reason = "use lines() instead now")]
- #[inline]
- #[allow(deprecated)]
- pub fn lines_any(&self) -> LinesAny {
- core_str::StrExt::lines_any(self)
- }
-
- /// Returns an iterator of `u16` over the string encoded as UTF-16.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let text = "Zażółć gęślą jaźń";
- ///
- /// let utf8_len = text.len();
- /// let utf16_len = text.encode_utf16().count();
- ///
- /// assert!(utf16_len <= utf8_len);
- /// ```
- #[stable(feature = "encode_utf16", since = "1.8.0")]
- pub fn encode_utf16(&self) -> EncodeUtf16 {
- EncodeUtf16 { chars: self[..].chars(), extra: 0 }
- }
-
- /// Returns `true` if the given pattern matches a sub-slice of
- /// this string slice.
- ///
- /// Returns `false` if it does not.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let bananas = "bananas";
- ///
- /// assert!(bananas.contains("nana"));
- /// assert!(!bananas.contains("apples"));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
- core_str::StrExt::contains(self, pat)
- }
-
- /// Returns `true` if the given pattern matches a prefix of this
- /// string slice.
- ///
- /// Returns `false` if it does not.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let bananas = "bananas";
- ///
- /// assert!(bananas.starts_with("bana"));
- /// assert!(!bananas.starts_with("nana"));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
- core_str::StrExt::starts_with(self, pat)
- }
-
- /// Returns `true` if the given pattern matches a suffix of this
- /// string slice.
- ///
- /// Returns `false` if it does not.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let bananas = "bananas";
- ///
- /// assert!(bananas.ends_with("anas"));
- /// assert!(!bananas.ends_with("nana"));
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
- where P::Searcher: ReverseSearcher<'a>
- {
- core_str::StrExt::ends_with(self, pat)
- }
-
- /// Returns the byte index of the first character of this string slice that
- /// matches the pattern.
- ///
- /// Returns [`None`] if the pattern doesn't match.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines if
- /// a character matches.
- ///
- /// [`char`]: primitive.char.html
- /// [`None`]: option/enum.Option.html#variant.None
- ///
- /// # Examples
- ///
- /// Simple patterns:
- ///
- /// ```
- /// let s = "Löwe 老虎 Léopard";
- ///
- /// assert_eq!(s.find('L'), Some(0));
- /// assert_eq!(s.find('é'), Some(14));
- /// assert_eq!(s.find("Léopard"), Some(13));
- /// ```
- ///
- /// More complex patterns using point-free style and closures:
- ///
- /// ```
- /// let s = "Löwe 老虎 Léopard";
- ///
- /// assert_eq!(s.find(char::is_whitespace), Some(5));
- /// assert_eq!(s.find(char::is_lowercase), Some(1));
- /// assert_eq!(s.find(|c: char| c.is_whitespace() || c.is_lowercase()), Some(1));
- /// assert_eq!(s.find(|c: char| (c < 'o') && (c > 'a')), Some(4));
- /// ```
- ///
- /// Not finding the pattern:
- ///
- /// ```
- /// let s = "Löwe 老虎 Léopard";
- /// let x: &[_] = &['1', '2'];
- ///
- /// assert_eq!(s.find(x), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
- core_str::StrExt::find(self, pat)
- }
-
- /// Returns the byte index of the last character of this string slice that
- /// matches the pattern.
- ///
- /// Returns [`None`] if the pattern doesn't match.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines if
- /// a character matches.
- ///
- /// [`char`]: primitive.char.html
- /// [`None`]: option/enum.Option.html#variant.None
- ///
- /// # Examples
- ///
- /// Simple patterns:
- ///
- /// ```
- /// let s = "Löwe 老虎 Léopard";
- ///
- /// assert_eq!(s.rfind('L'), Some(13));
- /// assert_eq!(s.rfind('é'), Some(14));
- /// ```
- ///
- /// More complex patterns with closures:
- ///
- /// ```
- /// let s = "Löwe 老虎 Léopard";
- ///
- /// assert_eq!(s.rfind(char::is_whitespace), Some(12));
- /// assert_eq!(s.rfind(char::is_lowercase), Some(20));
- /// ```
- ///
- /// Not finding the pattern:
- ///
- /// ```
- /// let s = "Löwe 老虎 Léopard";
- /// let x: &[_] = &['1', '2'];
- ///
- /// assert_eq!(s.rfind(x), None);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
- where P::Searcher: ReverseSearcher<'a>
- {
- core_str::StrExt::rfind(self, pat)
- }
-
- /// An iterator over substrings of this string slice, separated by
- /// characters matched by a pattern.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines the
- /// split.
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
- /// allows a reverse search and forward/reverse search yields the same
- /// elements. This is true for, eg, [`char`] but not for `&str`.
- ///
- /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
- ///
- /// If the pattern allows a reverse search but its results might differ
- /// from a forward search, the [`rsplit`] method can be used.
- ///
- /// [`char`]: primitive.char.html
- /// [`rsplit`]: #method.rsplit
- ///
- /// # Examples
- ///
- /// Simple patterns:
- ///
- /// ```
- /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
- /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
- ///
- /// let v: Vec<&str> = "".split('X').collect();
- /// assert_eq!(v, [""]);
- ///
- /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
- /// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
- ///
- /// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
- /// assert_eq!(v, ["lion", "tiger", "leopard"]);
- ///
- /// let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect();
- /// assert_eq!(v, ["abc", "def", "ghi"]);
- ///
- /// let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect();
- /// assert_eq!(v, ["lion", "tiger", "leopard"]);
- /// ```
- ///
- /// A more complex pattern, using a closure:
- ///
- /// ```
- /// let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect();
- /// assert_eq!(v, ["abc", "def", "ghi"]);
- /// ```
- ///
- /// If a string contains multiple contiguous separators, you will end up
- /// with empty strings in the output:
- ///
- /// ```
- /// let x = "||||a||b|c".to_string();
- /// let d: Vec<_> = x.split('|').collect();
- ///
- /// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
- /// ```
- ///
- /// Contiguous separators are separated by the empty string.
- ///
- /// ```
- /// let x = "(///)".to_string();
- /// let d: Vec<_> = x.split('/').collect();
- ///
- /// assert_eq!(d, &["(", "", "", ")"]);
- /// ```
- ///
- /// Separators at the start or end of a string are neighbored
- /// by empty strings.
- ///
- /// ```
- /// let d: Vec<_> = "010".split("0").collect();
- /// assert_eq!(d, &["", "1", ""]);
- /// ```
- ///
- /// When the empty string is used as a separator, it separates
- /// every character in the string, along with the beginning
- /// and end of the string.
- ///
- /// ```
- /// let f: Vec<_> = "rust".split("").collect();
- /// assert_eq!(f, &["", "r", "u", "s", "t", ""]);
- /// ```
- ///
- /// Contiguous separators can lead to possibly surprising behavior
- /// when whitespace is used as the separator. This code is correct:
- ///
- /// ```
- /// let x = " a b c".to_string();
- /// let d: Vec<_> = x.split(' ').collect();
- ///
- /// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
- /// ```
- ///
- /// It does _not_ give you:
- ///
- /// ```,ignore
- /// assert_eq!(d, &["a", "b", "c"]);
- /// ```
- ///
- /// Use [`split_whitespace`] for this behavior.
- ///
- /// [`split_whitespace`]: #method.split_whitespace
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
- core_str::StrExt::split(self, pat)
- }
-
- /// An iterator over substrings of the given string slice, separated by
- /// characters matched by a pattern and yielded in reverse order.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines the
- /// split.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator requires that the pattern supports a reverse
- /// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
- /// search yields the same elements.
- ///
- /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
- ///
- /// For iterating from the front, the [`split`] method can be used.
- ///
- /// [`split`]: #method.split
- ///
- /// # Examples
- ///
- /// Simple patterns:
- ///
- /// ```
- /// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
- /// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
- ///
- /// let v: Vec<&str> = "".rsplit('X').collect();
- /// assert_eq!(v, [""]);
- ///
- /// let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
- /// assert_eq!(v, ["leopard", "tiger", "", "lion"]);
- ///
- /// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
- /// assert_eq!(v, ["leopard", "tiger", "lion"]);
- /// ```
- ///
- /// A more complex pattern, using a closure:
- ///
- /// ```
- /// let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect();
- /// assert_eq!(v, ["ghi", "def", "abc"]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
- where P::Searcher: ReverseSearcher<'a>
- {
- core_str::StrExt::rsplit(self, pat)
- }
-
- /// An iterator over substrings of the given string slice, separated by
- /// characters matched by a pattern.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines the
- /// split.
- ///
- /// Equivalent to [`split`], except that the trailing substring
- /// is skipped if empty.
- ///
- /// [`split`]: #method.split
- ///
- /// This method can be used for string data that is _terminated_,
- /// rather than _separated_ by a pattern.
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
- /// allows a reverse search and forward/reverse search yields the same
- /// elements. This is true for, eg, [`char`] but not for `&str`.
- ///
- /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
- /// [`char`]: primitive.char.html
- ///
- /// If the pattern allows a reverse search but its results might differ
- /// from a forward search, the [`rsplit_terminator`] method can be used.
- ///
- /// [`rsplit_terminator`]: #method.rsplit_terminator
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
- /// assert_eq!(v, ["A", "B"]);
- ///
- /// let v: Vec<&str> = "A..B..".split_terminator(".").collect();
- /// assert_eq!(v, ["A", "", "B", ""]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
- core_str::StrExt::split_terminator(self, pat)
- }
-
- /// An iterator over substrings of `self`, separated by characters
- /// matched by a pattern and yielded in reverse order.
- ///
- /// The pattern can be a simple `&str`, [`char`], or a closure that
- /// determines the split.
- /// Additional libraries might provide more complex patterns like
- /// regular expressions.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// Equivalent to [`split`], except that the trailing substring is
- /// skipped if empty.
- ///
- /// [`split`]: #method.split
- ///
- /// This method can be used for string data that is _terminated_,
- /// rather than _separated_ by a pattern.
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator requires that the pattern supports a
- /// reverse search, and it will be double ended if a forward/reverse
- /// search yields the same elements.
- ///
- /// For iterating from the front, the [`split_terminator`] method can be
- /// used.
- ///
- /// [`split_terminator`]: #method.split_terminator
- ///
- /// # Examples
- ///
- /// ```
- /// let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
- /// assert_eq!(v, ["B", "A"]);
- ///
- /// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
- /// assert_eq!(v, ["", "B", "", "A"]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
- where P::Searcher: ReverseSearcher<'a>
- {
- core_str::StrExt::rsplit_terminator(self, pat)
- }
-
- /// An iterator over substrings of the given string slice, separated by a
- /// pattern, restricted to returning at most `n` items.
- ///
- /// If `n` substrings are returned, the last substring (the `n`th substring)
- /// will contain the remainder of the string.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines the
- /// split.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator will not be double ended, because it is
- /// not efficient to support.
- ///
- /// If the pattern allows a reverse search, the [`rsplitn`] method can be
- /// used.
- ///
- /// [`rsplitn`]: #method.rsplitn
- ///
- /// # Examples
- ///
- /// Simple patterns:
- ///
- /// ```
- /// let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
- /// assert_eq!(v, ["Mary", "had", "a little lambda"]);
- ///
- /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
- /// assert_eq!(v, ["lion", "", "tigerXleopard"]);
- ///
- /// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
- /// assert_eq!(v, ["abcXdef"]);
- ///
- /// let v: Vec<&str> = "".splitn(1, 'X').collect();
- /// assert_eq!(v, [""]);
- /// ```
- ///
- /// A more complex pattern, using a closure:
- ///
- /// ```
- /// let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect();
- /// assert_eq!(v, ["abc", "defXghi"]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
- core_str::StrExt::splitn(self, n, pat)
- }
-
- /// An iterator over substrings of this string slice, separated by a
- /// pattern, starting from the end of the string, restricted to returning
- /// at most `n` items.
- ///
- /// If `n` substrings are returned, the last substring (the `n`th substring)
- /// will contain the remainder of the string.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that
- /// determines the split.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator will not be double ended, because it is not
- /// efficient to support.
- ///
- /// For splitting from the front, the [`splitn`] method can be used.
- ///
- /// [`splitn`]: #method.splitn
- ///
- /// # Examples
- ///
- /// Simple patterns:
- ///
- /// ```
- /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
- /// assert_eq!(v, ["lamb", "little", "Mary had a"]);
- ///
- /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
- /// assert_eq!(v, ["leopard", "tiger", "lionX"]);
- ///
- /// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
- /// assert_eq!(v, ["leopard", "lion::tiger"]);
- /// ```
- ///
- /// A more complex pattern, using a closure:
- ///
- /// ```
- /// let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect();
- /// assert_eq!(v, ["ghi", "abc1def"]);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
- where P::Searcher: ReverseSearcher<'a>
- {
- core_str::StrExt::rsplitn(self, n, pat)
- }
-
- /// An iterator over the disjoint matches of a pattern within the given string
- /// slice.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that
- /// determines if a character matches.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
- /// allows a reverse search and forward/reverse search yields the same
- /// elements. This is true for, eg, [`char`] but not for `&str`.
- ///
- /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
- /// [`char`]: primitive.char.html
- ///
- /// If the pattern allows a reverse search but its results might differ
- /// from a forward search, the [`rmatches`] method can be used.
- ///
- /// [`rmatches`]: #method.rmatches
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
- /// assert_eq!(v, ["abc", "abc", "abc"]);
- ///
- /// let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect();
- /// assert_eq!(v, ["1", "2", "3"]);
- /// ```
- #[stable(feature = "str_matches", since = "1.2.0")]
- #[inline]
- pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
- core_str::StrExt::matches(self, pat)
- }
-
- /// An iterator over the disjoint matches of a pattern within this string slice,
- /// yielded in reverse order.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines if
- /// a character matches.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator requires that the pattern supports a reverse
- /// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
- /// search yields the same elements.
- ///
- /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
- ///
- /// For iterating from the front, the [`matches`] method can be used.
- ///
- /// [`matches`]: #method.matches
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
- /// assert_eq!(v, ["abc", "abc", "abc"]);
- ///
- /// let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect();
- /// assert_eq!(v, ["3", "2", "1"]);
- /// ```
- #[stable(feature = "str_matches", since = "1.2.0")]
- #[inline]
- pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
- where P::Searcher: ReverseSearcher<'a>
- {
- core_str::StrExt::rmatches(self, pat)
- }
-
- /// An iterator over the disjoint matches of a pattern within this string
- /// slice as well as the index that the match starts at.
- ///
- /// For matches of `pat` within `self` that overlap, only the indices
- /// corresponding to the first match are returned.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines
- /// if a character matches.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
- /// allows a reverse search and forward/reverse search yields the same
- /// elements. This is true for, eg, [`char`] but not for `&str`.
- ///
- /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
- ///
- /// If the pattern allows a reverse search but its results might differ
- /// from a forward search, the [`rmatch_indices`] method can be used.
- ///
- /// [`rmatch_indices`]: #method.rmatch_indices
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect();
- /// assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]);
- ///
- /// let v: Vec<_> = "1abcabc2".match_indices("abc").collect();
- /// assert_eq!(v, [(1, "abc"), (4, "abc")]);
- ///
- /// let v: Vec<_> = "ababa".match_indices("aba").collect();
- /// assert_eq!(v, [(0, "aba")]); // only the first `aba`
- /// ```
- #[stable(feature = "str_match_indices", since = "1.5.0")]
- #[inline]
- pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
- core_str::StrExt::match_indices(self, pat)
- }
-
- /// An iterator over the disjoint matches of a pattern within `self`,
- /// yielded in reverse order along with the index of the match.
- ///
- /// For matches of `pat` within `self` that overlap, only the indices
- /// corresponding to the last match are returned.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines if a
- /// character matches.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Iterator behavior
- ///
- /// The returned iterator requires that the pattern supports a reverse
- /// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
- /// search yields the same elements.
- ///
- /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
- ///
- /// For iterating from the front, the [`match_indices`] method can be used.
- ///
- /// [`match_indices`]: #method.match_indices
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
- /// assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]);
- ///
- /// let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect();
- /// assert_eq!(v, [(4, "abc"), (1, "abc")]);
- ///
- /// let v: Vec<_> = "ababa".rmatch_indices("aba").collect();
- /// assert_eq!(v, [(2, "aba")]); // only the last `aba`
- /// ```
- #[stable(feature = "str_match_indices", since = "1.5.0")]
- #[inline]
- pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
- where P::Searcher: ReverseSearcher<'a>
- {
- core_str::StrExt::rmatch_indices(self, pat)
- }
-
- /// Returns a string slice with leading and trailing whitespace removed.
- ///
- /// 'Whitespace' is defined according to the terms of the Unicode Derived
- /// Core Property `White_Space`.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let s = " Hello\tworld\t";
- ///
- /// assert_eq!("Hello\tworld", s.trim());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn trim(&self) -> &str {
- StrExt::trim(self)
- }
-
- /// Returns a string slice with leading whitespace removed.
- ///
- /// 'Whitespace' is defined according to the terms of the Unicode Derived
- /// Core Property `White_Space`.
- ///
- /// # Text directionality
- ///
- /// A string is a sequence of bytes. 'Left' in this context means the first
- /// position of that byte string; for a language like Arabic or Hebrew
- /// which are 'right to left' rather than 'left to right', this will be
- /// the _right_ side, not the left.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let s = " Hello\tworld\t";
- ///
- /// assert_eq!("Hello\tworld\t", s.trim_left());
- /// ```
- ///
- /// Directionality:
- ///
- /// ```
- /// let s = " English";
- /// assert!(Some('E') == s.trim_left().chars().next());
- ///
- /// let s = " עברית";
- /// assert!(Some('ע') == s.trim_left().chars().next());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn trim_left(&self) -> &str {
- StrExt::trim_left(self)
- }
-
- /// Returns a string slice with trailing whitespace removed.
- ///
- /// 'Whitespace' is defined according to the terms of the Unicode Derived
- /// Core Property `White_Space`.
- ///
- /// # Text directionality
- ///
- /// A string is a sequence of bytes. 'Right' in this context means the last
- /// position of that byte string; for a language like Arabic or Hebrew
- /// which are 'right to left' rather than 'left to right', this will be
- /// the _left_ side, not the right.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// let s = " Hello\tworld\t";
- ///
- /// assert_eq!(" Hello\tworld", s.trim_right());
- /// ```
- ///
- /// Directionality:
- ///
- /// ```
- /// let s = "English ";
- /// assert!(Some('h') == s.trim_right().chars().rev().next());
- ///
- /// let s = "עברית ";
- /// assert!(Some('ת') == s.trim_right().chars().rev().next());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn trim_right(&self) -> &str {
- StrExt::trim_right(self)
- }
-
- /// Returns a string slice with all prefixes and suffixes that match a
- /// pattern repeatedly removed.
- ///
- /// The pattern can be a [`char`] or a closure that determines if a
- /// character matches.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Examples
- ///
- /// Simple patterns:
- ///
- /// ```
- /// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
- /// assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar");
- ///
- /// let x: &[_] = &['1', '2'];
- /// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
- /// ```
- ///
- /// A more complex pattern, using a closure:
- ///
- /// ```
- /// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
- where P::Searcher: DoubleEndedSearcher<'a>
- {
- core_str::StrExt::trim_matches(self, pat)
- }
-
- /// Returns a string slice with all prefixes that match a pattern
- /// repeatedly removed.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that determines if
- /// a character matches.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Text directionality
- ///
- /// A string is a sequence of bytes. 'Left' in this context means the first
- /// position of that byte string; for a language like Arabic or Hebrew
- /// which are 'right to left' rather than 'left to right', this will be
- /// the _right_ side, not the left.
- ///
- /// # Examples
- ///
- /// Basic usage:
- ///
- /// ```
- /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
- /// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
- ///
- /// let x: &[_] = &['1', '2'];
- /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
- core_str::StrExt::trim_left_matches(self, pat)
- }
-
- /// Returns a string slice with all suffixes that match a pattern
- /// repeatedly removed.
- ///
- /// The pattern can be a `&str`, [`char`], or a closure that
- /// determines if a character matches.
- ///
- /// [`char`]: primitive.char.html
- ///
- /// # Text directionality
- ///
- /// A string is a sequence of bytes. 'Right' in this context means the last
- /// position of that byte string; for a language like Arabic or Hebrew
- /// which are 'right to left' rather than 'left to right', this will be
- /// the _left_ side, not the right.
- ///
- /// # Examples
- ///
- /// Simple patterns:
- ///
- /// ```
- /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
- /// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
- ///
- /// let x: &[_] = &['1', '2'];
- /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
- /// ```
- ///
- /// A more complex pattern, using a closure:
- ///
- /// ```
- /// assert_eq!("1fooX".trim_right_matches(|c| c == '1' || c == 'X'), "1foo");
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
- where P::Searcher: ReverseSearcher<'a>
- {
- core_str::StrExt::trim_right_matches(self, pat)
- }
-
- /// Parses this string slice into another type.
- ///
- /// Because `parse` is so general, it can cause problems with type
- /// inference. As such, `parse` is one of the few times you'll see
- /// the syntax affectionately known as the 'turbofish': `::<>`. This
- /// helps the inference algorithm understand specifically which type
- /// you're trying to parse into.
- ///
- /// `parse` can parse any type that implements the [`FromStr`] trait.
- ///
- /// [`FromStr`]: str/trait.FromStr.html
- ///
- /// # Errors
- ///
- /// Will return [`Err`] if it's not possible to parse this string slice into
- /// the desired type.
- ///
- /// [`Err`]: str/trait.FromStr.html#associatedtype.Err
- ///
- /// # Examples
- ///
- /// Basic usage
- ///
- /// ```
- /// let four: u32 = "4".parse().unwrap();
- ///
- /// assert_eq!(4, four);
- /// ```
- ///
- /// Using the 'turbofish' instead of annotating `four`:
- ///
- /// ```
- /// let four = "4".parse::<u32>();
- ///
- /// assert_eq!(Ok(4), four);
- /// ```
- ///
- /// Failing to parse:
- ///
- /// ```
- /// let nope = "j".parse::<u32>();
- ///
- /// assert!(nope.is_err());
- /// ```
- #[inline]
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
- core_str::StrExt::parse(self)
- }
+ #[cfg(stage0)]
+ str_core_methods!();
/// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
///
@@ -2140,26 +491,6 @@ impl str {
unsafe { String::from_utf8_unchecked(buf) }
}
- /// Checks if all characters in this string are within the ASCII range.
- ///
- /// # Examples
- ///
- /// ```
- /// let ascii = "hello!\n";
- /// let non_ascii = "Grüße, Jürgen ❤";
- ///
- /// assert!(ascii.is_ascii());
- /// assert!(!non_ascii.is_ascii());
- /// ```
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn is_ascii(&self) -> bool {
- // We can treat each byte as character here: all multibyte characters
- // start with a byte that is not in the ascii range, so we will stop
- // there already.
- self.bytes().all(|b| b.is_ascii())
- }
-
/// Returns a copy of this string where each character is mapped to its
/// ASCII upper case equivalent.
///
@@ -2219,54 +550,6 @@ impl str {
// make_ascii_lowercase() preserves the UTF-8 invariant.
unsafe { String::from_utf8_unchecked(bytes) }
}
-
- /// Checks that two strings are an ASCII case-insensitive match.
- ///
- /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
- /// but without allocating and copying temporaries.
- ///
- /// # Examples
- ///
- /// ```
- /// assert!("Ferris".eq_ignore_ascii_case("FERRIS"));
- /// assert!("Ferrös".eq_ignore_ascii_case("FERRöS"));
- /// assert!(!"Ferrös".eq_ignore_ascii_case("FERRÖS"));
- /// ```
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- #[inline]
- pub fn eq_ignore_ascii_case(&self, other: &str) -> bool {
- self.as_bytes().eq_ignore_ascii_case(other.as_bytes())
- }
-
- /// Converts this string to its ASCII upper case equivalent in-place.
- ///
- /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
- /// but non-ASCII letters are unchanged.
- ///
- /// To return a new uppercased value without modifying the existing one, use
- /// [`to_ascii_uppercase`].
- ///
- /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- pub fn make_ascii_uppercase(&mut self) {
- let me = unsafe { self.as_bytes_mut() };
- me.make_ascii_uppercase()
- }
-
- /// Converts this string to its ASCII lower case equivalent in-place.
- ///
- /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
- /// but non-ASCII letters are unchanged.
- ///
- /// To return a new lowercased value without modifying the existing one, use
- /// [`to_ascii_lowercase`].
- ///
- /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
- #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
- pub fn make_ascii_lowercase(&mut self) {
- let me = unsafe { self.as_bytes_mut() };
- me.make_ascii_lowercase()
- }
}
/// Converts a boxed slice of bytes to a boxed string slice without checking
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 7d1b2ed85c7..b184404c15b 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -74,6 +74,7 @@ use core::iter::{FromIterator, FusedIterator, TrustedLen};
use core::marker::PhantomData;
use core::mem;
#[cfg(not(test))]
+#[cfg(stage0)]
use core::num::Float;
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{Index, IndexMut, RangeBounds};
diff --git a/src/libcore/internal_macros.rs b/src/libcore/internal_macros.rs
index cb215a38e53..58eef649287 100644
--- a/src/libcore/internal_macros.rs
+++ b/src/libcore/internal_macros.rs
@@ -87,3 +87,16 @@ macro_rules! forward_ref_op_assign {
}
}
+#[cfg(stage0)]
+macro_rules! public_in_stage0 {
+ ( { $(#[$attr:meta])* } $($Item: tt)*) => {
+ $(#[$attr])* pub $($Item)*
+ }
+}
+
+#[cfg(not(stage0))]
+macro_rules! public_in_stage0 {
+ ( { $(#[$attr:meta])* } $($Item: tt)*) => {
+ $(#[$attr])* pub(crate) $($Item)*
+ }
+}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index ac1a8091eb3..0e605f8dbe7 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -71,6 +71,7 @@
#![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_fn)]
+#![feature(core_float)]
#![feature(custom_attribute)]
#![feature(doc_cfg)]
#![feature(doc_spotlight)]
@@ -93,6 +94,8 @@
#![feature(rustc_attrs)]
#![feature(rustc_const_unstable)]
#![feature(simd_ffi)]
+#![feature(core_slice_ext)]
+#![feature(core_str_ext)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(stmt_expr_attributes)]
@@ -229,7 +232,7 @@ macro_rules! test_v512 { ($item:item) => {}; }
#[allow(unused_macros)]
macro_rules! vector_impl { ($([$f:ident, $($args:tt)*]),*) => { $($f!($($args)*);)* } }
#[path = "../stdsimd/coresimd/mod.rs"]
-#[allow(missing_docs, missing_debug_implementations, dead_code)]
+#[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
#[unstable(feature = "stdsimd", issue = "48556")]
#[cfg(not(stage0))] // allow changes to how stdsimd works in stage0
mod coresimd;
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 3586fa5442f..8d5f6f601da 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -17,9 +17,9 @@
#![stable(feature = "rust1", since = "1.0.0")]
-use intrinsics;
use mem;
use num::Float;
+#[cfg(not(stage0))] use num::FpCategory;
use num::FpCategory as Fp;
/// The radix or base of the internal representation of `f32`.
@@ -188,27 +188,6 @@ impl Float for f32 {
}
}
- /// Computes the absolute value of `self`. Returns `Float::nan()` if the
- /// number is `Float::nan()`.
- #[inline]
- fn abs(self) -> f32 {
- unsafe { intrinsics::fabsf32(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()`
- #[inline]
- fn signum(self) -> f32 {
- if self.is_nan() {
- NAN
- } else {
- unsafe { intrinsics::copysignf32(1.0, self) }
- }
- }
-
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
/// positive sign bit and positive infinity.
#[inline]
@@ -231,11 +210,6 @@ impl Float for f32 {
1.0 / self
}
- #[inline]
- fn powi(self, n: i32) -> f32 {
- unsafe { intrinsics::powif32(self, n) }
- }
-
/// Converts to degrees, assuming the number is in radians.
#[inline]
fn to_degrees(self) -> f32 {
@@ -292,3 +266,286 @@ impl Float for f32 {
unsafe { mem::transmute(v) }
}
}
+
+// FIXME: remove (inline) this macro and the Float trait
+// when updating to a bootstrap compiler that has the new lang items.
+#[cfg_attr(stage0, macro_export)]
+#[unstable(feature = "core_float", issue = "32110")]
+macro_rules! f32_core_methods { () => {
+ /// Returns `true` if this value is `NaN` and false otherwise.
+ ///
+ /// ```
+ /// use std::f32;
+ ///
+ /// let nan = f32::NAN;
+ /// let f = 7.0_f32;
+ ///
+ /// assert!(nan.is_nan());
+ /// assert!(!f.is_nan());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_nan(self) -> bool { Float::is_nan(self) }
+
+ /// Returns `true` if this value is positive infinity or negative infinity and
+ /// false otherwise.
+ ///
+ /// ```
+ /// use std::f32;
+ ///
+ /// let f = 7.0f32;
+ /// let inf = f32::INFINITY;
+ /// let neg_inf = f32::NEG_INFINITY;
+ /// let nan = f32::NAN;
+ ///
+ /// assert!(!f.is_infinite());
+ /// assert!(!nan.is_infinite());
+ ///
+ /// assert!(inf.is_infinite());
+ /// assert!(neg_inf.is_infinite());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_infinite(self) -> bool { Float::is_infinite(self) }
+
+ /// Returns `true` if this number is neither infinite nor `NaN`.
+ ///
+ /// ```
+ /// use std::f32;
+ ///
+ /// let f = 7.0f32;
+ /// let inf = f32::INFINITY;
+ /// let neg_inf = f32::NEG_INFINITY;
+ /// let nan = f32::NAN;
+ ///
+ /// assert!(f.is_finite());
+ ///
+ /// assert!(!nan.is_finite());
+ /// assert!(!inf.is_finite());
+ /// assert!(!neg_inf.is_finite());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_finite(self) -> bool { Float::is_finite(self) }
+
+ /// Returns `true` if the number is neither zero, infinite,
+ /// [subnormal][subnormal], or `NaN`.
+ ///
+ /// ```
+ /// use std::f32;
+ ///
+ /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
+ /// let max = f32::MAX;
+ /// let lower_than_min = 1.0e-40_f32;
+ /// let zero = 0.0_f32;
+ ///
+ /// assert!(min.is_normal());
+ /// assert!(max.is_normal());
+ ///
+ /// assert!(!zero.is_normal());
+ /// assert!(!f32::NAN.is_normal());
+ /// assert!(!f32::INFINITY.is_normal());
+ /// // Values between `0` and `min` are Subnormal.
+ /// assert!(!lower_than_min.is_normal());
+ /// ```
+ /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_normal(self) -> bool { Float::is_normal(self) }
+
+ /// Returns the floating point category of the number. If only one property
+ /// is going to be tested, it is generally faster to use the specific
+ /// predicate instead.
+ ///
+ /// ```
+ /// use std::num::FpCategory;
+ /// use std::f32;
+ ///
+ /// let num = 12.4_f32;
+ /// let inf = f32::INFINITY;
+ ///
+ /// assert_eq!(num.classify(), FpCategory::Normal);
+ /// assert_eq!(inf.classify(), FpCategory::Infinite);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn classify(self) -> FpCategory { Float::classify(self) }
+
+ /// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
+ /// positive sign bit and positive infinity.
+ ///
+ /// ```
+ /// let f = 7.0_f32;
+ /// let g = -7.0_f32;
+ ///
+ /// assert!(f.is_sign_positive());
+ /// assert!(!g.is_sign_positive());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_sign_positive(self) -> bool { Float::is_sign_positive(self) }
+
+ /// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
+ /// negative sign bit and negative infinity.
+ ///
+ /// ```
+ /// let f = 7.0f32;
+ /// let g = -7.0f32;
+ ///
+ /// assert!(!f.is_sign_negative());
+ /// assert!(g.is_sign_negative());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_sign_negative(self) -> bool { Float::is_sign_negative(self) }
+
+ /// Takes the reciprocal (inverse) of a number, `1/x`.
+ ///
+ /// ```
+ /// use std::f32;
+ ///
+ /// let x = 2.0_f32;
+ /// let abs_difference = (x.recip() - (1.0/x)).abs();
+ ///
+ /// assert!(abs_difference <= f32::EPSILON);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn recip(self) -> f32 { Float::recip(self) }
+
+ /// Converts radians to degrees.
+ ///
+ /// ```
+ /// use std::f32::{self, consts};
+ ///
+ /// let angle = consts::PI;
+ ///
+ /// let abs_difference = (angle.to_degrees() - 180.0).abs();
+ ///
+ /// assert!(abs_difference <= f32::EPSILON);
+ /// ```
+ #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
+ #[inline]
+ pub fn to_degrees(self) -> f32 { Float::to_degrees(self) }
+
+ /// Converts degrees to radians.
+ ///
+ /// ```
+ /// use std::f32::{self, consts};
+ ///
+ /// let angle = 180.0f32;
+ ///
+ /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+ ///
+ /// assert!(abs_difference <= f32::EPSILON);
+ /// ```
+ #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
+ #[inline]
+ pub fn to_radians(self) -> f32 { Float::to_radians(self) }
+
+ /// Returns the maximum of the two numbers.
+ ///
+ /// ```
+ /// let x = 1.0f32;
+ /// let y = 2.0f32;
+ ///
+ /// assert_eq!(x.max(y), y);
+ /// ```
+ ///
+ /// If one of the arguments is NaN, then the other argument is returned.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn max(self, other: f32) -> f32 {
+ Float::max(self, other)
+ }
+
+ /// Returns the minimum of the two numbers.
+ ///
+ /// ```
+ /// let x = 1.0f32;
+ /// let y = 2.0f32;
+ ///
+ /// assert_eq!(x.min(y), x);
+ /// ```
+ ///
+ /// If one of the arguments is NaN, then the other argument is returned.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn min(self, other: f32) -> f32 {
+ Float::min(self, other)
+ }
+
+ /// Raw transmutation to `u32`.
+ ///
+ /// This is currently identical to `transmute::<f32, u32>(self)` on all platforms.
+ ///
+ /// See `from_bits` for some discussion of the portability of this operation
+ /// (there are almost no issues).
+ ///
+ /// Note that this function is distinct from `as` casting, which attempts to
+ /// preserve the *numeric* value, and not the bitwise value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_ne!((1f32).to_bits(), 1f32 as u32); // to_bits() is not casting!
+ /// assert_eq!((12.5f32).to_bits(), 0x41480000);
+ ///
+ /// ```
+ #[stable(feature = "float_bits_conv", since = "1.20.0")]
+ #[inline]
+ pub fn to_bits(self) -> u32 {
+ Float::to_bits(self)
+ }
+
+ /// Raw transmutation from `u32`.
+ ///
+ /// This is currently identical to `transmute::<u32, f32>(v)` on all platforms.
+ /// It turns out this is incredibly portable, for two reasons:
+ ///
+ /// * Floats and Ints have the same endianness on all supported platforms.
+ /// * IEEE-754 very precisely specifies the bit layout of floats.
+ ///
+ /// However there is one caveat: prior to the 2008 version of IEEE-754, how
+ /// to interpret the NaN signaling bit wasn't actually specified. Most platforms
+ /// (notably x86 and ARM) picked the interpretation that was ultimately
+ /// standardized in 2008, but some didn't (notably MIPS). As a result, all
+ /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
+ ///
+ /// Rather than trying to preserve signaling-ness cross-platform, this
+ /// implementation favours preserving the exact bits. This means that
+ /// any payloads encoded in NaNs will be preserved even if the result of
+ /// this method is sent over the network from an x86 machine to a MIPS one.
+ ///
+ /// If the results of this method are only manipulated by the same
+ /// architecture that produced them, then there is no portability concern.
+ ///
+ /// If the input isn't NaN, then there is no portability concern.
+ ///
+ /// If you don't care about signalingness (very likely), then there is no
+ /// portability concern.
+ ///
+ /// Note that this function is distinct from `as` casting, which attempts to
+ /// preserve the *numeric* value, and not the bitwise value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::f32;
+ /// let v = f32::from_bits(0x41480000);
+ /// let difference = (v - 12.5).abs();
+ /// assert!(difference <= 1e-5);
+ /// ```
+ #[stable(feature = "float_bits_conv", since = "1.20.0")]
+ #[inline]
+ pub fn from_bits(v: u32) -> Self {
+ Float::from_bits(v)
+ }
+}}
+
+#[lang = "f32"]
+#[cfg(not(test))]
+#[cfg(not(stage0))]
+impl f32 {
+ f32_core_methods!();
+}
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 64c0d508b38..08b869734d4 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -17,10 +17,10 @@
#![stable(feature = "rust1", since = "1.0.0")]
-use intrinsics;
use mem;
-use num::FpCategory as Fp;
use num::Float;
+#[cfg(not(stage0))] use num::FpCategory;
+use num::FpCategory as Fp;
/// The radix or base of the internal representation of `f64`.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -188,27 +188,6 @@ impl Float for f64 {
}
}
- /// Computes the absolute value of `self`. Returns `Float::nan()` if the
- /// number is `Float::nan()`.
- #[inline]
- fn abs(self) -> f64 {
- unsafe { intrinsics::fabsf64(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()`
- #[inline]
- fn signum(self) -> f64 {
- if self.is_nan() {
- NAN
- } else {
- unsafe { intrinsics::copysignf64(1.0, self) }
- }
- }
-
/// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
/// positive sign bit and positive infinity.
#[inline]
@@ -229,11 +208,6 @@ impl Float for f64 {
1.0 / self
}
- #[inline]
- fn powi(self, n: i32) -> f64 {
- unsafe { intrinsics::powif64(self, n) }
- }
-
/// Converts to degrees, assuming the number is in radians.
#[inline]
fn to_degrees(self) -> f64 {
@@ -291,3 +265,296 @@ impl Float for f64 {
unsafe { mem::transmute(v) }
}
}
+
+// FIXME: remove (inline) this macro and the Float trait
+// when updating to a bootstrap compiler that has the new lang items.
+#[cfg_attr(stage0, macro_export)]
+#[unstable(feature = "core_float", issue = "32110")]
+macro_rules! f64_core_methods { () => {
+ /// Returns `true` if this value is `NaN` and false otherwise.
+ ///
+ /// ```
+ /// use std::f64;
+ ///
+ /// let nan = f64::NAN;
+ /// let f = 7.0_f64;
+ ///
+ /// assert!(nan.is_nan());
+ /// assert!(!f.is_nan());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_nan(self) -> bool { Float::is_nan(self) }
+
+ /// Returns `true` if this value is positive infinity or negative infinity and
+ /// false otherwise.
+ ///
+ /// ```
+ /// use std::f64;
+ ///
+ /// let f = 7.0f64;
+ /// let inf = f64::INFINITY;
+ /// let neg_inf = f64::NEG_INFINITY;
+ /// let nan = f64::NAN;
+ ///
+ /// assert!(!f.is_infinite());
+ /// assert!(!nan.is_infinite());
+ ///
+ /// assert!(inf.is_infinite());
+ /// assert!(neg_inf.is_infinite());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_infinite(self) -> bool { Float::is_infinite(self) }
+
+ /// Returns `true` if this number is neither infinite nor `NaN`.
+ ///
+ /// ```
+ /// use std::f64;
+ ///
+ /// let f = 7.0f64;
+ /// let inf: f64 = f64::INFINITY;
+ /// let neg_inf: f64 = f64::NEG_INFINITY;
+ /// let nan: f64 = f64::NAN;
+ ///
+ /// assert!(f.is_finite());
+ ///
+ /// assert!(!nan.is_finite());
+ /// assert!(!inf.is_finite());
+ /// assert!(!neg_inf.is_finite());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_finite(self) -> bool { Float::is_finite(self) }
+
+ /// Returns `true` if the number is neither zero, infinite,
+ /// [subnormal][subnormal], or `NaN`.
+ ///
+ /// ```
+ /// use std::f64;
+ ///
+ /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308f64
+ /// let max = f64::MAX;
+ /// let lower_than_min = 1.0e-308_f64;
+ /// let zero = 0.0f64;
+ ///
+ /// assert!(min.is_normal());
+ /// assert!(max.is_normal());
+ ///
+ /// assert!(!zero.is_normal());
+ /// assert!(!f64::NAN.is_normal());
+ /// assert!(!f64::INFINITY.is_normal());
+ /// // Values between `0` and `min` are Subnormal.
+ /// assert!(!lower_than_min.is_normal());
+ /// ```
+ /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_normal(self) -> bool { Float::is_normal(self) }
+
+ /// Returns the floating point category of the number. If only one property
+ /// is going to be tested, it is generally faster to use the specific
+ /// predicate instead.
+ ///
+ /// ```
+ /// use std::num::FpCategory;
+ /// use std::f64;
+ ///
+ /// let num = 12.4_f64;
+ /// let inf = f64::INFINITY;
+ ///
+ /// assert_eq!(num.classify(), FpCategory::Normal);
+ /// assert_eq!(inf.classify(), FpCategory::Infinite);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn classify(self) -> FpCategory { Float::classify(self) }
+
+ /// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
+ /// positive sign bit and positive infinity.
+ ///
+ /// ```
+ /// let f = 7.0_f64;
+ /// let g = -7.0_f64;
+ ///
+ /// assert!(f.is_sign_positive());
+ /// assert!(!g.is_sign_positive());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_sign_positive(self) -> bool { Float::is_sign_positive(self) }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
+ #[inline]
+ #[doc(hidden)]
+ pub fn is_positive(self) -> bool { Float::is_sign_positive(self) }
+
+ /// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
+ /// negative sign bit and negative infinity.
+ ///
+ /// ```
+ /// let f = 7.0_f64;
+ /// let g = -7.0_f64;
+ ///
+ /// assert!(!f.is_sign_negative());
+ /// assert!(g.is_sign_negative());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_sign_negative(self) -> bool { Float::is_sign_negative(self) }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
+ #[inline]
+ #[doc(hidden)]
+ pub fn is_negative(self) -> bool { Float::is_sign_negative(self) }
+
+ /// Takes the reciprocal (inverse) of a number, `1/x`.
+ ///
+ /// ```
+ /// let x = 2.0_f64;
+ /// let abs_difference = (x.recip() - (1.0/x)).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn recip(self) -> f64 { Float::recip(self) }
+
+ /// Converts radians to degrees.
+ ///
+ /// ```
+ /// use std::f64::consts;
+ ///
+ /// let angle = consts::PI;
+ ///
+ /// let abs_difference = (angle.to_degrees() - 180.0).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn to_degrees(self) -> f64 { Float::to_degrees(self) }
+
+ /// Converts degrees to radians.
+ ///
+ /// ```
+ /// use std::f64::consts;
+ ///
+ /// let angle = 180.0_f64;
+ ///
+ /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+ ///
+ /// assert!(abs_difference < 1e-10);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn to_radians(self) -> f64 { Float::to_radians(self) }
+
+ /// Returns the maximum of the two numbers.
+ ///
+ /// ```
+ /// let x = 1.0_f64;
+ /// let y = 2.0_f64;
+ ///
+ /// assert_eq!(x.max(y), y);
+ /// ```
+ ///
+ /// If one of the arguments is NaN, then the other argument is returned.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn max(self, other: f64) -> f64 {
+ Float::max(self, other)
+ }
+
+ /// Returns the minimum of the two numbers.
+ ///
+ /// ```
+ /// let x = 1.0_f64;
+ /// let y = 2.0_f64;
+ ///
+ /// assert_eq!(x.min(y), x);
+ /// ```
+ ///
+ /// If one of the arguments is NaN, then the other argument is returned.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn min(self, other: f64) -> f64 {
+ Float::min(self, other)
+ }
+
+ /// Raw transmutation to `u64`.
+ ///
+ /// This is currently identical to `transmute::<f64, u64>(self)` on all platforms.
+ ///
+ /// See `from_bits` for some discussion of the portability of this operation
+ /// (there are almost no issues).
+ ///
+ /// Note that this function is distinct from `as` casting, which attempts to
+ /// preserve the *numeric* value, and not the bitwise value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert!((1f64).to_bits() != 1f64 as u64); // to_bits() is not casting!
+ /// assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
+ ///
+ /// ```
+ #[stable(feature = "float_bits_conv", since = "1.20.0")]
+ #[inline]
+ pub fn to_bits(self) -> u64 {
+ Float::to_bits(self)
+ }
+
+ /// Raw transmutation from `u64`.
+ ///
+ /// This is currently identical to `transmute::<u64, f64>(v)` on all platforms.
+ /// It turns out this is incredibly portable, for two reasons:
+ ///
+ /// * Floats and Ints have the same endianness on all supported platforms.
+ /// * IEEE-754 very precisely specifies the bit layout of floats.
+ ///
+ /// However there is one caveat: prior to the 2008 version of IEEE-754, how
+ /// to interpret the NaN signaling bit wasn't actually specified. Most platforms
+ /// (notably x86 and ARM) picked the interpretation that was ultimately
+ /// standardized in 2008, but some didn't (notably MIPS). As a result, all
+ /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
+ ///
+ /// Rather than trying to preserve signaling-ness cross-platform, this
+ /// implementation favours preserving the exact bits. This means that
+ /// any payloads encoded in NaNs will be preserved even if the result of
+ /// this method is sent over the network from an x86 machine to a MIPS one.
+ ///
+ /// If the results of this method are only manipulated by the same
+ /// architecture that produced them, then there is no portability concern.
+ ///
+ /// If the input isn't NaN, then there is no portability concern.
+ ///
+ /// If you don't care about signalingness (very likely), then there is no
+ /// portability concern.
+ ///
+ /// Note that this function is distinct from `as` casting, which attempts to
+ /// preserve the *numeric* value, and not the bitwise value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::f64;
+ /// let v = f64::from_bits(0x4029000000000000);
+ /// let difference = (v - 12.5).abs();
+ /// assert!(difference <= 1e-5);
+ /// ```
+ #[stable(feature = "float_bits_conv", since = "1.20.0")]
+ #[inline]
+ pub fn from_bits(v: u64) -> Self {
+ Float::from_bits(v)
+ }
+}}
+
+#[lang = "f64"]
+#[cfg(not(test))]
+#[cfg(not(stage0))]
+impl f64 {
+ f64_core_methods!();
+}
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 801e2328a4b..aa4d4bc638b 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -4098,83 +4098,58 @@ pub enum FpCategory {
Normal,
}
-/// A built-in floating point number.
+// Technically private and only exposed for coretests:
#[doc(hidden)]
-#[unstable(feature = "core_float",
- reason = "stable interface is via `impl f{32,64}` in later crates",
- issue = "32110")]
+#[unstable(feature = "float_internals",
+ reason = "internal routines only exposed for testing",
+ issue = "0")]
pub trait Float: Sized {
/// Type used by `to_bits` and `from_bits`.
- #[stable(feature = "core_float_bits", since = "1.25.0")]
type Bits;
/// 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;
- /// 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()`.
- #[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()`.
- #[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.
- #[stable(feature = "deg_rad_conversions", since="1.7.0")]
fn to_degrees(self) -> Self;
+
/// Convert degrees to radians.
- #[stable(feature = "deg_rad_conversions", since="1.7.0")]
fn to_radians(self) -> Self;
/// Returns the maximum of the two numbers.
- #[stable(feature = "core_float_min_max", since="1.20.0")]
fn max(self, other: Self) -> Self;
+
/// Returns the minimum of the two numbers.
- #[stable(feature = "core_float_min_max", since="1.20.0")]
fn min(self, other: Self) -> Self;
/// Raw transmutation to integer.
- #[stable(feature = "core_float_bits", since="1.25.0")]
fn to_bits(self) -> Self::Bits;
+
/// Raw transmutation from integer.
- #[stable(feature = "core_float_bits", since="1.25.0")]
fn from_bits(v: Self::Bits) -> Self;
}
diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs
index cc3ad71117a..8212648f2d8 100644
--- a/src/libcore/prelude/v1.rs
+++ b/src/libcore/prelude/v1.rs
@@ -58,7 +58,9 @@ pub use result::Result::{self, Ok, Err};
// Re-exported extension traits for primitive types
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
+#[cfg(stage0)]
pub use slice::SliceExt;
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
+#[cfg(stage0)]
pub use str::StrExt;
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index afb149f2997..cc42acd77ae 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -68,12 +68,15 @@ struct Repr<T> {
// Extension traits
//
+public_in_stage0! {
+{
/// Extension methods for slices.
#[unstable(feature = "core_slice_ext",
reason = "stable interface provided by `impl [T]` in later crates",
issue = "32110")]
#[allow(missing_docs)] // documented elsewhere
-pub trait SliceExt {
+}
+trait SliceExt {
type Item;
#[stable(feature = "core", since = "1.6.0")]
@@ -238,7 +241,7 @@ pub trait SliceExt {
fn sort_unstable_by_key<B, F>(&mut self, f: F)
where F: FnMut(&Self::Item) -> B,
B: Ord;
-}
+}}
// Use macros to be generic over const/mut
macro_rules! slice_offset {
@@ -755,6 +758,1475 @@ impl<T> SliceExt for [T] {
}
}
+// FIXME: remove (inline) this macro and the SliceExt trait
+// when updating to a bootstrap compiler that has the new lang items.
+#[cfg_attr(stage0, macro_export)]
+#[unstable(feature = "core_slice_ext", issue = "32110")]
+macro_rules! slice_core_methods { () => {
+ /// Returns the number of elements in the slice.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let a = [1, 2, 3];
+ /// assert_eq!(a.len(), 3);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn len(&self) -> usize {
+ SliceExt::len(self)
+ }
+
+ /// Returns `true` if the slice has a length of 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let a = [1, 2, 3];
+ /// assert!(!a.is_empty());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn is_empty(&self) -> bool {
+ SliceExt::is_empty(self)
+ }
+
+ /// Returns the first element of the slice, or `None` if it is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = [10, 40, 30];
+ /// assert_eq!(Some(&10), v.first());
+ ///
+ /// let w: &[i32] = &[];
+ /// assert_eq!(None, w.first());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn first(&self) -> Option<&T> {
+ SliceExt::first(self)
+ }
+
+ /// Returns a mutable pointer to the first element of the slice, or `None` if it is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &mut [0, 1, 2];
+ ///
+ /// if let Some(first) = x.first_mut() {
+ /// *first = 5;
+ /// }
+ /// assert_eq!(x, &[5, 1, 2]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn first_mut(&mut self) -> Option<&mut T> {
+ SliceExt::first_mut(self)
+ }
+
+ /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &[0, 1, 2];
+ ///
+ /// if let Some((first, elements)) = x.split_first() {
+ /// assert_eq!(first, &0);
+ /// assert_eq!(elements, &[1, 2]);
+ /// }
+ /// ```
+ #[stable(feature = "slice_splits", since = "1.5.0")]
+ #[inline]
+ pub fn split_first(&self) -> Option<(&T, &[T])> {
+ SliceExt::split_first(self)
+ }
+
+ /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &mut [0, 1, 2];
+ ///
+ /// if let Some((first, elements)) = x.split_first_mut() {
+ /// *first = 3;
+ /// elements[0] = 4;
+ /// elements[1] = 5;
+ /// }
+ /// assert_eq!(x, &[3, 4, 5]);
+ /// ```
+ #[stable(feature = "slice_splits", since = "1.5.0")]
+ #[inline]
+ pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
+ SliceExt::split_first_mut(self)
+ }
+
+ /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &[0, 1, 2];
+ ///
+ /// if let Some((last, elements)) = x.split_last() {
+ /// assert_eq!(last, &2);
+ /// assert_eq!(elements, &[0, 1]);
+ /// }
+ /// ```
+ #[stable(feature = "slice_splits", since = "1.5.0")]
+ #[inline]
+ pub fn split_last(&self) -> Option<(&T, &[T])> {
+ SliceExt::split_last(self)
+
+ }
+
+ /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &mut [0, 1, 2];
+ ///
+ /// if let Some((last, elements)) = x.split_last_mut() {
+ /// *last = 3;
+ /// elements[0] = 4;
+ /// elements[1] = 5;
+ /// }
+ /// assert_eq!(x, &[4, 5, 3]);
+ /// ```
+ #[stable(feature = "slice_splits", since = "1.5.0")]
+ #[inline]
+ pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
+ SliceExt::split_last_mut(self)
+ }
+
+ /// Returns the last element of the slice, or `None` if it is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = [10, 40, 30];
+ /// assert_eq!(Some(&30), v.last());
+ ///
+ /// let w: &[i32] = &[];
+ /// assert_eq!(None, w.last());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn last(&self) -> Option<&T> {
+ SliceExt::last(self)
+ }
+
+ /// Returns a mutable pointer to the last item in the slice.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &mut [0, 1, 2];
+ ///
+ /// if let Some(last) = x.last_mut() {
+ /// *last = 10;
+ /// }
+ /// assert_eq!(x, &[0, 1, 10]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn last_mut(&mut self) -> Option<&mut T> {
+ SliceExt::last_mut(self)
+ }
+
+ /// Returns a reference to an element or subslice depending on the type of
+ /// index.
+ ///
+ /// - If given a position, returns a reference to the element at that
+ /// position or `None` if out of bounds.
+ /// - If given a range, returns the subslice corresponding to that range,
+ /// or `None` if out of bounds.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = [10, 40, 30];
+ /// assert_eq!(Some(&40), v.get(1));
+ /// assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+ /// assert_eq!(None, v.get(3));
+ /// assert_eq!(None, v.get(0..4));
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn get<I>(&self, index: I) -> Option<&I::Output>
+ where I: SliceIndex<Self>
+ {
+ SliceExt::get(self, index)
+ }
+
+ /// Returns a mutable reference to an element or subslice depending on the
+ /// type of index (see [`get`]) or `None` if the index is out of bounds.
+ ///
+ /// [`get`]: #method.get
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &mut [0, 1, 2];
+ ///
+ /// if let Some(elem) = x.get_mut(1) {
+ /// *elem = 42;
+ /// }
+ /// assert_eq!(x, &[0, 42, 2]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
+ where I: SliceIndex<Self>
+ {
+ SliceExt::get_mut(self, index)
+ }
+
+ /// Returns a reference to an element or subslice, without doing bounds
+ /// checking.
+ ///
+ /// This is generally not recommended, use with caution! For a safe
+ /// alternative see [`get`].
+ ///
+ /// [`get`]: #method.get
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &[1, 2, 4];
+ ///
+ /// unsafe {
+ /// assert_eq!(x.get_unchecked(1), &2);
+ /// }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
+ where I: SliceIndex<Self>
+ {
+ SliceExt::get_unchecked(self, index)
+ }
+
+ /// Returns a mutable reference to an element or subslice, without doing
+ /// bounds checking.
+ ///
+ /// This is generally not recommended, use with caution! For a safe
+ /// alternative see [`get_mut`].
+ ///
+ /// [`get_mut`]: #method.get_mut
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &mut [1, 2, 4];
+ ///
+ /// unsafe {
+ /// let elem = x.get_unchecked_mut(1);
+ /// *elem = 13;
+ /// }
+ /// assert_eq!(x, &[1, 13, 4]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
+ where I: SliceIndex<Self>
+ {
+ SliceExt::get_unchecked_mut(self, index)
+ }
+
+ /// Returns a raw pointer to the slice's buffer.
+ ///
+ /// The caller must ensure that the slice outlives the pointer this
+ /// function returns, or else it will end up pointing to garbage.
+ ///
+ /// Modifying the container referenced by this slice may cause its buffer
+ /// to be reallocated, which would also make any pointers to it invalid.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &[1, 2, 4];
+ /// let x_ptr = x.as_ptr();
+ ///
+ /// unsafe {
+ /// for i in 0..x.len() {
+ /// assert_eq!(x.get_unchecked(i), &*x_ptr.offset(i as isize));
+ /// }
+ /// }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn as_ptr(&self) -> *const T {
+ SliceExt::as_ptr(self)
+ }
+
+ /// Returns an unsafe mutable pointer to the slice's buffer.
+ ///
+ /// The caller must ensure that the slice outlives the pointer this
+ /// function returns, or else it will end up pointing to garbage.
+ ///
+ /// Modifying the container referenced by this slice may cause its buffer
+ /// to be reallocated, which would also make any pointers to it invalid.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &mut [1, 2, 4];
+ /// let x_ptr = x.as_mut_ptr();
+ ///
+ /// unsafe {
+ /// for i in 0..x.len() {
+ /// *x_ptr.offset(i as isize) += 2;
+ /// }
+ /// }
+ /// assert_eq!(x, &[3, 4, 6]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn as_mut_ptr(&mut self) -> *mut T {
+ SliceExt::as_mut_ptr(self)
+ }
+
+ /// Swaps two elements in the slice.
+ ///
+ /// # Arguments
+ ///
+ /// * a - The index of the first element
+ /// * b - The index of the second element
+ ///
+ /// # Panics
+ ///
+ /// Panics if `a` or `b` are out of bounds.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = ["a", "b", "c", "d"];
+ /// v.swap(1, 3);
+ /// assert!(v == ["a", "d", "c", "b"]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn swap(&mut self, a: usize, b: usize) {
+ SliceExt::swap(self, a, b)
+ }
+
+ /// Reverses the order of elements in the slice, in place.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = [1, 2, 3];
+ /// v.reverse();
+ /// assert!(v == [3, 2, 1]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn reverse(&mut self) {
+ SliceExt::reverse(self)
+ }
+
+ /// Returns an iterator over the slice.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &[1, 2, 4];
+ /// let mut iterator = x.iter();
+ ///
+ /// assert_eq!(iterator.next(), Some(&1));
+ /// assert_eq!(iterator.next(), Some(&2));
+ /// assert_eq!(iterator.next(), Some(&4));
+ /// assert_eq!(iterator.next(), None);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn iter(&self) -> Iter<T> {
+ SliceExt::iter(self)
+ }
+
+ /// Returns an iterator that allows modifying each value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = &mut [1, 2, 4];
+ /// for elem in x.iter_mut() {
+ /// *elem += 2;
+ /// }
+ /// assert_eq!(x, &[3, 4, 6]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn iter_mut(&mut self) -> IterMut<T> {
+ SliceExt::iter_mut(self)
+ }
+
+ /// Returns an iterator over all contiguous windows of length
+ /// `size`. The windows overlap. If the slice is shorter than
+ /// `size`, the iterator returns no values.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `size` is 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let slice = ['r', 'u', 's', 't'];
+ /// let mut iter = slice.windows(2);
+ /// assert_eq!(iter.next().unwrap(), &['r', 'u']);
+ /// assert_eq!(iter.next().unwrap(), &['u', 's']);
+ /// assert_eq!(iter.next().unwrap(), &['s', 't']);
+ /// assert!(iter.next().is_none());
+ /// ```
+ ///
+ /// If the slice is shorter than `size`:
+ ///
+ /// ```
+ /// let slice = ['f', 'o', 'o'];
+ /// let mut iter = slice.windows(4);
+ /// assert!(iter.next().is_none());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn windows(&self, size: usize) -> Windows<T> {
+ SliceExt::windows(self, size)
+ }
+
+ /// Returns an iterator over `chunk_size` elements of the slice at a
+ /// time. The chunks are slices and do not overlap. If `chunk_size` does
+ /// not divide the length of the slice, then the last chunk will
+ /// not have length `chunk_size`.
+ ///
+ /// See [`exact_chunks`] for a variant of this iterator that returns chunks
+ /// of always exactly `chunk_size` elements.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `chunk_size` is 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let slice = ['l', 'o', 'r', 'e', 'm'];
+ /// let mut iter = slice.chunks(2);
+ /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
+ /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
+ /// assert_eq!(iter.next().unwrap(), &['m']);
+ /// assert!(iter.next().is_none());
+ /// ```
+ ///
+ /// [`exact_chunks`]: #method.exact_chunks
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn chunks(&self, chunk_size: usize) -> Chunks<T> {
+ SliceExt::chunks(self, chunk_size)
+ }
+
+ /// Returns an iterator over `chunk_size` elements of the slice at a
+ /// time. The chunks are slices and do not overlap. If `chunk_size` does
+ /// not divide the length of the slice, then the last up to `chunk_size-1`
+ /// elements will be omitted.
+ ///
+ /// Due to each chunk having exactly `chunk_size` elements, the compiler
+ /// can often optimize the resulting code better than in the case of
+ /// [`chunks`].
+ ///
+ /// # Panics
+ ///
+ /// Panics if `chunk_size` is 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(exact_chunks)]
+ ///
+ /// let slice = ['l', 'o', 'r', 'e', 'm'];
+ /// let mut iter = slice.exact_chunks(2);
+ /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
+ /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
+ /// assert!(iter.next().is_none());
+ /// ```
+ ///
+ /// [`chunks`]: #method.chunks
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ #[inline]
+ pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
+ SliceExt::exact_chunks(self, chunk_size)
+ }
+
+ /// Returns an iterator over `chunk_size` elements of the slice at a time.
+ /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
+ /// not divide the length of the slice, then the last chunk will not
+ /// have length `chunk_size`.
+ ///
+ /// See [`exact_chunks_mut`] for a variant of this iterator that returns chunks
+ /// of always exactly `chunk_size` elements.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `chunk_size` is 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = &mut [0, 0, 0, 0, 0];
+ /// let mut count = 1;
+ ///
+ /// for chunk in v.chunks_mut(2) {
+ /// for elem in chunk.iter_mut() {
+ /// *elem += count;
+ /// }
+ /// count += 1;
+ /// }
+ /// assert_eq!(v, &[1, 1, 2, 2, 3]);
+ /// ```
+ ///
+ /// [`exact_chunks_mut`]: #method.exact_chunks_mut
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
+ SliceExt::chunks_mut(self, chunk_size)
+ }
+
+ /// Returns an iterator over `chunk_size` elements of the slice at a time.
+ /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
+ /// not divide the length of the slice, then the last up to `chunk_size-1`
+ /// elements will be omitted.
+ ///
+ ///
+ /// Due to each chunk having exactly `chunk_size` elements, the compiler
+ /// can often optimize the resulting code better than in the case of
+ /// [`chunks_mut`].
+ ///
+ /// # Panics
+ ///
+ /// Panics if `chunk_size` is 0.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(exact_chunks)]
+ ///
+ /// let v = &mut [0, 0, 0, 0, 0];
+ /// let mut count = 1;
+ ///
+ /// for chunk in v.exact_chunks_mut(2) {
+ /// for elem in chunk.iter_mut() {
+ /// *elem += count;
+ /// }
+ /// count += 1;
+ /// }
+ /// assert_eq!(v, &[1, 1, 2, 2, 0]);
+ /// ```
+ ///
+ /// [`chunks_mut`]: #method.chunks_mut
+ #[unstable(feature = "exact_chunks", issue = "47115")]
+ #[inline]
+ pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
+ SliceExt::exact_chunks_mut(self, chunk_size)
+ }
+
+ /// Divides one slice into two at an index.
+ ///
+ /// The first will contain all indices from `[0, mid)` (excluding
+ /// the index `mid` itself) and the second will contain all
+ /// indices from `[mid, len)` (excluding the index `len` itself).
+ ///
+ /// # Panics
+ ///
+ /// Panics if `mid > len`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = [1, 2, 3, 4, 5, 6];
+ ///
+ /// {
+ /// let (left, right) = v.split_at(0);
+ /// assert!(left == []);
+ /// assert!(right == [1, 2, 3, 4, 5, 6]);
+ /// }
+ ///
+ /// {
+ /// let (left, right) = v.split_at(2);
+ /// assert!(left == [1, 2]);
+ /// assert!(right == [3, 4, 5, 6]);
+ /// }
+ ///
+ /// {
+ /// let (left, right) = v.split_at(6);
+ /// assert!(left == [1, 2, 3, 4, 5, 6]);
+ /// assert!(right == []);
+ /// }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
+ SliceExt::split_at(self, mid)
+ }
+
+ /// Divides one mutable slice into two at an index.
+ ///
+ /// The first will contain all indices from `[0, mid)` (excluding
+ /// the index `mid` itself) and the second will contain all
+ /// indices from `[mid, len)` (excluding the index `len` itself).
+ ///
+ /// # Panics
+ ///
+ /// Panics if `mid > len`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = [1, 0, 3, 0, 5, 6];
+ /// // scoped to restrict the lifetime of the borrows
+ /// {
+ /// let (left, right) = v.split_at_mut(2);
+ /// assert!(left == [1, 0]);
+ /// assert!(right == [3, 0, 5, 6]);
+ /// left[1] = 2;
+ /// right[1] = 4;
+ /// }
+ /// assert!(v == [1, 2, 3, 4, 5, 6]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
+ SliceExt::split_at_mut(self, mid)
+ }
+
+ /// Returns an iterator over subslices separated by elements that match
+ /// `pred`. The matched element is not contained in the subslices.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let slice = [10, 40, 33, 20];
+ /// let mut iter = slice.split(|num| num % 3 == 0);
+ ///
+ /// assert_eq!(iter.next().unwrap(), &[10, 40]);
+ /// assert_eq!(iter.next().unwrap(), &[20]);
+ /// assert!(iter.next().is_none());
+ /// ```
+ ///
+ /// If the first element is matched, an empty slice will be the first item
+ /// returned by the iterator. Similarly, if the last element in the slice
+ /// is matched, an empty slice will be the last item returned by the
+ /// iterator:
+ ///
+ /// ```
+ /// let slice = [10, 40, 33];
+ /// let mut iter = slice.split(|num| num % 3 == 0);
+ ///
+ /// assert_eq!(iter.next().unwrap(), &[10, 40]);
+ /// assert_eq!(iter.next().unwrap(), &[]);
+ /// assert!(iter.next().is_none());
+ /// ```
+ ///
+ /// If two matched elements are directly adjacent, an empty slice will be
+ /// present between them:
+ ///
+ /// ```
+ /// let slice = [10, 6, 33, 20];
+ /// let mut iter = slice.split(|num| num % 3 == 0);
+ ///
+ /// assert_eq!(iter.next().unwrap(), &[10]);
+ /// assert_eq!(iter.next().unwrap(), &[]);
+ /// assert_eq!(iter.next().unwrap(), &[20]);
+ /// assert!(iter.next().is_none());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn split<F>(&self, pred: F) -> Split<T, F>
+ where F: FnMut(&T) -> bool
+ {
+ SliceExt::split(self, pred)
+ }
+
+ /// Returns an iterator over mutable subslices separated by elements that
+ /// match `pred`. The matched element is not contained in the subslices.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = [10, 40, 30, 20, 60, 50];
+ ///
+ /// for group in v.split_mut(|num| *num % 3 == 0) {
+ /// group[0] = 1;
+ /// }
+ /// assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
+ where F: FnMut(&T) -> bool
+ {
+ SliceExt::split_mut(self, pred)
+ }
+
+ /// Returns an iterator over subslices separated by elements that match
+ /// `pred`, starting at the end of the slice and working backwards.
+ /// The matched element is not contained in the subslices.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let slice = [11, 22, 33, 0, 44, 55];
+ /// let mut iter = slice.rsplit(|num| *num == 0);
+ ///
+ /// assert_eq!(iter.next().unwrap(), &[44, 55]);
+ /// assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+ /// assert_eq!(iter.next(), None);
+ /// ```
+ ///
+ /// As with `split()`, if the first or last element is matched, an empty
+ /// slice will be the first (or last) item returned by the iterator.
+ ///
+ /// ```
+ /// let v = &[0, 1, 1, 2, 3, 5, 8];
+ /// let mut it = v.rsplit(|n| *n % 2 == 0);
+ /// assert_eq!(it.next().unwrap(), &[]);
+ /// assert_eq!(it.next().unwrap(), &[3, 5]);
+ /// assert_eq!(it.next().unwrap(), &[1, 1]);
+ /// assert_eq!(it.next().unwrap(), &[]);
+ /// assert_eq!(it.next(), None);
+ /// ```
+ #[stable(feature = "slice_rsplit", since = "1.27.0")]
+ #[inline]
+ pub fn rsplit<F>(&self, pred: F) -> RSplit<T, F>
+ where F: FnMut(&T) -> bool
+ {
+ SliceExt::rsplit(self, pred)
+ }
+
+ /// Returns an iterator over mutable subslices separated by elements that
+ /// match `pred`, starting at the end of the slice and working
+ /// backwards. The matched element is not contained in the subslices.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = [100, 400, 300, 200, 600, 500];
+ ///
+ /// let mut count = 0;
+ /// for group in v.rsplit_mut(|num| *num % 3 == 0) {
+ /// count += 1;
+ /// group[0] = count;
+ /// }
+ /// assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+ /// ```
+ ///
+ #[stable(feature = "slice_rsplit", since = "1.27.0")]
+ #[inline]
+ pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<T, F>
+ where F: FnMut(&T) -> bool
+ {
+ SliceExt::rsplit_mut(self, pred)
+ }
+
+ /// Returns an iterator over subslices separated by elements that match
+ /// `pred`, limited to returning at most `n` items. The matched element is
+ /// not contained in the subslices.
+ ///
+ /// The last element returned, if any, will contain the remainder of the
+ /// slice.
+ ///
+ /// # Examples
+ ///
+ /// Print the slice split once by numbers divisible by 3 (i.e. `[10, 40]`,
+ /// `[20, 60, 50]`):
+ ///
+ /// ```
+ /// let v = [10, 40, 30, 20, 60, 50];
+ ///
+ /// for group in v.splitn(2, |num| *num % 3 == 0) {
+ /// println!("{:?}", group);
+ /// }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, F>
+ where F: FnMut(&T) -> bool
+ {
+ SliceExt::splitn(self, n, pred)
+ }
+
+ /// Returns an iterator over subslices separated by elements that match
+ /// `pred`, limited to returning at most `n` items. The matched element is
+ /// not contained in the subslices.
+ ///
+ /// The last element returned, if any, will contain the remainder of the
+ /// slice.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = [10, 40, 30, 20, 60, 50];
+ ///
+ /// for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+ /// group[0] = 1;
+ /// }
+ /// assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, F>
+ where F: FnMut(&T) -> bool
+ {
+ SliceExt::splitn_mut(self, n, pred)
+ }
+
+ /// Returns an iterator over subslices separated by elements that match
+ /// `pred` limited to returning at most `n` items. This starts at the end of
+ /// the slice and works backwards. The matched element is not contained in
+ /// the subslices.
+ ///
+ /// The last element returned, if any, will contain the remainder of the
+ /// slice.
+ ///
+ /// # Examples
+ ///
+ /// Print the slice split once, starting from the end, by numbers divisible
+ /// by 3 (i.e. `[50]`, `[10, 40, 30, 20]`):
+ ///
+ /// ```
+ /// let v = [10, 40, 30, 20, 60, 50];
+ ///
+ /// for group in v.rsplitn(2, |num| *num % 3 == 0) {
+ /// println!("{:?}", group);
+ /// }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, F>
+ where F: FnMut(&T) -> bool
+ {
+ SliceExt::rsplitn(self, n, pred)
+ }
+
+ /// Returns an iterator over subslices separated by elements that match
+ /// `pred` limited to returning at most `n` items. This starts at the end of
+ /// the slice and works backwards. The matched element is not contained in
+ /// the subslices.
+ ///
+ /// The last element returned, if any, will contain the remainder of the
+ /// slice.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut s = [10, 40, 30, 20, 60, 50];
+ ///
+ /// for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+ /// group[0] = 1;
+ /// }
+ /// assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<T, F>
+ where F: FnMut(&T) -> bool
+ {
+ SliceExt::rsplitn_mut(self, n, pred)
+ }
+
+ /// Returns `true` if the slice contains an element with the given value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = [10, 40, 30];
+ /// assert!(v.contains(&30));
+ /// assert!(!v.contains(&50));
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn contains(&self, x: &T) -> bool
+ where T: PartialEq
+ {
+ SliceExt::contains(self, x)
+ }
+
+ /// Returns `true` if `needle` is a prefix of the slice.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = [10, 40, 30];
+ /// assert!(v.starts_with(&[10]));
+ /// assert!(v.starts_with(&[10, 40]));
+ /// assert!(!v.starts_with(&[50]));
+ /// assert!(!v.starts_with(&[10, 50]));
+ /// ```
+ ///
+ /// Always returns `true` if `needle` is an empty slice:
+ ///
+ /// ```
+ /// let v = &[10, 40, 30];
+ /// assert!(v.starts_with(&[]));
+ /// let v: &[u8] = &[];
+ /// assert!(v.starts_with(&[]));
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn starts_with(&self, needle: &[T]) -> bool
+ where T: PartialEq
+ {
+ SliceExt::starts_with(self, needle)
+ }
+
+ /// Returns `true` if `needle` is a suffix of the slice.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = [10, 40, 30];
+ /// assert!(v.ends_with(&[30]));
+ /// assert!(v.ends_with(&[40, 30]));
+ /// assert!(!v.ends_with(&[50]));
+ /// assert!(!v.ends_with(&[50, 30]));
+ /// ```
+ ///
+ /// Always returns `true` if `needle` is an empty slice:
+ ///
+ /// ```
+ /// let v = &[10, 40, 30];
+ /// assert!(v.ends_with(&[]));
+ /// let v: &[u8] = &[];
+ /// assert!(v.ends_with(&[]));
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn ends_with(&self, needle: &[T]) -> bool
+ where T: PartialEq
+ {
+ SliceExt::ends_with(self, needle)
+ }
+
+ /// Binary searches this sorted slice for a given element.
+ ///
+ /// If the value is found then `Ok` is returned, containing the
+ /// index of the matching element; if the value is not found then
+ /// `Err` is returned, containing the index where a matching
+ /// element could be inserted while maintaining sorted order.
+ ///
+ /// # Examples
+ ///
+ /// Looks up a series of four elements. The first is found, with a
+ /// uniquely determined position; the second and third are not
+ /// found; the fourth could match any position in `[1, 4]`.
+ ///
+ /// ```
+ /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+ ///
+ /// assert_eq!(s.binary_search(&13), Ok(9));
+ /// assert_eq!(s.binary_search(&4), Err(7));
+ /// assert_eq!(s.binary_search(&100), Err(13));
+ /// let r = s.binary_search(&1);
+ /// assert!(match r { Ok(1...4) => true, _ => false, });
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn binary_search(&self, x: &T) -> Result<usize, usize>
+ where T: Ord
+ {
+ SliceExt::binary_search(self, x)
+ }
+
+ /// Binary searches this sorted slice with a comparator function.
+ ///
+ /// The comparator function should implement an order consistent
+ /// with the sort order of the underlying slice, returning an
+ /// order code that indicates whether its argument is `Less`,
+ /// `Equal` or `Greater` the desired target.
+ ///
+ /// If a matching value is found then returns `Ok`, containing
+ /// the index for the matched element; if no match is found then
+ /// `Err` is returned, containing the index where a matching
+ /// element could be inserted while maintaining sorted order.
+ ///
+ /// # Examples
+ ///
+ /// Looks up a series of four elements. The first is found, with a
+ /// uniquely determined position; the second and third are not
+ /// found; the fourth could match any position in `[1, 4]`.
+ ///
+ /// ```
+ /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+ ///
+ /// let seek = 13;
+ /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+ /// let seek = 4;
+ /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+ /// let seek = 100;
+ /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+ /// let seek = 1;
+ /// let r = s.binary_search_by(|probe| probe.cmp(&seek));
+ /// assert!(match r { Ok(1...4) => true, _ => false, });
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
+ where F: FnMut(&'a T) -> Ordering
+ {
+ SliceExt::binary_search_by(self, f)
+ }
+
+ /// Binary searches this sorted slice with a key extraction function.
+ ///
+ /// Assumes that the slice is sorted by the key, for instance with
+ /// [`sort_by_key`] using the same key extraction function.
+ ///
+ /// If a matching value is found then returns `Ok`, containing the
+ /// index for the matched element; if no match is found then `Err`
+ /// is returned, containing the index where a matching element could
+ /// be inserted while maintaining sorted order.
+ ///
+ /// [`sort_by_key`]: #method.sort_by_key
+ ///
+ /// # Examples
+ ///
+ /// Looks up a series of four elements in a slice of pairs sorted by
+ /// their second elements. The first is found, with a uniquely
+ /// determined position; the second and third are not found; the
+ /// fourth could match any position in `[1, 4]`.
+ ///
+ /// ```
+ /// let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+ /// (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+ /// (1, 21), (2, 34), (4, 55)];
+ ///
+ /// assert_eq!(s.binary_search_by_key(&13, |&(a,b)| b), Ok(9));
+ /// assert_eq!(s.binary_search_by_key(&4, |&(a,b)| b), Err(7));
+ /// assert_eq!(s.binary_search_by_key(&100, |&(a,b)| b), Err(13));
+ /// let r = s.binary_search_by_key(&1, |&(a,b)| b);
+ /// assert!(match r { Ok(1...4) => true, _ => false, });
+ /// ```
+ #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
+ #[inline]
+ pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<usize, usize>
+ where F: FnMut(&'a T) -> B,
+ B: Ord
+ {
+ SliceExt::binary_search_by_key(self, b, f)
+ }
+
+ /// Sorts the slice, but may not preserve the order of equal elements.
+ ///
+ /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
+ /// and `O(n log n)` worst-case.
+ ///
+ /// # Current implementation
+ ///
+ /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters,
+ /// which combines the fast average case of randomized quicksort with the fast worst case of
+ /// heapsort, while achieving linear time on slices with certain patterns. It uses some
+ /// randomization to avoid degenerate cases, but with a fixed seed to always provide
+ /// deterministic behavior.
+ ///
+ /// It is typically faster than stable sorting, except in a few special cases, e.g. when the
+ /// slice consists of several concatenated sorted sequences.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = [-5, 4, 1, -3, 2];
+ ///
+ /// v.sort_unstable();
+ /// assert!(v == [-5, -3, 1, 2, 4]);
+ /// ```
+ ///
+ /// [pdqsort]: https://github.com/orlp/pdqsort
+ #[stable(feature = "sort_unstable", since = "1.20.0")]
+ #[inline]
+ pub fn sort_unstable(&mut self)
+ where T: Ord
+ {
+ SliceExt::sort_unstable(self);
+ }
+
+ /// Sorts the slice with a comparator function, but may not preserve the order of equal
+ /// elements.
+ ///
+ /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
+ /// and `O(n log n)` worst-case.
+ ///
+ /// # Current implementation
+ ///
+ /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters,
+ /// which combines the fast average case of randomized quicksort with the fast worst case of
+ /// heapsort, while achieving linear time on slices with certain patterns. It uses some
+ /// randomization to avoid degenerate cases, but with a fixed seed to always provide
+ /// deterministic behavior.
+ ///
+ /// It is typically faster than stable sorting, except in a few special cases, e.g. when the
+ /// slice consists of several concatenated sorted sequences.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = [5, 4, 1, 3, 2];
+ /// v.sort_unstable_by(|a, b| a.cmp(b));
+ /// assert!(v == [1, 2, 3, 4, 5]);
+ ///
+ /// // reverse sorting
+ /// v.sort_unstable_by(|a, b| b.cmp(a));
+ /// assert!(v == [5, 4, 3, 2, 1]);
+ /// ```
+ ///
+ /// [pdqsort]: https://github.com/orlp/pdqsort
+ #[stable(feature = "sort_unstable", since = "1.20.0")]
+ #[inline]
+ pub fn sort_unstable_by<F>(&mut self, compare: F)
+ where F: FnMut(&T, &T) -> Ordering
+ {
+ SliceExt::sort_unstable_by(self, compare);
+ }
+
+ /// Sorts the slice with a key extraction function, but may not preserve the order of equal
+ /// elements.
+ ///
+ /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate),
+ /// and `O(m n log(m n))` worst-case, where the key function is `O(m)`.
+ ///
+ /// # Current implementation
+ ///
+ /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters,
+ /// which combines the fast average case of randomized quicksort with the fast worst case of
+ /// heapsort, while achieving linear time on slices with certain patterns. It uses some
+ /// randomization to avoid degenerate cases, but with a fixed seed to always provide
+ /// deterministic behavior.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = [-5i32, 4, 1, -3, 2];
+ ///
+ /// v.sort_unstable_by_key(|k| k.abs());
+ /// assert!(v == [1, 2, -3, 4, -5]);
+ /// ```
+ ///
+ /// [pdqsort]: https://github.com/orlp/pdqsort
+ #[stable(feature = "sort_unstable", since = "1.20.0")]
+ #[inline]
+ pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
+ where F: FnMut(&T) -> K, K: Ord
+ {
+ SliceExt::sort_unstable_by_key(self, f);
+ }
+
+ /// Rotates the slice in-place such that the first `mid` elements of the
+ /// slice move to the end while the last `self.len() - mid` elements move to
+ /// the front. After calling `rotate_left`, the element previously at index
+ /// `mid` will become the first element in the slice.
+ ///
+ /// # Panics
+ ///
+ /// This function will panic if `mid` is greater than the length of the
+ /// slice. Note that `mid == self.len()` does _not_ panic and is a no-op
+ /// rotation.
+ ///
+ /// # Complexity
+ ///
+ /// Takes linear (in `self.len()`) time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a.rotate_left(2);
+ /// assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+ /// ```
+ ///
+ /// Rotating a subslice:
+ ///
+ /// ```
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a[1..5].rotate_left(1);
+ /// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+ /// ```
+ #[stable(feature = "slice_rotate", since = "1.26.0")]
+ pub fn rotate_left(&mut self, mid: usize) {
+ SliceExt::rotate_left(self, mid);
+ }
+
+ /// Rotates the slice in-place such that the first `self.len() - k`
+ /// elements of the slice move to the end while the last `k` elements move
+ /// to the front. After calling `rotate_right`, the element previously at
+ /// index `self.len() - k` will become the first element in the slice.
+ ///
+ /// # Panics
+ ///
+ /// This function will panic if `k` is greater than the length of the
+ /// slice. Note that `k == self.len()` does _not_ panic and is a no-op
+ /// rotation.
+ ///
+ /// # Complexity
+ ///
+ /// Takes linear (in `self.len()`) time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a.rotate_right(2);
+ /// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+ /// ```
+ ///
+ /// Rotate a subslice:
+ ///
+ /// ```
+ /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+ /// a[1..5].rotate_right(1);
+ /// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+ /// ```
+ #[stable(feature = "slice_rotate", since = "1.26.0")]
+ pub fn rotate_right(&mut self, k: usize) {
+ SliceExt::rotate_right(self, k);
+ }
+
+ /// Copies the elements from `src` into `self`.
+ ///
+ /// The length of `src` must be the same as `self`.
+ ///
+ /// If `src` implements `Copy`, it can be more performant to use
+ /// [`copy_from_slice`].
+ ///
+ /// # Panics
+ ///
+ /// This function will panic if the two slices have different lengths.
+ ///
+ /// # Examples
+ ///
+ /// Cloning two elements from a slice into another:
+ ///
+ /// ```
+ /// let src = [1, 2, 3, 4];
+ /// let mut dst = [0, 0];
+ ///
+ /// dst.clone_from_slice(&src[2..]);
+ ///
+ /// assert_eq!(src, [1, 2, 3, 4]);
+ /// assert_eq!(dst, [3, 4]);
+ /// ```
+ ///
+ /// Rust enforces that there can only be one mutable reference with no
+ /// immutable references to a particular piece of data in a particular
+ /// scope. Because of this, attempting to use `clone_from_slice` on a
+ /// single slice will result in a compile failure:
+ ///
+ /// ```compile_fail
+ /// let mut slice = [1, 2, 3, 4, 5];
+ ///
+ /// slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+ /// ```
+ ///
+ /// To work around this, we can use [`split_at_mut`] to create two distinct
+ /// sub-slices from a slice:
+ ///
+ /// ```
+ /// let mut slice = [1, 2, 3, 4, 5];
+ ///
+ /// {
+ /// let (left, right) = slice.split_at_mut(2);
+ /// left.clone_from_slice(&right[1..]);
+ /// }
+ ///
+ /// assert_eq!(slice, [4, 5, 3, 4, 5]);
+ /// ```
+ ///
+ /// [`copy_from_slice`]: #method.copy_from_slice
+ /// [`split_at_mut`]: #method.split_at_mut
+ #[stable(feature = "clone_from_slice", since = "1.7.0")]
+ pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
+ SliceExt::clone_from_slice(self, src)
+ }
+
+ /// Copies all elements from `src` into `self`, using a memcpy.
+ ///
+ /// The length of `src` must be the same as `self`.
+ ///
+ /// If `src` does not implement `Copy`, use [`clone_from_slice`].
+ ///
+ /// # Panics
+ ///
+ /// This function will panic if the two slices have different lengths.
+ ///
+ /// # Examples
+ ///
+ /// Copying two elements from a slice into another:
+ ///
+ /// ```
+ /// let src = [1, 2, 3, 4];
+ /// let mut dst = [0, 0];
+ ///
+ /// dst.copy_from_slice(&src[2..]);
+ ///
+ /// assert_eq!(src, [1, 2, 3, 4]);
+ /// assert_eq!(dst, [3, 4]);
+ /// ```
+ ///
+ /// Rust enforces that there can only be one mutable reference with no
+ /// immutable references to a particular piece of data in a particular
+ /// scope. Because of this, attempting to use `copy_from_slice` on a
+ /// single slice will result in a compile failure:
+ ///
+ /// ```compile_fail
+ /// let mut slice = [1, 2, 3, 4, 5];
+ ///
+ /// slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+ /// ```
+ ///
+ /// To work around this, we can use [`split_at_mut`] to create two distinct
+ /// sub-slices from a slice:
+ ///
+ /// ```
+ /// let mut slice = [1, 2, 3, 4, 5];
+ ///
+ /// {
+ /// let (left, right) = slice.split_at_mut(2);
+ /// left.copy_from_slice(&right[1..]);
+ /// }
+ ///
+ /// assert_eq!(slice, [4, 5, 3, 4, 5]);
+ /// ```
+ ///
+ /// [`clone_from_slice`]: #method.clone_from_slice
+ /// [`split_at_mut`]: #method.split_at_mut
+ #[stable(feature = "copy_from_slice", since = "1.9.0")]
+ pub fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
+ SliceExt::copy_from_slice(self, src)
+ }
+
+ /// Swaps all elements in `self` with those in `other`.
+ ///
+ /// The length of `other` must be the same as `self`.
+ ///
+ /// # Panics
+ ///
+ /// This function will panic if the two slices have different lengths.
+ ///
+ /// # Example
+ ///
+ /// Swapping two elements across slices:
+ ///
+ /// ```
+ /// let mut slice1 = [0, 0];
+ /// let mut slice2 = [1, 2, 3, 4];
+ ///
+ /// slice1.swap_with_slice(&mut slice2[2..]);
+ ///
+ /// assert_eq!(slice1, [3, 4]);
+ /// assert_eq!(slice2, [1, 2, 0, 0]);
+ /// ```
+ ///
+ /// Rust enforces that there can only be one mutable reference to a
+ /// particular piece of data in a particular scope. Because of this,
+ /// attempting to use `swap_with_slice` on a single slice will result in
+ /// a compile failure:
+ ///
+ /// ```compile_fail
+ /// let mut slice = [1, 2, 3, 4, 5];
+ /// slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+ /// ```
+ ///
+ /// To work around this, we can use [`split_at_mut`] to create two distinct
+ /// mutable sub-slices from a slice:
+ ///
+ /// ```
+ /// let mut slice = [1, 2, 3, 4, 5];
+ ///
+ /// {
+ /// let (left, right) = slice.split_at_mut(2);
+ /// left.swap_with_slice(&mut right[1..]);
+ /// }
+ ///
+ /// assert_eq!(slice, [4, 5, 3, 1, 2]);
+ /// ```
+ ///
+ /// [`split_at_mut`]: #method.split_at_mut
+ #[stable(feature = "swap_with_slice", since = "1.27.0")]
+ pub fn swap_with_slice(&mut self, other: &mut [T]) {
+ SliceExt::swap_with_slice(self, other)
+ }
+}}
+
+#[lang = "slice"]
+#[cfg(not(test))]
+#[cfg(not(stage0))]
+impl<T> [T] {
+ slice_core_methods!();
+}
+
+// FIXME: remove (inline) this macro
+// when updating to a bootstrap compiler that has the new lang items.
+#[cfg_attr(stage0, macro_export)]
+#[unstable(feature = "core_slice_ext", issue = "32110")]
+macro_rules! slice_u8_core_methods { () => {
+ /// Checks if all bytes in this slice are within the ASCII range.
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn is_ascii(&self) -> bool {
+ self.iter().all(|b| b.is_ascii())
+ }
+
+ /// Checks that two slices are an ASCII case-insensitive match.
+ ///
+ /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
+ /// but without allocating and copying temporaries.
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
+ self.len() == other.len() &&
+ self.iter().zip(other).all(|(a, b)| {
+ a.eq_ignore_ascii_case(b)
+ })
+ }
+
+ /// Converts this slice to its ASCII upper case equivalent in-place.
+ ///
+ /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
+ /// but non-ASCII letters are unchanged.
+ ///
+ /// To return a new uppercased value without modifying the existing one, use
+ /// [`to_ascii_uppercase`].
+ ///
+ /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn make_ascii_uppercase(&mut self) {
+ for byte in self {
+ byte.make_ascii_uppercase();
+ }
+ }
+
+ /// Converts this slice to its ASCII lower case equivalent in-place.
+ ///
+ /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
+ /// but non-ASCII letters are unchanged.
+ ///
+ /// To return a new lowercased value without modifying the existing one, use
+ /// [`to_ascii_lowercase`].
+ ///
+ /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn make_ascii_lowercase(&mut self) {
+ for byte in self {
+ byte.make_ascii_lowercase();
+ }
+ }
+}}
+
+#[lang = "slice_u8"]
+#[cfg(not(test))]
+#[cfg(not(stage0))]
+impl [u8] {
+ slice_u8_core_methods!();
+}
+
#[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]
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 5b52119d031..b39d9feb35b 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2112,14 +2112,16 @@ mod traits {
}
-
+public_in_stage0! {
+{
/// Methods for string slices
#[allow(missing_docs)]
#[doc(hidden)]
#[unstable(feature = "core_str_ext",
reason = "stable interface provided by `impl str` in later crates",
issue = "32110")]
-pub trait StrExt {
+}
+trait StrExt {
// NB there are no docs here are they're all located on the StrExt trait in
// liballoc, not here.
@@ -2213,17 +2215,13 @@ pub trait StrExt {
fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
#[stable(feature = "split_whitespace", since = "1.1.0")]
fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
- #[stable(feature = "unicode_methods_on_intrinsics", since = "1.27.0")]
- fn is_whitespace(&self) -> bool;
- #[stable(feature = "unicode_methods_on_intrinsics", since = "1.27.0")]
- fn is_alphanumeric(&self) -> bool;
#[stable(feature = "rust1", since = "1.0.0")]
fn trim(&self) -> &str;
#[stable(feature = "rust1", since = "1.0.0")]
fn trim_left(&self) -> &str;
#[stable(feature = "rust1", since = "1.0.0")]
fn trim_right(&self) -> &str;
-}
+}}
// truncate `&str` to length at most equal to `max`
// return `true` if it were truncated, and the new str.
@@ -2550,16 +2548,6 @@ impl StrExt for str {
}
#[inline]
- fn is_whitespace(&self) -> bool {
- self.chars().all(|c| c.is_whitespace())
- }
-
- #[inline]
- fn is_alphanumeric(&self) -> bool {
- self.chars().all(|c| c.is_alphanumeric())
- }
-
- #[inline]
fn trim(&self) -> &str {
self.trim_matches(|c: char| c.is_whitespace())
}
@@ -2575,6 +2563,1685 @@ impl StrExt for str {
}
}
+// FIXME: remove (inline) this macro and the SliceExt trait
+// when updating to a bootstrap compiler that has the new lang items.
+#[cfg_attr(stage0, macro_export)]
+#[unstable(feature = "core_str_ext", issue = "32110")]
+macro_rules! str_core_methods { () => {
+ /// Returns the length of `self`.
+ ///
+ /// This length is in bytes, not [`char`]s or graphemes. In other words,
+ /// it may not be what a human considers the length of the string.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let len = "foo".len();
+ /// assert_eq!(3, len);
+ ///
+ /// let len = "ƒoo".len(); // fancy f!
+ /// assert_eq!(4, len);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn len(&self) -> usize {
+ StrExt::len(self)
+ }
+
+ /// Returns `true` if `self` has a length of zero bytes.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let s = "";
+ /// assert!(s.is_empty());
+ ///
+ /// let s = "not empty";
+ /// assert!(!s.is_empty());
+ /// ```
+ #[inline]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn is_empty(&self) -> bool {
+ StrExt::is_empty(self)
+ }
+
+ /// Checks that `index`-th byte lies at the start and/or end of a
+ /// UTF-8 code point sequence.
+ ///
+ /// The start and end of the string (when `index == self.len()`) are
+ /// considered to be
+ /// boundaries.
+ ///
+ /// Returns `false` if `index` is greater than `self.len()`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let s = "Löwe 老虎 Léopard";
+ /// assert!(s.is_char_boundary(0));
+ /// // start of `老`
+ /// assert!(s.is_char_boundary(6));
+ /// assert!(s.is_char_boundary(s.len()));
+ ///
+ /// // second byte of `ö`
+ /// assert!(!s.is_char_boundary(2));
+ ///
+ /// // third byte of `老`
+ /// assert!(!s.is_char_boundary(8));
+ /// ```
+ #[stable(feature = "is_char_boundary", since = "1.9.0")]
+ #[inline]
+ pub fn is_char_boundary(&self, index: usize) -> bool {
+ StrExt::is_char_boundary(self, index)
+ }
+
+ /// Converts a string slice to a byte slice. To convert the byte slice back
+ /// into a string slice, use the [`str::from_utf8`] function.
+ ///
+ /// [`str::from_utf8`]: ./str/fn.from_utf8.html
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let bytes = "bors".as_bytes();
+ /// assert_eq!(b"bors", bytes);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline(always)]
+ pub fn as_bytes(&self) -> &[u8] {
+ StrExt::as_bytes(self)
+ }
+
+ /// Converts a mutable string slice to a mutable byte slice. To convert the
+ /// mutable byte slice back into a mutable string slice, use the
+ /// [`str::from_utf8_mut`] function.
+ ///
+ /// [`str::from_utf8_mut`]: ./str/fn.from_utf8_mut.html
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let mut s = String::from("Hello");
+ /// let bytes = unsafe { s.as_bytes_mut() };
+ ///
+ /// assert_eq!(b"Hello", bytes);
+ /// ```
+ ///
+ /// Mutability:
+ ///
+ /// ```
+ /// let mut s = String::from("🗻∈🌏");
+ ///
+ /// unsafe {
+ /// let bytes = s.as_bytes_mut();
+ ///
+ /// bytes[0] = 0xF0;
+ /// bytes[1] = 0x9F;
+ /// bytes[2] = 0x8D;
+ /// bytes[3] = 0x94;
+ /// }
+ ///
+ /// assert_eq!("🍔∈🌏", s);
+ /// ```
+ #[stable(feature = "str_mut_extras", since = "1.20.0")]
+ #[inline(always)]
+ pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
+ StrExt::as_bytes_mut(self)
+ }
+
+ /// Converts a string slice to a raw pointer.
+ ///
+ /// As string slices are a slice of bytes, the raw pointer points to a
+ /// [`u8`]. This pointer will be pointing to the first byte of the string
+ /// slice.
+ ///
+ /// [`u8`]: primitive.u8.html
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let s = "Hello";
+ /// let ptr = s.as_ptr();
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn as_ptr(&self) -> *const u8 {
+ StrExt::as_ptr(self)
+ }
+
+ /// Returns a subslice of `str`.
+ ///
+ /// This is the non-panicking alternative to indexing the `str`. Returns
+ /// [`None`] whenever equivalent indexing operation would panic.
+ ///
+ /// [`None`]: option/enum.Option.html#variant.None
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = String::from("🗻∈🌏");
+ ///
+ /// assert_eq!(Some("🗻"), v.get(0..4));
+ ///
+ /// // indices not on UTF-8 sequence boundaries
+ /// assert!(v.get(1..).is_none());
+ /// assert!(v.get(..8).is_none());
+ ///
+ /// // out of bounds
+ /// assert!(v.get(..42).is_none());
+ /// ```
+ #[stable(feature = "str_checked_slicing", since = "1.20.0")]
+ #[inline]
+ pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
+ StrExt::get(self, i)
+ }
+
+ /// Returns a mutable subslice of `str`.
+ ///
+ /// This is the non-panicking alternative to indexing the `str`. Returns
+ /// [`None`] whenever equivalent indexing operation would panic.
+ ///
+ /// [`None`]: option/enum.Option.html#variant.None
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = String::from("hello");
+ /// // correct length
+ /// assert!(v.get_mut(0..5).is_some());
+ /// // out of bounds
+ /// assert!(v.get_mut(..42).is_none());
+ /// assert_eq!(Some("he"), v.get_mut(0..2).map(|v| &*v));
+ ///
+ /// assert_eq!("hello", v);
+ /// {
+ /// let s = v.get_mut(0..2);
+ /// let s = s.map(|s| {
+ /// s.make_ascii_uppercase();
+ /// &*s
+ /// });
+ /// assert_eq!(Some("HE"), s);
+ /// }
+ /// assert_eq!("HEllo", v);
+ /// ```
+ #[stable(feature = "str_checked_slicing", since = "1.20.0")]
+ #[inline]
+ pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
+ StrExt::get_mut(self, i)
+ }
+
+ /// Returns a unchecked subslice of `str`.
+ ///
+ /// This is the unchecked alternative to indexing the `str`.
+ ///
+ /// # Safety
+ ///
+ /// Callers of this function are responsible that these preconditions are
+ /// satisfied:
+ ///
+ /// * The starting index must come before the ending index;
+ /// * Indexes must be within bounds of the original slice;
+ /// * Indexes must lie on UTF-8 sequence boundaries.
+ ///
+ /// Failing that, the returned string slice may reference invalid memory or
+ /// violate the invariants communicated by the `str` type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v = "🗻∈🌏";
+ /// unsafe {
+ /// assert_eq!("🗻", v.get_unchecked(0..4));
+ /// assert_eq!("∈", v.get_unchecked(4..7));
+ /// assert_eq!("🌏", v.get_unchecked(7..11));
+ /// }
+ /// ```
+ #[stable(feature = "str_checked_slicing", since = "1.20.0")]
+ #[inline]
+ pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
+ StrExt::get_unchecked(self, i)
+ }
+
+ /// Returns a mutable, unchecked subslice of `str`.
+ ///
+ /// This is the unchecked alternative to indexing the `str`.
+ ///
+ /// # Safety
+ ///
+ /// Callers of this function are responsible that these preconditions are
+ /// satisfied:
+ ///
+ /// * The starting index must come before the ending index;
+ /// * Indexes must be within bounds of the original slice;
+ /// * Indexes must lie on UTF-8 sequence boundaries.
+ ///
+ /// Failing that, the returned string slice may reference invalid memory or
+ /// violate the invariants communicated by the `str` type.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut v = String::from("🗻∈🌏");
+ /// unsafe {
+ /// assert_eq!("🗻", v.get_unchecked_mut(0..4));
+ /// assert_eq!("∈", v.get_unchecked_mut(4..7));
+ /// assert_eq!("🌏", v.get_unchecked_mut(7..11));
+ /// }
+ /// ```
+ #[stable(feature = "str_checked_slicing", since = "1.20.0")]
+ #[inline]
+ pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
+ StrExt::get_unchecked_mut(self, i)
+ }
+
+ /// Creates a string slice from another string slice, bypassing safety
+ /// checks.
+ ///
+ /// This is generally not recommended, use with caution! For a safe
+ /// alternative see [`str`] and [`Index`].
+ ///
+ /// [`str`]: primitive.str.html
+ /// [`Index`]: ops/trait.Index.html
+ ///
+ /// This new slice goes from `begin` to `end`, including `begin` but
+ /// excluding `end`.
+ ///
+ /// To get a mutable string slice instead, see the
+ /// [`slice_mut_unchecked`] method.
+ ///
+ /// [`slice_mut_unchecked`]: #method.slice_mut_unchecked
+ ///
+ /// # Safety
+ ///
+ /// Callers of this function are responsible that three preconditions are
+ /// satisfied:
+ ///
+ /// * `begin` must come before `end`.
+ /// * `begin` and `end` must be byte positions within the string slice.
+ /// * `begin` and `end` must lie on UTF-8 sequence boundaries.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let s = "Löwe 老虎 Léopard";
+ ///
+ /// unsafe {
+ /// assert_eq!("Löwe 老虎 Léopard", s.slice_unchecked(0, 21));
+ /// }
+ ///
+ /// let s = "Hello, world!";
+ ///
+ /// unsafe {
+ /// assert_eq!("world", s.slice_unchecked(7, 12));
+ /// }
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
+ StrExt::slice_unchecked(self, begin, end)
+ }
+
+ /// Creates a string slice from another string slice, bypassing safety
+ /// checks.
+ /// This is generally not recommended, use with caution! For a safe
+ /// alternative see [`str`] and [`IndexMut`].
+ ///
+ /// [`str`]: primitive.str.html
+ /// [`IndexMut`]: ops/trait.IndexMut.html
+ ///
+ /// This new slice goes from `begin` to `end`, including `begin` but
+ /// excluding `end`.
+ ///
+ /// To get an immutable string slice instead, see the
+ /// [`slice_unchecked`] method.
+ ///
+ /// [`slice_unchecked`]: #method.slice_unchecked
+ ///
+ /// # Safety
+ ///
+ /// Callers of this function are responsible that three preconditions are
+ /// satisfied:
+ ///
+ /// * `begin` must come before `end`.
+ /// * `begin` and `end` must be byte positions within the string slice.
+ /// * `begin` and `end` must lie on UTF-8 sequence boundaries.
+ #[stable(feature = "str_slice_mut", since = "1.5.0")]
+ #[inline]
+ pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
+ StrExt::slice_mut_unchecked(self, begin, end)
+ }
+
+ /// Divide one string slice into two at an index.
+ ///
+ /// The argument, `mid`, should be a byte offset from the start of the
+ /// string. It must also be on the boundary of a UTF-8 code point.
+ ///
+ /// The two slices returned go from the start of the string slice to `mid`,
+ /// and from `mid` to the end of the string slice.
+ ///
+ /// To get mutable string slices instead, see the [`split_at_mut`]
+ /// method.
+ ///
+ /// [`split_at_mut`]: #method.split_at_mut
+ ///
+ /// # Panics
+ ///
+ /// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
+ /// beyond the last code point of the string slice.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let s = "Per Martin-Löf";
+ ///
+ /// let (first, last) = s.split_at(3);
+ ///
+ /// assert_eq!("Per", first);
+ /// assert_eq!(" Martin-Löf", last);
+ /// ```
+ #[inline]
+ #[stable(feature = "str_split_at", since = "1.4.0")]
+ pub fn split_at(&self, mid: usize) -> (&str, &str) {
+ StrExt::split_at(self, mid)
+ }
+
+ /// Divide one mutable string slice into two at an index.
+ ///
+ /// The argument, `mid`, should be a byte offset from the start of the
+ /// string. It must also be on the boundary of a UTF-8 code point.
+ ///
+ /// The two slices returned go from the start of the string slice to `mid`,
+ /// and from `mid` to the end of the string slice.
+ ///
+ /// To get immutable string slices instead, see the [`split_at`] method.
+ ///
+ /// [`split_at`]: #method.split_at
+ ///
+ /// # Panics
+ ///
+ /// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
+ /// beyond the last code point of the string slice.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let mut s = "Per Martin-Löf".to_string();
+ /// {
+ /// let (first, last) = s.split_at_mut(3);
+ /// first.make_ascii_uppercase();
+ /// assert_eq!("PER", first);
+ /// assert_eq!(" Martin-Löf", last);
+ /// }
+ /// assert_eq!("PER Martin-Löf", s);
+ /// ```
+ #[inline]
+ #[stable(feature = "str_split_at", since = "1.4.0")]
+ pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
+ StrExt::split_at_mut(self, mid)
+ }
+
+ /// Returns an iterator over the [`char`]s of a string slice.
+ ///
+ /// As a string slice consists of valid UTF-8, we can iterate through a
+ /// string slice by [`char`]. This method returns such an iterator.
+ ///
+ /// It's important to remember that [`char`] represents a Unicode Scalar
+ /// Value, and may not match your idea of what a 'character' is. Iteration
+ /// over grapheme clusters may be what you actually want.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let word = "goodbye";
+ ///
+ /// let count = word.chars().count();
+ /// assert_eq!(7, count);
+ ///
+ /// let mut chars = word.chars();
+ ///
+ /// assert_eq!(Some('g'), chars.next());
+ /// assert_eq!(Some('o'), chars.next());
+ /// assert_eq!(Some('o'), chars.next());
+ /// assert_eq!(Some('d'), chars.next());
+ /// assert_eq!(Some('b'), chars.next());
+ /// assert_eq!(Some('y'), chars.next());
+ /// assert_eq!(Some('e'), chars.next());
+ ///
+ /// assert_eq!(None, chars.next());
+ /// ```
+ ///
+ /// Remember, [`char`]s may not match your human intuition about characters:
+ ///
+ /// ```
+ /// let y = "y̆";
+ ///
+ /// let mut chars = y.chars();
+ ///
+ /// assert_eq!(Some('y'), chars.next()); // not 'y̆'
+ /// assert_eq!(Some('\u{0306}'), chars.next());
+ ///
+ /// assert_eq!(None, chars.next());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn chars(&self) -> Chars {
+ StrExt::chars(self)
+ }
+ /// Returns an iterator over the [`char`]s of a string slice, and their
+ /// positions.
+ ///
+ /// As a string slice consists of valid UTF-8, we can iterate through a
+ /// string slice by [`char`]. This method returns an iterator of both
+ /// these [`char`]s, as well as their byte positions.
+ ///
+ /// The iterator yields tuples. The position is first, the [`char`] is
+ /// second.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let word = "goodbye";
+ ///
+ /// let count = word.char_indices().count();
+ /// assert_eq!(7, count);
+ ///
+ /// let mut char_indices = word.char_indices();
+ ///
+ /// assert_eq!(Some((0, 'g')), char_indices.next());
+ /// assert_eq!(Some((1, 'o')), char_indices.next());
+ /// assert_eq!(Some((2, 'o')), char_indices.next());
+ /// assert_eq!(Some((3, 'd')), char_indices.next());
+ /// assert_eq!(Some((4, 'b')), char_indices.next());
+ /// assert_eq!(Some((5, 'y')), char_indices.next());
+ /// assert_eq!(Some((6, 'e')), char_indices.next());
+ ///
+ /// assert_eq!(None, char_indices.next());
+ /// ```
+ ///
+ /// Remember, [`char`]s may not match your human intuition about characters:
+ ///
+ /// ```
+ /// let yes = "y̆es";
+ ///
+ /// let mut char_indices = yes.char_indices();
+ ///
+ /// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆')
+ /// assert_eq!(Some((1, '\u{0306}')), char_indices.next());
+ ///
+ /// // note the 3 here - the last character took up two bytes
+ /// assert_eq!(Some((3, 'e')), char_indices.next());
+ /// assert_eq!(Some((4, 's')), char_indices.next());
+ ///
+ /// assert_eq!(None, char_indices.next());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn char_indices(&self) -> CharIndices {
+ StrExt::char_indices(self)
+ }
+
+ /// An iterator over the bytes of a string slice.
+ ///
+ /// As a string slice consists of a sequence of bytes, we can iterate
+ /// through a string slice by byte. This method returns such an iterator.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let mut bytes = "bors".bytes();
+ ///
+ /// assert_eq!(Some(b'b'), bytes.next());
+ /// assert_eq!(Some(b'o'), bytes.next());
+ /// assert_eq!(Some(b'r'), bytes.next());
+ /// assert_eq!(Some(b's'), bytes.next());
+ ///
+ /// assert_eq!(None, bytes.next());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn bytes(&self) -> Bytes {
+ StrExt::bytes(self)
+ }
+
+ /// Split a string slice by whitespace.
+ ///
+ /// The iterator returned will return string slices that are sub-slices of
+ /// the original string slice, separated by any amount of whitespace.
+ ///
+ /// 'Whitespace' is defined according to the terms of the Unicode Derived
+ /// Core Property `White_Space`.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let mut iter = "A few words".split_whitespace();
+ ///
+ /// assert_eq!(Some("A"), iter.next());
+ /// assert_eq!(Some("few"), iter.next());
+ /// assert_eq!(Some("words"), iter.next());
+ ///
+ /// assert_eq!(None, iter.next());
+ /// ```
+ ///
+ /// All kinds of whitespace are considered:
+ ///
+ /// ```
+ /// let mut iter = " Mary had\ta\u{2009}little \n\t lamb".split_whitespace();
+ /// assert_eq!(Some("Mary"), iter.next());
+ /// assert_eq!(Some("had"), iter.next());
+ /// assert_eq!(Some("a"), iter.next());
+ /// assert_eq!(Some("little"), iter.next());
+ /// assert_eq!(Some("lamb"), iter.next());
+ ///
+ /// assert_eq!(None, iter.next());
+ /// ```
+ #[stable(feature = "split_whitespace", since = "1.1.0")]
+ #[inline]
+ pub fn split_whitespace(&self) -> SplitWhitespace {
+ StrExt::split_whitespace(self)
+ }
+
+ /// An iterator over the lines of a string, as string slices.
+ ///
+ /// Lines are ended with either a newline (`\n`) or a carriage return with
+ /// a line feed (`\r\n`).
+ ///
+ /// The final line ending is optional.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let text = "foo\r\nbar\n\nbaz\n";
+ /// let mut lines = text.lines();
+ ///
+ /// assert_eq!(Some("foo"), lines.next());
+ /// assert_eq!(Some("bar"), lines.next());
+ /// assert_eq!(Some(""), lines.next());
+ /// assert_eq!(Some("baz"), lines.next());
+ ///
+ /// assert_eq!(None, lines.next());
+ /// ```
+ ///
+ /// The final line ending isn't required:
+ ///
+ /// ```
+ /// let text = "foo\nbar\n\r\nbaz";
+ /// let mut lines = text.lines();
+ ///
+ /// assert_eq!(Some("foo"), lines.next());
+ /// assert_eq!(Some("bar"), lines.next());
+ /// assert_eq!(Some(""), lines.next());
+ /// assert_eq!(Some("baz"), lines.next());
+ ///
+ /// assert_eq!(None, lines.next());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn lines(&self) -> Lines {
+ StrExt::lines(self)
+ }
+
+ /// An iterator over the lines of a string.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_deprecated(since = "1.4.0", reason = "use lines() instead now")]
+ #[inline]
+ #[allow(deprecated)]
+ pub fn lines_any(&self) -> LinesAny {
+ StrExt::lines_any(self)
+ }
+
+ /// Returns an iterator of `u16` over the string encoded as UTF-16.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let text = "Zażółć gęślą jaźń";
+ ///
+ /// let utf8_len = text.len();
+ /// let utf16_len = text.encode_utf16().count();
+ ///
+ /// assert!(utf16_len <= utf8_len);
+ /// ```
+ #[stable(feature = "encode_utf16", since = "1.8.0")]
+ pub fn encode_utf16(&self) -> EncodeUtf16 {
+ EncodeUtf16::new(self)
+ }
+
+ /// Returns `true` if the given pattern matches a sub-slice of
+ /// this string slice.
+ ///
+ /// Returns `false` if it does not.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let bananas = "bananas";
+ ///
+ /// assert!(bananas.contains("nana"));
+ /// assert!(!bananas.contains("apples"));
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+ StrExt::contains(self, pat)
+ }
+
+ /// Returns `true` if the given pattern matches a prefix of this
+ /// string slice.
+ ///
+ /// Returns `false` if it does not.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let bananas = "bananas";
+ ///
+ /// assert!(bananas.starts_with("bana"));
+ /// assert!(!bananas.starts_with("nana"));
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+ StrExt::starts_with(self, pat)
+ }
+
+ /// Returns `true` if the given pattern matches a suffix of this
+ /// string slice.
+ ///
+ /// Returns `false` if it does not.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let bananas = "bananas";
+ ///
+ /// assert!(bananas.ends_with("anas"));
+ /// assert!(!bananas.ends_with("nana"));
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
+ where P::Searcher: ReverseSearcher<'a>
+ {
+ StrExt::ends_with(self, pat)
+ }
+
+ /// Returns the byte index of the first character of this string slice that
+ /// matches the pattern.
+ ///
+ /// Returns [`None`] if the pattern doesn't match.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines if
+ /// a character matches.
+ ///
+ /// [`char`]: primitive.char.html
+ /// [`None`]: option/enum.Option.html#variant.None
+ ///
+ /// # Examples
+ ///
+ /// Simple patterns:
+ ///
+ /// ```
+ /// let s = "Löwe 老虎 Léopard";
+ ///
+ /// assert_eq!(s.find('L'), Some(0));
+ /// assert_eq!(s.find('é'), Some(14));
+ /// assert_eq!(s.find("Léopard"), Some(13));
+ /// ```
+ ///
+ /// More complex patterns using point-free style and closures:
+ ///
+ /// ```
+ /// let s = "Löwe 老虎 Léopard";
+ ///
+ /// assert_eq!(s.find(char::is_whitespace), Some(5));
+ /// assert_eq!(s.find(char::is_lowercase), Some(1));
+ /// assert_eq!(s.find(|c: char| c.is_whitespace() || c.is_lowercase()), Some(1));
+ /// assert_eq!(s.find(|c: char| (c < 'o') && (c > 'a')), Some(4));
+ /// ```
+ ///
+ /// Not finding the pattern:
+ ///
+ /// ```
+ /// let s = "Löwe 老虎 Léopard";
+ /// let x: &[_] = &['1', '2'];
+ ///
+ /// assert_eq!(s.find(x), None);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
+ StrExt::find(self, pat)
+ }
+
+ /// Returns the byte index of the last character of this string slice that
+ /// matches the pattern.
+ ///
+ /// Returns [`None`] if the pattern doesn't match.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines if
+ /// a character matches.
+ ///
+ /// [`char`]: primitive.char.html
+ /// [`None`]: option/enum.Option.html#variant.None
+ ///
+ /// # Examples
+ ///
+ /// Simple patterns:
+ ///
+ /// ```
+ /// let s = "Löwe 老虎 Léopard";
+ ///
+ /// assert_eq!(s.rfind('L'), Some(13));
+ /// assert_eq!(s.rfind('é'), Some(14));
+ /// ```
+ ///
+ /// More complex patterns with closures:
+ ///
+ /// ```
+ /// let s = "Löwe 老虎 Léopard";
+ ///
+ /// assert_eq!(s.rfind(char::is_whitespace), Some(12));
+ /// assert_eq!(s.rfind(char::is_lowercase), Some(20));
+ /// ```
+ ///
+ /// Not finding the pattern:
+ ///
+ /// ```
+ /// let s = "Löwe 老虎 Léopard";
+ /// let x: &[_] = &['1', '2'];
+ ///
+ /// assert_eq!(s.rfind(x), None);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
+ where P::Searcher: ReverseSearcher<'a>
+ {
+ StrExt::rfind(self, pat)
+ }
+
+ /// An iterator over substrings of this string slice, separated by
+ /// characters matched by a pattern.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines the
+ /// split.
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
+ /// allows a reverse search and forward/reverse search yields the same
+ /// elements. This is true for, eg, [`char`] but not for `&str`.
+ ///
+ /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
+ ///
+ /// If the pattern allows a reverse search but its results might differ
+ /// from a forward search, the [`rsplit`] method can be used.
+ ///
+ /// [`char`]: primitive.char.html
+ /// [`rsplit`]: #method.rsplit
+ ///
+ /// # Examples
+ ///
+ /// Simple patterns:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
+ /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
+ ///
+ /// let v: Vec<&str> = "".split('X').collect();
+ /// assert_eq!(v, [""]);
+ ///
+ /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
+ /// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
+ ///
+ /// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
+ /// assert_eq!(v, ["lion", "tiger", "leopard"]);
+ ///
+ /// let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect();
+ /// assert_eq!(v, ["abc", "def", "ghi"]);
+ ///
+ /// let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect();
+ /// assert_eq!(v, ["lion", "tiger", "leopard"]);
+ /// ```
+ ///
+ /// A more complex pattern, using a closure:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect();
+ /// assert_eq!(v, ["abc", "def", "ghi"]);
+ /// ```
+ ///
+ /// If a string contains multiple contiguous separators, you will end up
+ /// with empty strings in the output:
+ ///
+ /// ```
+ /// let x = "||||a||b|c".to_string();
+ /// let d: Vec<_> = x.split('|').collect();
+ ///
+ /// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
+ /// ```
+ ///
+ /// Contiguous separators are separated by the empty string.
+ ///
+ /// ```
+ /// let x = "(///)".to_string();
+ /// let d: Vec<_> = x.split('/').collect();
+ ///
+ /// assert_eq!(d, &["(", "", "", ")"]);
+ /// ```
+ ///
+ /// Separators at the start or end of a string are neighbored
+ /// by empty strings.
+ ///
+ /// ```
+ /// let d: Vec<_> = "010".split("0").collect();
+ /// assert_eq!(d, &["", "1", ""]);
+ /// ```
+ ///
+ /// When the empty string is used as a separator, it separates
+ /// every character in the string, along with the beginning
+ /// and end of the string.
+ ///
+ /// ```
+ /// let f: Vec<_> = "rust".split("").collect();
+ /// assert_eq!(f, &["", "r", "u", "s", "t", ""]);
+ /// ```
+ ///
+ /// Contiguous separators can lead to possibly surprising behavior
+ /// when whitespace is used as the separator. This code is correct:
+ ///
+ /// ```
+ /// let x = " a b c".to_string();
+ /// let d: Vec<_> = x.split(' ').collect();
+ ///
+ /// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
+ /// ```
+ ///
+ /// It does _not_ give you:
+ ///
+ /// ```,ignore
+ /// assert_eq!(d, &["a", "b", "c"]);
+ /// ```
+ ///
+ /// Use [`split_whitespace`] for this behavior.
+ ///
+ /// [`split_whitespace`]: #method.split_whitespace
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
+ StrExt::split(self, pat)
+ }
+
+ /// An iterator over substrings of the given string slice, separated by
+ /// characters matched by a pattern and yielded in reverse order.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines the
+ /// split.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator requires that the pattern supports a reverse
+ /// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
+ /// search yields the same elements.
+ ///
+ /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
+ ///
+ /// For iterating from the front, the [`split`] method can be used.
+ ///
+ /// [`split`]: #method.split
+ ///
+ /// # Examples
+ ///
+ /// Simple patterns:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
+ /// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
+ ///
+ /// let v: Vec<&str> = "".rsplit('X').collect();
+ /// assert_eq!(v, [""]);
+ ///
+ /// let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
+ /// assert_eq!(v, ["leopard", "tiger", "", "lion"]);
+ ///
+ /// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
+ /// assert_eq!(v, ["leopard", "tiger", "lion"]);
+ /// ```
+ ///
+ /// A more complex pattern, using a closure:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect();
+ /// assert_eq!(v, ["ghi", "def", "abc"]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
+ where P::Searcher: ReverseSearcher<'a>
+ {
+ StrExt::rsplit(self, pat)
+ }
+
+ /// An iterator over substrings of the given string slice, separated by
+ /// characters matched by a pattern.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines the
+ /// split.
+ ///
+ /// Equivalent to [`split`], except that the trailing substring
+ /// is skipped if empty.
+ ///
+ /// [`split`]: #method.split
+ ///
+ /// This method can be used for string data that is _terminated_,
+ /// rather than _separated_ by a pattern.
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
+ /// allows a reverse search and forward/reverse search yields the same
+ /// elements. This is true for, eg, [`char`] but not for `&str`.
+ ///
+ /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
+ /// [`char`]: primitive.char.html
+ ///
+ /// If the pattern allows a reverse search but its results might differ
+ /// from a forward search, the [`rsplit_terminator`] method can be used.
+ ///
+ /// [`rsplit_terminator`]: #method.rsplit_terminator
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
+ /// assert_eq!(v, ["A", "B"]);
+ ///
+ /// let v: Vec<&str> = "A..B..".split_terminator(".").collect();
+ /// assert_eq!(v, ["A", "", "B", ""]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
+ StrExt::split_terminator(self, pat)
+ }
+
+ /// An iterator over substrings of `self`, separated by characters
+ /// matched by a pattern and yielded in reverse order.
+ ///
+ /// The pattern can be a simple `&str`, [`char`], or a closure that
+ /// determines the split.
+ /// Additional libraries might provide more complex patterns like
+ /// regular expressions.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// Equivalent to [`split`], except that the trailing substring is
+ /// skipped if empty.
+ ///
+ /// [`split`]: #method.split
+ ///
+ /// This method can be used for string data that is _terminated_,
+ /// rather than _separated_ by a pattern.
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator requires that the pattern supports a
+ /// reverse search, and it will be double ended if a forward/reverse
+ /// search yields the same elements.
+ ///
+ /// For iterating from the front, the [`split_terminator`] method can be
+ /// used.
+ ///
+ /// [`split_terminator`]: #method.split_terminator
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
+ /// assert_eq!(v, ["B", "A"]);
+ ///
+ /// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
+ /// assert_eq!(v, ["", "B", "", "A"]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
+ where P::Searcher: ReverseSearcher<'a>
+ {
+ StrExt::rsplit_terminator(self, pat)
+ }
+
+ /// An iterator over substrings of the given string slice, separated by a
+ /// pattern, restricted to returning at most `n` items.
+ ///
+ /// If `n` substrings are returned, the last substring (the `n`th substring)
+ /// will contain the remainder of the string.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines the
+ /// split.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator will not be double ended, because it is
+ /// not efficient to support.
+ ///
+ /// If the pattern allows a reverse search, the [`rsplitn`] method can be
+ /// used.
+ ///
+ /// [`rsplitn`]: #method.rsplitn
+ ///
+ /// # Examples
+ ///
+ /// Simple patterns:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
+ /// assert_eq!(v, ["Mary", "had", "a little lambda"]);
+ ///
+ /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
+ /// assert_eq!(v, ["lion", "", "tigerXleopard"]);
+ ///
+ /// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
+ /// assert_eq!(v, ["abcXdef"]);
+ ///
+ /// let v: Vec<&str> = "".splitn(1, 'X').collect();
+ /// assert_eq!(v, [""]);
+ /// ```
+ ///
+ /// A more complex pattern, using a closure:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect();
+ /// assert_eq!(v, ["abc", "defXghi"]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
+ StrExt::splitn(self, n, pat)
+ }
+
+ /// An iterator over substrings of this string slice, separated by a
+ /// pattern, starting from the end of the string, restricted to returning
+ /// at most `n` items.
+ ///
+ /// If `n` substrings are returned, the last substring (the `n`th substring)
+ /// will contain the remainder of the string.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that
+ /// determines the split.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator will not be double ended, because it is not
+ /// efficient to support.
+ ///
+ /// For splitting from the front, the [`splitn`] method can be used.
+ ///
+ /// [`splitn`]: #method.splitn
+ ///
+ /// # Examples
+ ///
+ /// Simple patterns:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
+ /// assert_eq!(v, ["lamb", "little", "Mary had a"]);
+ ///
+ /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
+ /// assert_eq!(v, ["leopard", "tiger", "lionX"]);
+ ///
+ /// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
+ /// assert_eq!(v, ["leopard", "lion::tiger"]);
+ /// ```
+ ///
+ /// A more complex pattern, using a closure:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect();
+ /// assert_eq!(v, ["ghi", "abc1def"]);
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
+ pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
+ where P::Searcher: ReverseSearcher<'a>
+ {
+ StrExt::rsplitn(self, n, pat)
+ }
+
+ /// An iterator over the disjoint matches of a pattern within the given string
+ /// slice.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that
+ /// determines if a character matches.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
+ /// allows a reverse search and forward/reverse search yields the same
+ /// elements. This is true for, eg, [`char`] but not for `&str`.
+ ///
+ /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
+ /// [`char`]: primitive.char.html
+ ///
+ /// If the pattern allows a reverse search but its results might differ
+ /// from a forward search, the [`rmatches`] method can be used.
+ ///
+ /// [`rmatches`]: #method.rmatches
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
+ /// assert_eq!(v, ["abc", "abc", "abc"]);
+ ///
+ /// let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect();
+ /// assert_eq!(v, ["1", "2", "3"]);
+ /// ```
+ #[stable(feature = "str_matches", since = "1.2.0")]
+ #[inline]
+ pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
+ StrExt::matches(self, pat)
+ }
+
+ /// An iterator over the disjoint matches of a pattern within this string slice,
+ /// yielded in reverse order.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines if
+ /// a character matches.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator requires that the pattern supports a reverse
+ /// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
+ /// search yields the same elements.
+ ///
+ /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
+ ///
+ /// For iterating from the front, the [`matches`] method can be used.
+ ///
+ /// [`matches`]: #method.matches
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
+ /// assert_eq!(v, ["abc", "abc", "abc"]);
+ ///
+ /// let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect();
+ /// assert_eq!(v, ["3", "2", "1"]);
+ /// ```
+ #[stable(feature = "str_matches", since = "1.2.0")]
+ #[inline]
+ pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
+ where P::Searcher: ReverseSearcher<'a>
+ {
+ StrExt::rmatches(self, pat)
+ }
+
+ /// An iterator over the disjoint matches of a pattern within this string
+ /// slice as well as the index that the match starts at.
+ ///
+ /// For matches of `pat` within `self` that overlap, only the indices
+ /// corresponding to the first match are returned.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines
+ /// if a character matches.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
+ /// allows a reverse search and forward/reverse search yields the same
+ /// elements. This is true for, eg, [`char`] but not for `&str`.
+ ///
+ /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
+ ///
+ /// If the pattern allows a reverse search but its results might differ
+ /// from a forward search, the [`rmatch_indices`] method can be used.
+ ///
+ /// [`rmatch_indices`]: #method.rmatch_indices
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect();
+ /// assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]);
+ ///
+ /// let v: Vec<_> = "1abcabc2".match_indices("abc").collect();
+ /// assert_eq!(v, [(1, "abc"), (4, "abc")]);
+ ///
+ /// let v: Vec<_> = "ababa".match_indices("aba").collect();
+ /// assert_eq!(v, [(0, "aba")]); // only the first `aba`
+ /// ```
+ #[stable(feature = "str_match_indices", since = "1.5.0")]
+ #[inline]
+ pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
+ StrExt::match_indices(self, pat)
+ }
+
+ /// An iterator over the disjoint matches of a pattern within `self`,
+ /// yielded in reverse order along with the index of the match.
+ ///
+ /// For matches of `pat` within `self` that overlap, only the indices
+ /// corresponding to the last match are returned.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines if a
+ /// character matches.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Iterator behavior
+ ///
+ /// The returned iterator requires that the pattern supports a reverse
+ /// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
+ /// search yields the same elements.
+ ///
+ /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
+ ///
+ /// For iterating from the front, the [`match_indices`] method can be used.
+ ///
+ /// [`match_indices`]: #method.match_indices
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
+ /// assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]);
+ ///
+ /// let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect();
+ /// assert_eq!(v, [(4, "abc"), (1, "abc")]);
+ ///
+ /// let v: Vec<_> = "ababa".rmatch_indices("aba").collect();
+ /// assert_eq!(v, [(2, "aba")]); // only the last `aba`
+ /// ```
+ #[stable(feature = "str_match_indices", since = "1.5.0")]
+ #[inline]
+ pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
+ where P::Searcher: ReverseSearcher<'a>
+ {
+ StrExt::rmatch_indices(self, pat)
+ }
+
+ /// Returns a string slice with leading and trailing whitespace removed.
+ ///
+ /// 'Whitespace' is defined according to the terms of the Unicode Derived
+ /// Core Property `White_Space`.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let s = " Hello\tworld\t";
+ ///
+ /// assert_eq!("Hello\tworld", s.trim());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn trim(&self) -> &str {
+ StrExt::trim(self)
+ }
+
+ /// Returns a string slice with leading whitespace removed.
+ ///
+ /// 'Whitespace' is defined according to the terms of the Unicode Derived
+ /// Core Property `White_Space`.
+ ///
+ /// # Text directionality
+ ///
+ /// A string is a sequence of bytes. 'Left' in this context means the first
+ /// position of that byte string; for a language like Arabic or Hebrew
+ /// which are 'right to left' rather than 'left to right', this will be
+ /// the _right_ side, not the left.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let s = " Hello\tworld\t";
+ ///
+ /// assert_eq!("Hello\tworld\t", s.trim_left());
+ /// ```
+ ///
+ /// Directionality:
+ ///
+ /// ```
+ /// let s = " English";
+ /// assert!(Some('E') == s.trim_left().chars().next());
+ ///
+ /// let s = " עברית";
+ /// assert!(Some('ע') == s.trim_left().chars().next());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn trim_left(&self) -> &str {
+ StrExt::trim_left(self)
+ }
+
+ /// Returns a string slice with trailing whitespace removed.
+ ///
+ /// 'Whitespace' is defined according to the terms of the Unicode Derived
+ /// Core Property `White_Space`.
+ ///
+ /// # Text directionality
+ ///
+ /// A string is a sequence of bytes. 'Right' in this context means the last
+ /// position of that byte string; for a language like Arabic or Hebrew
+ /// which are 'right to left' rather than 'left to right', this will be
+ /// the _left_ side, not the right.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let s = " Hello\tworld\t";
+ ///
+ /// assert_eq!(" Hello\tworld", s.trim_right());
+ /// ```
+ ///
+ /// Directionality:
+ ///
+ /// ```
+ /// let s = "English ";
+ /// assert!(Some('h') == s.trim_right().chars().rev().next());
+ ///
+ /// let s = "עברית ";
+ /// assert!(Some('ת') == s.trim_right().chars().rev().next());
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn trim_right(&self) -> &str {
+ StrExt::trim_right(self)
+ }
+
+ /// Returns a string slice with all prefixes and suffixes that match a
+ /// pattern repeatedly removed.
+ ///
+ /// The pattern can be a [`char`] or a closure that determines if a
+ /// character matches.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Examples
+ ///
+ /// Simple patterns:
+ ///
+ /// ```
+ /// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
+ /// assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar");
+ ///
+ /// let x: &[_] = &['1', '2'];
+ /// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
+ /// ```
+ ///
+ /// A more complex pattern, using a closure:
+ ///
+ /// ```
+ /// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+ where P::Searcher: DoubleEndedSearcher<'a>
+ {
+ StrExt::trim_matches(self, pat)
+ }
+
+ /// Returns a string slice with all prefixes that match a pattern
+ /// repeatedly removed.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that determines if
+ /// a character matches.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Text directionality
+ ///
+ /// A string is a sequence of bytes. 'Left' in this context means the first
+ /// position of that byte string; for a language like Arabic or Hebrew
+ /// which are 'right to left' rather than 'left to right', this will be
+ /// the _right_ side, not the left.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
+ /// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
+ ///
+ /// let x: &[_] = &['1', '2'];
+ /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
+ StrExt::trim_left_matches(self, pat)
+ }
+
+ /// Returns a string slice with all suffixes that match a pattern
+ /// repeatedly removed.
+ ///
+ /// The pattern can be a `&str`, [`char`], or a closure that
+ /// determines if a character matches.
+ ///
+ /// [`char`]: primitive.char.html
+ ///
+ /// # Text directionality
+ ///
+ /// A string is a sequence of bytes. 'Right' in this context means the last
+ /// position of that byte string; for a language like Arabic or Hebrew
+ /// which are 'right to left' rather than 'left to right', this will be
+ /// the _left_ side, not the right.
+ ///
+ /// # Examples
+ ///
+ /// Simple patterns:
+ ///
+ /// ```
+ /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
+ /// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
+ ///
+ /// let x: &[_] = &['1', '2'];
+ /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
+ /// ```
+ ///
+ /// A more complex pattern, using a closure:
+ ///
+ /// ```
+ /// assert_eq!("1fooX".trim_right_matches(|c| c == '1' || c == 'X'), "1foo");
+ /// ```
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+ where P::Searcher: ReverseSearcher<'a>
+ {
+ StrExt::trim_right_matches(self, pat)
+ }
+
+ /// Parses this string slice into another type.
+ ///
+ /// Because `parse` is so general, it can cause problems with type
+ /// inference. As such, `parse` is one of the few times you'll see
+ /// the syntax affectionately known as the 'turbofish': `::<>`. This
+ /// helps the inference algorithm understand specifically which type
+ /// you're trying to parse into.
+ ///
+ /// `parse` can parse any type that implements the [`FromStr`] trait.
+ ///
+ /// [`FromStr`]: str/trait.FromStr.html
+ ///
+ /// # Errors
+ ///
+ /// Will return [`Err`] if it's not possible to parse this string slice into
+ /// the desired type.
+ ///
+ /// [`Err`]: str/trait.FromStr.html#associatedtype.Err
+ ///
+ /// # Examples
+ ///
+ /// Basic usage
+ ///
+ /// ```
+ /// let four: u32 = "4".parse().unwrap();
+ ///
+ /// assert_eq!(4, four);
+ /// ```
+ ///
+ /// Using the 'turbofish' instead of annotating `four`:
+ ///
+ /// ```
+ /// let four = "4".parse::<u32>();
+ ///
+ /// assert_eq!(Ok(4), four);
+ /// ```
+ ///
+ /// Failing to parse:
+ ///
+ /// ```
+ /// let nope = "j".parse::<u32>();
+ ///
+ /// assert!(nope.is_err());
+ /// ```
+ #[inline]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
+ StrExt::parse(self)
+ }
+
+ /// Checks if all characters in this string are within the ASCII range.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let ascii = "hello!\n";
+ /// let non_ascii = "Grüße, Jürgen ❤";
+ ///
+ /// assert!(ascii.is_ascii());
+ /// assert!(!non_ascii.is_ascii());
+ /// ```
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn is_ascii(&self) -> bool {
+ // We can treat each byte as character here: all multibyte characters
+ // start with a byte that is not in the ascii range, so we will stop
+ // there already.
+ self.bytes().all(|b| b.is_ascii())
+ }
+
+ /// Checks that two strings are an ASCII case-insensitive match.
+ ///
+ /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
+ /// but without allocating and copying temporaries.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert!("Ferris".eq_ignore_ascii_case("FERRIS"));
+ /// assert!("Ferrös".eq_ignore_ascii_case("FERRöS"));
+ /// assert!(!"Ferrös".eq_ignore_ascii_case("FERRÖS"));
+ /// ```
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ #[inline]
+ pub fn eq_ignore_ascii_case(&self, other: &str) -> bool {
+ self.as_bytes().eq_ignore_ascii_case(other.as_bytes())
+ }
+
+ /// Converts this string to its ASCII upper case equivalent in-place.
+ ///
+ /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
+ /// but non-ASCII letters are unchanged.
+ ///
+ /// To return a new uppercased value without modifying the existing one, use
+ /// [`to_ascii_uppercase`].
+ ///
+ /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ pub fn make_ascii_uppercase(&mut self) {
+ let me = unsafe { self.as_bytes_mut() };
+ me.make_ascii_uppercase()
+ }
+
+ /// Converts this string to its ASCII lower case equivalent in-place.
+ ///
+ /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
+ /// but non-ASCII letters are unchanged.
+ ///
+ /// To return a new lowercased value without modifying the existing one, use
+ /// [`to_ascii_lowercase`].
+ ///
+ /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
+ #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+ pub fn make_ascii_lowercase(&mut self) {
+ let me = unsafe { self.as_bytes_mut() };
+ me.make_ascii_lowercase()
+ }
+}}
+
+#[lang = "str"]
+#[cfg(not(test))]
+#[cfg(not(stage0))]
+impl str {
+ str_core_methods!();
+}
+
+
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<[u8]> for str {
#[inline]
@@ -2660,3 +4327,72 @@ impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
#[stable(feature = "fused", since = "1.26.0")]
impl<'a> FusedIterator for SplitWhitespace<'a> {}
+
+/// An iterator of [`u16`] over the string encoded as UTF-16.
+///
+/// [`u16`]: ../../std/primitive.u16.html
+///
+/// This struct is created by the [`encode_utf16`] method on [`str`].
+/// See its documentation for more.
+///
+/// [`encode_utf16`]: ../../std/primitive.str.html#method.encode_utf16
+/// [`str`]: ../../std/primitive.str.html
+#[derive(Clone)]
+#[stable(feature = "encode_utf16", since = "1.8.0")]
+pub struct EncodeUtf16<'a> {
+ chars: Chars<'a>,
+ extra: u16,
+}
+
+// FIXME: remove (inline) this method
+// when updating to a bootstrap compiler that has the new lang items.
+// For grepping purpose: #[cfg(stage0)]
+impl<'a> EncodeUtf16<'a> {
+ #[unstable(feature = "core_str_ext", issue = "32110")]
+ #[doc(hidden)]
+ pub fn new(s: &'a str) -> Self {
+ EncodeUtf16 { chars: s.chars(), extra: 0 }
+ }
+}
+
+#[stable(feature = "collection_debug", since = "1.17.0")]
+impl<'a> fmt::Debug for EncodeUtf16<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.pad("EncodeUtf16 { .. }")
+ }
+}
+
+#[stable(feature = "encode_utf16", since = "1.8.0")]
+impl<'a> Iterator for EncodeUtf16<'a> {
+ type Item = u16;
+
+ #[inline]
+ fn next(&mut self) -> Option<u16> {
+ if self.extra != 0 {
+ let tmp = self.extra;
+ self.extra = 0;
+ return Some(tmp);
+ }
+
+ let mut buf = [0; 2];
+ self.chars.next().map(|ch| {
+ let n = ch.encode_utf16(&mut buf).len();
+ if n == 2 {
+ self.extra = buf[1];
+ }
+ buf[0]
+ })
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let (low, high) = self.chars.size_hint();
+ // every char gets either one u16 or two u16,
+ // so this iterator is between 1 or 2 times as
+ // long as the underlying iterator.
+ (low, high.and_then(|n| n.checked_mul(2)))
+ }
+}
+
+#[stable(feature = "fused", since = "1.26.0")]
+impl<'a> FusedIterator for EncodeUtf16<'a> {}
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 3b080689cb3..7d3852d2f2a 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -17,6 +17,7 @@
#![feature(decode_utf8)]
#![feature(exact_size_is_empty)]
#![feature(fixed_size_array)]
+#![feature(float_internals)]
#![feature(flt2dec)]
#![feature(fmt_internals)]
#![feature(hashmap_internals)]
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 3b37031cf46..c7412dbeeb3 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -214,6 +214,9 @@ language_item_table! {
StrImplItem, "str", str_impl;
SliceImplItem, "slice", slice_impl;
SliceU8ImplItem, "slice_u8", slice_u8_impl;
+ StrAllocImplItem, "str_alloc", str_alloc_impl;
+ SliceAllocImplItem, "slice_alloc", slice_alloc_impl;
+ SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl;
ConstPtrImplItem, "const_ptr", const_ptr_impl;
MutPtrImplItem, "mut_ptr", mut_ptr_impl;
I8ImplItem, "i8", i8_impl;
@@ -230,6 +233,8 @@ language_item_table! {
UsizeImplItem, "usize", usize_impl;
F32ImplItem, "f32", f32_impl;
F64ImplItem, "f64", f64_impl;
+ F32RuntimeImplItem, "f32_runtime", f32_runtime_impl;
+ F64RuntimeImplItem, "f64_runtime", f64_runtime_impl;
SizedTraitLangItem, "sized", sized_trait;
UnsizeTraitLangItem, "unsize", unsize_trait;
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index de570956622..073f36b9f3c 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -471,6 +471,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
ty::TyStr => {
let lang_def_id = lang_items.str_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
+
+ let lang_def_id = lang_items.str_alloc_impl();
+ self.assemble_inherent_impl_for_primitive(lang_def_id);
}
ty::TySlice(_) => {
let lang_def_id = lang_items.slice_impl();
@@ -478,6 +481,12 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
let lang_def_id = lang_items.slice_u8_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
+
+ let lang_def_id = lang_items.slice_alloc_impl();
+ self.assemble_inherent_impl_for_primitive(lang_def_id);
+
+ let lang_def_id = lang_items.slice_u8_alloc_impl();
+ self.assemble_inherent_impl_for_primitive(lang_def_id);
}
ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
let lang_def_id = lang_items.const_ptr_impl();
@@ -538,10 +547,16 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
ty::TyFloat(ast::FloatTy::F32) => {
let lang_def_id = lang_items.f32_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
+
+ let lang_def_id = lang_items.f32_runtime_impl();
+ self.assemble_inherent_impl_for_primitive(lang_def_id);
}
ty::TyFloat(ast::FloatTy::F64) => {
let lang_def_id = lang_items.f64_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
+
+ let lang_def_id = lang_items.f64_runtime_impl();
+ self.assemble_inherent_impl_for_primitive(lang_def_id);
}
_ => {}
}
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index d43ab0d3713..532f1da4f30 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -114,6 +114,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyChar => {
self.check_primitive_impl(def_id,
lang_items.char_impl(),
+ None,
"char",
"char",
item.span);
@@ -121,6 +122,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyStr => {
self.check_primitive_impl(def_id,
lang_items.str_impl(),
+ lang_items.str_alloc_impl(),
"str",
"str",
item.span);
@@ -128,6 +130,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TySlice(slice_item) if slice_item == self.tcx.types.u8 => {
self.check_primitive_impl(def_id,
lang_items.slice_u8_impl(),
+ lang_items.slice_u8_alloc_impl(),
"slice_u8",
"[u8]",
item.span);
@@ -135,6 +138,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TySlice(_) => {
self.check_primitive_impl(def_id,
lang_items.slice_impl(),
+ lang_items.slice_alloc_impl(),
"slice",
"[T]",
item.span);
@@ -142,6 +146,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
self.check_primitive_impl(def_id,
lang_items.const_ptr_impl(),
+ None,
"const_ptr",
"*const T",
item.span);
@@ -149,6 +154,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
self.check_primitive_impl(def_id,
lang_items.mut_ptr_impl(),
+ None,
"mut_ptr",
"*mut T",
item.span);
@@ -156,6 +162,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I8) => {
self.check_primitive_impl(def_id,
lang_items.i8_impl(),
+ None,
"i8",
"i8",
item.span);
@@ -163,6 +170,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I16) => {
self.check_primitive_impl(def_id,
lang_items.i16_impl(),
+ None,
"i16",
"i16",
item.span);
@@ -170,6 +178,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I32) => {
self.check_primitive_impl(def_id,
lang_items.i32_impl(),
+ None,
"i32",
"i32",
item.span);
@@ -177,6 +186,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I64) => {
self.check_primitive_impl(def_id,
lang_items.i64_impl(),
+ None,
"i64",
"i64",
item.span);
@@ -184,6 +194,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I128) => {
self.check_primitive_impl(def_id,
lang_items.i128_impl(),
+ None,
"i128",
"i128",
item.span);
@@ -191,6 +202,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::Isize) => {
self.check_primitive_impl(def_id,
lang_items.isize_impl(),
+ None,
"isize",
"isize",
item.span);
@@ -198,6 +210,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U8) => {
self.check_primitive_impl(def_id,
lang_items.u8_impl(),
+ None,
"u8",
"u8",
item.span);
@@ -205,6 +218,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U16) => {
self.check_primitive_impl(def_id,
lang_items.u16_impl(),
+ None,
"u16",
"u16",
item.span);
@@ -212,6 +226,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U32) => {
self.check_primitive_impl(def_id,
lang_items.u32_impl(),
+ None,
"u32",
"u32",
item.span);
@@ -219,6 +234,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U64) => {
self.check_primitive_impl(def_id,
lang_items.u64_impl(),
+ None,
"u64",
"u64",
item.span);
@@ -226,6 +242,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U128) => {
self.check_primitive_impl(def_id,
lang_items.u128_impl(),
+ None,
"u128",
"u128",
item.span);
@@ -233,6 +250,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::Usize) => {
self.check_primitive_impl(def_id,
lang_items.usize_impl(),
+ None,
"usize",
"usize",
item.span);
@@ -240,6 +258,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyFloat(ast::FloatTy::F32) => {
self.check_primitive_impl(def_id,
lang_items.f32_impl(),
+ lang_items.f32_runtime_impl(),
"f32",
"f32",
item.span);
@@ -247,6 +266,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyFloat(ast::FloatTy::F64) => {
self.check_primitive_impl(def_id,
lang_items.f64_impl(),
+ lang_items.f64_runtime_impl(),
"f64",
"f64",
item.span);
@@ -305,11 +325,15 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> {
fn check_primitive_impl(&self,
impl_def_id: DefId,
lang_def_id: Option<DefId>,
+ lang_def_id2: Option<DefId>,
lang: &str,
ty: &str,
span: Span) {
- match lang_def_id {
- Some(lang_def_id) if lang_def_id == impl_def_id => {
+ match (lang_def_id, lang_def_id2) {
+ (Some(lang_def_id), _) if lang_def_id == impl_def_id => {
+ // OK
+ }
+ (_, Some(lang_def_id)) if lang_def_id == impl_def_id => {
// OK
}
_ => {
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index ae3b2b22ea1..e3f7ff5cb3f 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -4526,23 +4526,23 @@ but the type of the numeric value or binding could not be identified.
The error happens on numeric literals:
```compile_fail,E0689
-2.0.powi(2);
+2.0.recip();
```
and on numeric bindings without an identified concrete type:
```compile_fail,E0689
let x = 2.0;
-x.powi(2); // same error as above
+x.recip(); // same error as above
```
Because of this, you must give the numeric literal or binding a type:
```
-let _ = 2.0_f32.powi(2);
+let _ = 2.0_f32.recip();
let x: f32 = 2.0;
-let _ = x.powi(2);
-let _ = (2.0 as f32).powi(2);
+let _ = x.recip();
+let _ = (2.0 as f32).recip();
```
"##,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 32f23e923d9..23e0c2625ee 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -286,10 +286,15 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean:
lang_items.u128_impl(),
lang_items.f32_impl(),
lang_items.f64_impl(),
+ lang_items.f32_runtime_impl(),
+ lang_items.f64_runtime_impl(),
lang_items.char_impl(),
lang_items.str_impl(),
lang_items.slice_impl(),
lang_items.slice_u8_impl(),
+ lang_items.str_alloc_impl(),
+ lang_items.slice_alloc_impl(),
+ lang_items.slice_u8_alloc_impl(),
lang_items.const_ptr_impl(),
lang_items.mut_ptr_impl(),
];
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index ca39089a958..26644c76957 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -19,10 +19,12 @@
#![allow(missing_docs)]
#[cfg(not(test))]
-use core::num;
+#[cfg(stage0)]
+use core::num::Float;
#[cfg(not(test))]
use intrinsics;
#[cfg(not(test))]
+#[cfg(stage0)]
use num::FpCategory;
#[cfg(not(test))]
use sys::cmath;
@@ -39,106 +41,11 @@ pub use core::f32::{MIN, MIN_POSITIVE, MAX};
pub use core::f32::consts;
#[cfg(not(test))]
-#[lang = "f32"]
+#[cfg_attr(stage0, lang = "f32")]
+#[cfg_attr(not(stage0), lang = "f32_runtime")]
impl f32 {
- /// Returns `true` if this value is `NaN` and false otherwise.
- ///
- /// ```
- /// use std::f32;
- ///
- /// let nan = f32::NAN;
- /// let f = 7.0_f32;
- ///
- /// assert!(nan.is_nan());
- /// assert!(!f.is_nan());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_nan(self) -> bool { num::Float::is_nan(self) }
-
- /// Returns `true` if this value is positive infinity or negative infinity and
- /// false otherwise.
- ///
- /// ```
- /// use std::f32;
- ///
- /// let f = 7.0f32;
- /// let inf = f32::INFINITY;
- /// let neg_inf = f32::NEG_INFINITY;
- /// let nan = f32::NAN;
- ///
- /// assert!(!f.is_infinite());
- /// assert!(!nan.is_infinite());
- ///
- /// assert!(inf.is_infinite());
- /// assert!(neg_inf.is_infinite());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
-
- /// Returns `true` if this number is neither infinite nor `NaN`.
- ///
- /// ```
- /// use std::f32;
- ///
- /// let f = 7.0f32;
- /// let inf = f32::INFINITY;
- /// let neg_inf = f32::NEG_INFINITY;
- /// let nan = f32::NAN;
- ///
- /// assert!(f.is_finite());
- ///
- /// assert!(!nan.is_finite());
- /// assert!(!inf.is_finite());
- /// assert!(!neg_inf.is_finite());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
-
- /// Returns `true` if the number is neither zero, infinite,
- /// [subnormal][subnormal], or `NaN`.
- ///
- /// ```
- /// use std::f32;
- ///
- /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
- /// let max = f32::MAX;
- /// let lower_than_min = 1.0e-40_f32;
- /// let zero = 0.0_f32;
- ///
- /// assert!(min.is_normal());
- /// assert!(max.is_normal());
- ///
- /// assert!(!zero.is_normal());
- /// assert!(!f32::NAN.is_normal());
- /// assert!(!f32::INFINITY.is_normal());
- /// // Values between `0` and `min` are Subnormal.
- /// assert!(!lower_than_min.is_normal());
- /// ```
- /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
-
- /// Returns the floating point category of the number. If only one property
- /// is going to be tested, it is generally faster to use the specific
- /// predicate instead.
- ///
- /// ```
- /// use std::num::FpCategory;
- /// use std::f32;
- ///
- /// let num = 12.4_f32;
- /// let inf = f32::INFINITY;
- ///
- /// assert_eq!(num.classify(), FpCategory::Normal);
- /// assert_eq!(inf.classify(), FpCategory::Infinite);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn classify(self) -> FpCategory { num::Float::classify(self) }
+ #[cfg(stage0)]
+ f32_core_methods!();
/// Returns the largest integer less than or equal to a number.
///
@@ -257,7 +164,9 @@ impl f32 {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn abs(self) -> f32 { num::Float::abs(self) }
+ pub fn abs(self) -> f32 {
+ unsafe { intrinsics::fabsf32(self) }
+ }
/// Returns a number that represents the sign of `self`.
///
@@ -277,35 +186,13 @@ impl f32 {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn signum(self) -> f32 { num::Float::signum(self) }
-
- /// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
- /// positive sign bit and positive infinity.
- ///
- /// ```
- /// let f = 7.0_f32;
- /// let g = -7.0_f32;
- ///
- /// assert!(f.is_sign_positive());
- /// assert!(!g.is_sign_positive());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_sign_positive(self) -> bool { num::Float::is_sign_positive(self) }
-
- /// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
- /// negative sign bit and negative infinity.
- ///
- /// ```
- /// let f = 7.0f32;
- /// let g = -7.0f32;
- ///
- /// assert!(!f.is_sign_negative());
- /// assert!(g.is_sign_negative());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_sign_negative(self) -> bool { num::Float::is_sign_negative(self) }
+ pub fn signum(self) -> f32 {
+ if self.is_nan() {
+ NAN
+ } else {
+ unsafe { intrinsics::copysignf32(1.0, self) }
+ }
+ }
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
/// error. This produces a more accurate result with better performance than
@@ -380,20 +267,6 @@ impl f32 {
}
- /// Takes the reciprocal (inverse) of a number, `1/x`.
- ///
- /// ```
- /// use std::f32;
- ///
- /// let x = 2.0_f32;
- /// let abs_difference = (x.recip() - (1.0/x)).abs();
- ///
- /// assert!(abs_difference <= f32::EPSILON);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn recip(self) -> f32 { num::Float::recip(self) }
-
/// Raises a number to an integer power.
///
/// Using this function is generally faster than using `powf`
@@ -408,7 +281,9 @@ impl f32 {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn powi(self, n: i32) -> f32 { num::Float::powi(self, n) }
+ pub fn powi(self, n: i32) -> f32 {
+ unsafe { intrinsics::powif32(self, n) }
+ }
/// Raises a number to a floating point power.
///
@@ -584,68 +459,6 @@ impl f32 {
return unsafe { intrinsics::log10f32(self) };
}
- /// Converts radians to degrees.
- ///
- /// ```
- /// use std::f32::{self, consts};
- ///
- /// let angle = consts::PI;
- ///
- /// let abs_difference = (angle.to_degrees() - 180.0).abs();
- ///
- /// assert!(abs_difference <= f32::EPSILON);
- /// ```
- #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
- #[inline]
- pub fn to_degrees(self) -> f32 { num::Float::to_degrees(self) }
-
- /// Converts degrees to radians.
- ///
- /// ```
- /// use std::f32::{self, consts};
- ///
- /// let angle = 180.0f32;
- ///
- /// let abs_difference = (angle.to_radians() - consts::PI).abs();
- ///
- /// assert!(abs_difference <= f32::EPSILON);
- /// ```
- #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")]
- #[inline]
- pub fn to_radians(self) -> f32 { num::Float::to_radians(self) }
-
- /// Returns the maximum of the two numbers.
- ///
- /// ```
- /// let x = 1.0f32;
- /// let y = 2.0f32;
- ///
- /// assert_eq!(x.max(y), y);
- /// ```
- ///
- /// If one of the arguments is NaN, then the other argument is returned.
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn max(self, other: f32) -> f32 {
- num::Float::max(self, other)
- }
-
- /// Returns the minimum of the two numbers.
- ///
- /// ```
- /// let x = 1.0f32;
- /// let y = 2.0f32;
- ///
- /// assert_eq!(x.min(y), x);
- /// ```
- ///
- /// If one of the arguments is NaN, then the other argument is returned.
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn min(self, other: f32) -> f32 {
- num::Float::min(self, other)
- }
-
/// The positive difference of two numbers.
///
/// * If `self <= other`: `0:0`
@@ -1046,73 +859,6 @@ impl f32 {
pub fn atanh(self) -> f32 {
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
}
-
- /// Raw transmutation to `u32`.
- ///
- /// This is currently identical to `transmute::<f32, u32>(self)` on all platforms.
- ///
- /// See `from_bits` for some discussion of the portability of this operation
- /// (there are almost no issues).
- ///
- /// Note that this function is distinct from `as` casting, which attempts to
- /// preserve the *numeric* value, and not the bitwise value.
- ///
- /// # Examples
- ///
- /// ```
- /// assert_ne!((1f32).to_bits(), 1f32 as u32); // to_bits() is not casting!
- /// assert_eq!((12.5f32).to_bits(), 0x41480000);
- ///
- /// ```
- #[stable(feature = "float_bits_conv", since = "1.20.0")]
- #[inline]
- pub fn to_bits(self) -> u32 {
- num::Float::to_bits(self)
- }
-
- /// Raw transmutation from `u32`.
- ///
- /// This is currently identical to `transmute::<u32, f32>(v)` on all platforms.
- /// It turns out this is incredibly portable, for two reasons:
- ///
- /// * Floats and Ints have the same endianness on all supported platforms.
- /// * IEEE-754 very precisely specifies the bit layout of floats.
- ///
- /// However there is one caveat: prior to the 2008 version of IEEE-754, how
- /// to interpret the NaN signaling bit wasn't actually specified. Most platforms
- /// (notably x86 and ARM) picked the interpretation that was ultimately
- /// standardized in 2008, but some didn't (notably MIPS). As a result, all
- /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
- ///
- /// Rather than trying to preserve signaling-ness cross-platform, this
- /// implementation favours preserving the exact bits. This means that
- /// any payloads encoded in NaNs will be preserved even if the result of
- /// this method is sent over the network from an x86 machine to a MIPS one.
- ///
- /// If the results of this method are only manipulated by the same
- /// architecture that produced them, then there is no portability concern.
- ///
- /// If the input isn't NaN, then there is no portability concern.
- ///
- /// If you don't care about signalingness (very likely), then there is no
- /// portability concern.
- ///
- /// Note that this function is distinct from `as` casting, which attempts to
- /// preserve the *numeric* value, and not the bitwise value.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::f32;
- /// let v = f32::from_bits(0x41480000);
- /// let difference = (v - 12.5).abs();
- /// assert!(difference <= 1e-5);
- /// ```
- #[stable(feature = "float_bits_conv", since = "1.20.0")]
- #[inline]
- pub fn from_bits(v: u32) -> Self {
- num::Float::from_bits(v)
- }
}
#[cfg(test)]
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index a9585670ad0..a7e63f59b1c 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -19,10 +19,12 @@
#![allow(missing_docs)]
#[cfg(not(test))]
-use core::num;
+#[cfg(stage0)]
+use core::num::Float;
#[cfg(not(test))]
use intrinsics;
#[cfg(not(test))]
+#[cfg(stage0)]
use num::FpCategory;
#[cfg(not(test))]
use sys::cmath;
@@ -39,106 +41,11 @@ pub use core::f64::{MIN, MIN_POSITIVE, MAX};
pub use core::f64::consts;
#[cfg(not(test))]
-#[lang = "f64"]
+#[cfg_attr(stage0, lang = "f64")]
+#[cfg_attr(not(stage0), lang = "f64_runtime")]
impl f64 {
- /// Returns `true` if this value is `NaN` and false otherwise.
- ///
- /// ```
- /// use std::f64;
- ///
- /// let nan = f64::NAN;
- /// let f = 7.0_f64;
- ///
- /// assert!(nan.is_nan());
- /// assert!(!f.is_nan());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_nan(self) -> bool { num::Float::is_nan(self) }
-
- /// Returns `true` if this value is positive infinity or negative infinity and
- /// false otherwise.
- ///
- /// ```
- /// use std::f64;
- ///
- /// let f = 7.0f64;
- /// let inf = f64::INFINITY;
- /// let neg_inf = f64::NEG_INFINITY;
- /// let nan = f64::NAN;
- ///
- /// assert!(!f.is_infinite());
- /// assert!(!nan.is_infinite());
- ///
- /// assert!(inf.is_infinite());
- /// assert!(neg_inf.is_infinite());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
-
- /// Returns `true` if this number is neither infinite nor `NaN`.
- ///
- /// ```
- /// use std::f64;
- ///
- /// let f = 7.0f64;
- /// let inf: f64 = f64::INFINITY;
- /// let neg_inf: f64 = f64::NEG_INFINITY;
- /// let nan: f64 = f64::NAN;
- ///
- /// assert!(f.is_finite());
- ///
- /// assert!(!nan.is_finite());
- /// assert!(!inf.is_finite());
- /// assert!(!neg_inf.is_finite());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
-
- /// Returns `true` if the number is neither zero, infinite,
- /// [subnormal][subnormal], or `NaN`.
- ///
- /// ```
- /// use std::f64;
- ///
- /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308f64
- /// let max = f64::MAX;
- /// let lower_than_min = 1.0e-308_f64;
- /// let zero = 0.0f64;
- ///
- /// assert!(min.is_normal());
- /// assert!(max.is_normal());
- ///
- /// assert!(!zero.is_normal());
- /// assert!(!f64::NAN.is_normal());
- /// assert!(!f64::INFINITY.is_normal());
- /// // Values between `0` and `min` are Subnormal.
- /// assert!(!lower_than_min.is_normal());
- /// ```
- /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
-
- /// Returns the floating point category of the number. If only one property
- /// is going to be tested, it is generally faster to use the specific
- /// predicate instead.
- ///
- /// ```
- /// use std::num::FpCategory;
- /// use std::f64;
- ///
- /// let num = 12.4_f64;
- /// let inf = f64::INFINITY;
- ///
- /// assert_eq!(num.classify(), FpCategory::Normal);
- /// assert_eq!(inf.classify(), FpCategory::Infinite);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn classify(self) -> FpCategory { num::Float::classify(self) }
+ #[cfg(stage0)]
+ f64_core_methods!();
/// Returns the largest integer less than or equal to a number.
///
@@ -235,7 +142,9 @@ impl f64 {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn abs(self) -> f64 { num::Float::abs(self) }
+ pub fn abs(self) -> f64 {
+ unsafe { intrinsics::fabsf64(self) }
+ }
/// Returns a number that represents the sign of `self`.
///
@@ -255,45 +164,13 @@ impl f64 {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn signum(self) -> f64 { num::Float::signum(self) }
-
- /// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with
- /// positive sign bit and positive infinity.
- ///
- /// ```
- /// let f = 7.0_f64;
- /// let g = -7.0_f64;
- ///
- /// assert!(f.is_sign_positive());
- /// assert!(!g.is_sign_positive());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_sign_positive(self) -> bool { num::Float::is_sign_positive(self) }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_positive")]
- #[inline]
- pub fn is_positive(self) -> bool { num::Float::is_sign_positive(self) }
-
- /// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with
- /// negative sign bit and negative infinity.
- ///
- /// ```
- /// let f = 7.0_f64;
- /// let g = -7.0_f64;
- ///
- /// assert!(!f.is_sign_negative());
- /// assert!(g.is_sign_negative());
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn is_sign_negative(self) -> bool { num::Float::is_sign_negative(self) }
-
- #[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_deprecated(since = "1.0.0", reason = "renamed to is_sign_negative")]
- #[inline]
- pub fn is_negative(self) -> bool { num::Float::is_sign_negative(self) }
+ pub fn signum(self) -> f64 {
+ if self.is_nan() {
+ NAN
+ } else {
+ unsafe { intrinsics::copysignf64(1.0, self) }
+ }
+ }
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
/// error. This produces a more accurate result with better performance than
@@ -365,18 +242,6 @@ impl f64 {
}
}
- /// Takes the reciprocal (inverse) of a number, `1/x`.
- ///
- /// ```
- /// let x = 2.0_f64;
- /// let abs_difference = (x.recip() - (1.0/x)).abs();
- ///
- /// assert!(abs_difference < 1e-10);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn recip(self) -> f64 { num::Float::recip(self) }
-
/// Raises a number to an integer power.
///
/// Using this function is generally faster than using `powf`
@@ -389,7 +254,9 @@ impl f64 {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- pub fn powi(self, n: i32) -> f64 { num::Float::powi(self, n) }
+ pub fn powi(self, n: i32) -> f64 {
+ unsafe { intrinsics::powif64(self, n) }
+ }
/// Raises a number to a floating point power.
///
@@ -535,68 +402,6 @@ impl f64 {
self.log_wrapper(|n| { unsafe { intrinsics::log10f64(n) } })
}
- /// Converts radians to degrees.
- ///
- /// ```
- /// use std::f64::consts;
- ///
- /// let angle = consts::PI;
- ///
- /// let abs_difference = (angle.to_degrees() - 180.0).abs();
- ///
- /// assert!(abs_difference < 1e-10);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn to_degrees(self) -> f64 { num::Float::to_degrees(self) }
-
- /// Converts degrees to radians.
- ///
- /// ```
- /// use std::f64::consts;
- ///
- /// let angle = 180.0_f64;
- ///
- /// let abs_difference = (angle.to_radians() - consts::PI).abs();
- ///
- /// assert!(abs_difference < 1e-10);
- /// ```
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn to_radians(self) -> f64 { num::Float::to_radians(self) }
-
- /// Returns the maximum of the two numbers.
- ///
- /// ```
- /// let x = 1.0_f64;
- /// let y = 2.0_f64;
- ///
- /// assert_eq!(x.max(y), y);
- /// ```
- ///
- /// If one of the arguments is NaN, then the other argument is returned.
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn max(self, other: f64) -> f64 {
- num::Float::max(self, other)
- }
-
- /// Returns the minimum of the two numbers.
- ///
- /// ```
- /// let x = 1.0_f64;
- /// let y = 2.0_f64;
- ///
- /// assert_eq!(x.min(y), x);
- /// ```
- ///
- /// If one of the arguments is NaN, then the other argument is returned.
- #[stable(feature = "rust1", since = "1.0.0")]
- #[inline]
- pub fn min(self, other: f64) -> f64 {
- num::Float::min(self, other)
- }
-
/// The positive difference of two numbers.
///
/// * If `self <= other`: `0:0`
@@ -1000,73 +805,6 @@ impl f64 {
}
}
}
-
- /// Raw transmutation to `u64`.
- ///
- /// This is currently identical to `transmute::<f64, u64>(self)` on all platforms.
- ///
- /// See `from_bits` for some discussion of the portability of this operation
- /// (there are almost no issues).
- ///
- /// Note that this function is distinct from `as` casting, which attempts to
- /// preserve the *numeric* value, and not the bitwise value.
- ///
- /// # Examples
- ///
- /// ```
- /// assert!((1f64).to_bits() != 1f64 as u64); // to_bits() is not casting!
- /// assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
- ///
- /// ```
- #[stable(feature = "float_bits_conv", since = "1.20.0")]
- #[inline]
- pub fn to_bits(self) -> u64 {
- num::Float::to_bits(self)
- }
-
- /// Raw transmutation from `u64`.
- ///
- /// This is currently identical to `transmute::<u64, f64>(v)` on all platforms.
- /// It turns out this is incredibly portable, for two reasons:
- ///
- /// * Floats and Ints have the same endianness on all supported platforms.
- /// * IEEE-754 very precisely specifies the bit layout of floats.
- ///
- /// However there is one caveat: prior to the 2008 version of IEEE-754, how
- /// to interpret the NaN signaling bit wasn't actually specified. Most platforms
- /// (notably x86 and ARM) picked the interpretation that was ultimately
- /// standardized in 2008, but some didn't (notably MIPS). As a result, all
- /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa.
- ///
- /// Rather than trying to preserve signaling-ness cross-platform, this
- /// implementation favours preserving the exact bits. This means that
- /// any payloads encoded in NaNs will be preserved even if the result of
- /// this method is sent over the network from an x86 machine to a MIPS one.
- ///
- /// If the results of this method are only manipulated by the same
- /// architecture that produced them, then there is no portability concern.
- ///
- /// If the input isn't NaN, then there is no portability concern.
- ///
- /// If you don't care about signalingness (very likely), then there is no
- /// portability concern.
- ///
- /// Note that this function is distinct from `as` casting, which attempts to
- /// preserve the *numeric* value, and not the bitwise value.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::f64;
- /// let v = f64::from_bits(0x4029000000000000);
- /// let difference = (v - 12.5).abs();
- /// assert!(difference <= 1e-5);
- /// ```
- #[stable(feature = "float_bits_conv", since = "1.20.0")]
- #[inline]
- pub fn from_bits(v: u64) -> Self {
- num::Float::from_bits(v)
- }
}
#[cfg(test)]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index e53e009678c..2c8203a3dc4 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -252,7 +252,7 @@
#![feature(collections_range)]
#![feature(compiler_builtins_lib)]
#![feature(const_fn)]
-#![feature(core_float)]
+#![cfg_attr(stage0, feature(core_float))]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
@@ -260,6 +260,7 @@
#![feature(fs_read_write)]
#![feature(fixed_size_array)]
#![feature(float_from_str_radix)]
+#![cfg_attr(stage0, feature(float_internals))]
#![feature(fn_traits)]
#![feature(fnbox)]
#![cfg_attr(stage0, feature(generic_param_attrs))]
diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs
index dda4e1bab3b..fe7e058091e 100644
--- a/src/libstd/sys_common/wtf8.rs
+++ b/src/libstd/sys_common/wtf8.rs
@@ -876,21 +876,7 @@ impl Hash for Wtf8 {
}
impl Wtf8 {
- pub fn is_ascii(&self) -> bool {
- self.bytes.is_ascii()
- }
- pub fn to_ascii_uppercase(&self) -> Wtf8Buf {
- Wtf8Buf { bytes: self.bytes.to_ascii_uppercase() }
- }
- pub fn to_ascii_lowercase(&self) -> Wtf8Buf {
- Wtf8Buf { bytes: self.bytes.to_ascii_lowercase() }
- }
- pub fn eq_ignore_ascii_case(&self, other: &Wtf8) -> bool {
- self.bytes.eq_ignore_ascii_case(&other.bytes)
- }
-
pub fn make_ascii_uppercase(&mut self) { self.bytes.make_ascii_uppercase() }
- pub fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() }
}
#[cfg(test)]
diff --git a/src/test/compile-fail/single-primitive-inherent-impl.rs b/src/test/compile-fail/single-primitive-inherent-impl.rs
index 365387c3e5e..0a0f9ce4bd1 100644
--- a/src/test/compile-fail/single-primitive-inherent-impl.rs
+++ b/src/test/compile-fail/single-primitive-inherent-impl.rs
@@ -15,7 +15,7 @@
#![no_std]
// OK
-#[lang = "str"]
+#[lang = "str_alloc"]
impl str {}
impl str {
diff --git a/src/test/rustdoc/issue-23511.rs b/src/test/rustdoc/issue-23511.rs
index 50c31d309ee..ee0a5c1aa1b 100644
--- a/src/test/rustdoc/issue-23511.rs
+++ b/src/test/rustdoc/issue-23511.rs
@@ -14,7 +14,7 @@
pub mod str {
#![doc(primitive = "str")]
- #[lang = "str"]
+ #[lang = "str_alloc"]
impl str {
// @has search-index.js foo
pub fn foo(&self) {}
diff --git a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr
index 438d29f0535..f7aaab4242c 100644
--- a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr
+++ b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr
@@ -8,10 +8,8 @@ LL | foo(|s| s.is_empty());
| ^^^^^^^^
|
= help: items from traits can only be used if the trait is implemented and in scope
- = note: the following traits define an item `is_empty`, perhaps you need to implement one of them:
+ = note: the following trait defines an item `is_empty`, perhaps you need to implement it:
candidate #1: `std::iter::ExactSizeIterator`
- candidate #2: `core::slice::SliceExt`
- candidate #3: `core::str::StrExt`
error: aborting due to previous error
diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.rs b/src/test/ui/macros/macro-backtrace-invalid-internals.rs
index bff64ad4892..090ff817eb0 100644
--- a/src/test/ui/macros/macro-backtrace-invalid-internals.rs
+++ b/src/test/ui/macros/macro-backtrace-invalid-internals.rs
@@ -48,13 +48,13 @@ macro_rules! fake_anon_field_expr {
macro_rules! real_method_stmt {
() => {
- 2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ 2.0.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
}
}
macro_rules! real_method_expr {
() => {
- 2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ 2.0.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
}
}
diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
index cb7d422b7f3..284960d2f6e 100644
--- a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
+++ b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
@@ -25,17 +25,17 @@ LL | (1).0 //~ ERROR doesn't have fields
LL | fake_anon_field_stmt!();
| ------------------------ in this macro invocation
-error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+error[E0689]: can't call method `recip` on ambiguous numeric type `{float}`
--> $DIR/macro-backtrace-invalid-internals.rs:51:15
|
-LL | 2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
- | ^^^^
+LL | 2.0.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
+ | ^^^^^
...
LL | real_method_stmt!();
| -------------------- in this macro invocation
help: you must specify a concrete type for this numeric value, like `f32`
|
-LL | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+LL | 2.0_f32.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
| ^^^^^^^
error[E0599]: no method named `fake` found for type `{integer}` in the current scope
@@ -65,17 +65,17 @@ LL | (1).0 //~ ERROR doesn't have fields
LL | let _ = fake_anon_field_expr!();
| ----------------------- in this macro invocation
-error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+error[E0689]: can't call method `recip` on ambiguous numeric type `{float}`
--> $DIR/macro-backtrace-invalid-internals.rs:57:15
|
-LL | 2.0.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
- | ^^^^
+LL | 2.0.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
+ | ^^^^^
...
LL | let _ = real_method_expr!();
| ------------------- in this macro invocation
help: you must specify a concrete type for this numeric value, like `f32`
|
-LL | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+LL | 2.0_f32.recip() //~ ERROR can't call method `recip` on ambiguous numeric type `{float}`
| ^^^^^^^
error: aborting due to 8 previous errors
diff --git a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs
index fa5bafab871..2e452f9671f 100644
--- a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs
+++ b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.rs
@@ -9,10 +9,10 @@
// except according to those terms.
fn main() {
- let x = 2.0.powi(2);
- //~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ let x = 2.0.recip();
+ //~^ ERROR can't call method `recip` on ambiguous numeric type `{float}`
let y = 2.0;
- let x = y.powi(2);
- //~^ ERROR can't call method `powi` on ambiguous numeric type `{float}`
+ let x = y.recip();
+ //~^ ERROR can't call method `recip` on ambiguous numeric type `{float}`
println!("{:?}", x);
}
diff --git a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr
index 92ad2280615..477b4c3821d 100644
--- a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr
+++ b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr
@@ -1,18 +1,18 @@
-error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+error[E0689]: can't call method `recip` on ambiguous numeric type `{float}`
--> $DIR/method-on-ambiguous-numeric-type.rs:12:17
|
-LL | let x = 2.0.powi(2);
- | ^^^^
+LL | let x = 2.0.recip();
+ | ^^^^^
help: you must specify a concrete type for this numeric value, like `f32`
|
-LL | let x = 2.0_f32.powi(2);
+LL | let x = 2.0_f32.recip();
| ^^^^^^^
-error[E0689]: can't call method `powi` on ambiguous numeric type `{float}`
+error[E0689]: can't call method `recip` on ambiguous numeric type `{float}`
--> $DIR/method-on-ambiguous-numeric-type.rs:15:15
|
-LL | let x = y.powi(2);
- | ^^^^
+LL | let x = y.recip();
+ | ^^^^^
help: you must specify a type for this binding, like `f32`
|
LL | let y: f32 = 2.0;