diff --git a/src/Cargo.lock b/src/Cargo.lock index 4c97b8923ec7b..5de710b68bbba 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -36,6 +36,7 @@ name = "alloc" version = "0.0.0" dependencies = [ "core 0.0.0", + "std_unicode 0.0.0", ] [[package]] @@ -250,15 +251,6 @@ dependencies = [ "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "collections" -version = "0.0.0" -dependencies = [ - "alloc 0.0.0", - "core 0.0.0", - "std_unicode 0.0.0", -] - [[package]] name = "compiler_builtins" version = "0.0.0" @@ -1594,7 +1586,6 @@ dependencies = [ "alloc_jemalloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "collections 0.0.0", "compiler_builtins 0.0.0", "core 0.0.0", "gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index ebf602373c965..4d58620ca648c 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -376,8 +376,8 @@ pub fn debugger_scripts(build: &Build, install(&build.src.join("src/etc/rust-windbg.cmd"), &sysroot.join("bin"), 0o755); + cp_debugger_script("natvis/liballoc.natvis"); cp_debugger_script("natvis/libcore.natvis"); - cp_debugger_script("natvis/libcollections.natvis"); } else { cp_debugger_script("debugger_pretty_printers_common.py"); @@ -550,7 +550,6 @@ pub fn rust_src(build: &Build) { "src/liballoc_jemalloc", "src/liballoc_system", "src/libbacktrace", - "src/libcollections", "src/libcompiler_builtins", "src/libcore", "src/liblibc", diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index baee1ada508f2..fc75b6ff5c3a4 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -246,7 +246,7 @@ pub fn std(build: &Build, stage: u32, target: &str) { // for which docs must be built. if !build.config.compiler_docs { cargo.arg("--no-deps"); - for krate in &["alloc", "collections", "core", "std", "std_unicode"] { + for krate in &["alloc", "core", "std", "std_unicode"] { cargo.arg("-p").arg(krate); // Create all crate output directories first to make sure rustdoc uses // relative links. diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 39922b7bbcfda..64bbb104f68e4 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -110,7 +110,6 @@ - [coerce_unsized](library-features/coerce-unsized.md) - [collection_placement](library-features/collection-placement.md) - [collections_range](library-features/collections-range.md) - - [collections](library-features/collections.md) - [command_envs](library-features/command-envs.md) - [compiler_builtins_lib](library-features/compiler-builtins-lib.md) - [compiler_fences](library-features/compiler-fences.md) diff --git a/src/doc/unstable-book/src/library-features/collections.md b/src/doc/unstable-book/src/library-features/collections.md deleted file mode 100644 index 5c937833c9e26..0000000000000 --- a/src/doc/unstable-book/src/library-features/collections.md +++ /dev/null @@ -1,5 +0,0 @@ -# `collections` - -This feature is internal to the Rust compiler and is not intended for general use. - ------------------------- diff --git a/src/etc/natvis/libcollections.natvis b/src/etc/natvis/liballoc.natvis similarity index 81% rename from src/etc/natvis/libcollections.natvis rename to src/etc/natvis/liballoc.natvis index e7e93be98695a..1f6d17748ab00 100644 --- a/src/etc/natvis/libcollections.natvis +++ b/src/etc/natvis/liballoc.natvis @@ -1,6 +1,6 @@ - + {{ size={len} }} len @@ -11,7 +11,7 @@ - + {{ size={tail <= head ? head - tail : buf.cap - tail + head} }} tail <= head ? head - tail : buf.cap - tail + head @@ -30,18 +30,18 @@ - + {{ size={len} }} len - *(collections::linked_list::Node<$T1> **)&head - *(collections::linked_list::Node<$T1> **)&next + *(alloc::linked_list::Node<$T1> **)&head + *(alloc::linked_list::Node<$T1> **)&next element - + {*(char**)this,[vec.len]} *(char**)this,[vec.len] @@ -53,4 +53,4 @@ - \ No newline at end of file + diff --git a/src/etc/rust-windbg.cmd b/src/etc/rust-windbg.cmd index 4cdd6b9860996..b09b37c1db423 100644 --- a/src/etc/rust-windbg.cmd +++ b/src/etc/rust-windbg.cmd @@ -15,4 +15,4 @@ for /f "delims=" %%i in ('rustc --print=sysroot') do set rustc_sysroot=%%i set rust_etc=%rustc_sysroot%\lib\rustlib\etc -windbg -c ".nvload %rust_etc%\libcore.natvis;.nvload %rust_etc%\libcollections.natvis;" %* \ No newline at end of file +windbg -c ".nvload %rust_etc%\liballoc.natvis; .nvload %rust_etc%\libcore.natvis;" %* diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml index 0889ca9fc84d4..686e5681d12b4 100644 --- a/src/liballoc/Cargo.toml +++ b/src/liballoc/Cargo.toml @@ -9,3 +9,12 @@ path = "lib.rs" [dependencies] core = { path = "../libcore" } +std_unicode = { path = "../libstd_unicode" } + +[[test]] +name = "collectionstests" +path = "../liballoc/tests/lib.rs" + +[[bench]] +name = "collectionsbenches" +path = "../liballoc/benches/lib.rs" diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 5ed41f6ffe627..7c51c4b161ca8 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -1222,11 +1222,12 @@ mod tests { use std::sync::atomic; use std::sync::atomic::Ordering::{Acquire, SeqCst}; use std::thread; - use std::vec::Vec; - use super::{Arc, Weak}; use std::sync::Mutex; use std::convert::From; + use super::{Arc, Weak}; + use vec::Vec; + struct Canary(*mut atomic::AtomicUsize); impl Drop for Canary { diff --git a/src/libcollections/benches/btree/map.rs b/src/liballoc/benches/btree/map.rs similarity index 100% rename from src/libcollections/benches/btree/map.rs rename to src/liballoc/benches/btree/map.rs diff --git a/src/libcollections/benches/btree/mod.rs b/src/liballoc/benches/btree/mod.rs similarity index 100% rename from src/libcollections/benches/btree/mod.rs rename to src/liballoc/benches/btree/mod.rs diff --git a/src/libcollections/benches/lib.rs b/src/liballoc/benches/lib.rs similarity index 100% rename from src/libcollections/benches/lib.rs rename to src/liballoc/benches/lib.rs diff --git a/src/libcollections/benches/linked_list.rs b/src/liballoc/benches/linked_list.rs similarity index 100% rename from src/libcollections/benches/linked_list.rs rename to src/liballoc/benches/linked_list.rs diff --git a/src/libcollections/benches/slice.rs b/src/liballoc/benches/slice.rs similarity index 100% rename from src/libcollections/benches/slice.rs rename to src/liballoc/benches/slice.rs diff --git a/src/libcollections/benches/str.rs b/src/liballoc/benches/str.rs similarity index 100% rename from src/libcollections/benches/str.rs rename to src/liballoc/benches/str.rs diff --git a/src/libcollections/benches/string.rs b/src/liballoc/benches/string.rs similarity index 100% rename from src/libcollections/benches/string.rs rename to src/liballoc/benches/string.rs diff --git a/src/libcollections/benches/vec.rs b/src/liballoc/benches/vec.rs similarity index 100% rename from src/libcollections/benches/vec.rs rename to src/liballoc/benches/vec.rs diff --git a/src/libcollections/benches/vec_deque.rs b/src/liballoc/benches/vec_deque.rs similarity index 100% rename from src/libcollections/benches/vec_deque.rs rename to src/liballoc/benches/vec_deque.rs diff --git a/src/libcollections/binary_heap.rs b/src/liballoc/binary_heap.rs similarity index 100% rename from src/libcollections/binary_heap.rs rename to src/liballoc/binary_heap.rs diff --git a/src/libcollections/borrow.rs b/src/liballoc/borrow.rs similarity index 100% rename from src/libcollections/borrow.rs rename to src/liballoc/borrow.rs diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 8a39be8fae8a5..2f867912f5824 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -95,6 +95,7 @@ pub const HEAP: ExchangeHeapSingleton = ExchangeHeapSingleton { _force_singleton #[unstable(feature = "box_heap", reason = "may be renamed; uncertain about custom allocator design", issue = "27779")] +#[allow(missing_debug_implementations)] #[derive(Copy, Clone)] pub struct ExchangeHeapSingleton { _force_singleton: (), @@ -129,6 +130,7 @@ pub struct Box(Unique); #[unstable(feature = "placement_in", reason = "placement box design is still being worked out.", issue = "27779")] +#[allow(missing_debug_implementations)] pub struct IntermediateBox { ptr: *mut u8, size: usize, diff --git a/src/libcollections/btree/map.rs b/src/liballoc/btree/map.rs similarity index 100% rename from src/libcollections/btree/map.rs rename to src/liballoc/btree/map.rs diff --git a/src/libcollections/btree/mod.rs b/src/liballoc/btree/mod.rs similarity index 100% rename from src/libcollections/btree/mod.rs rename to src/liballoc/btree/mod.rs diff --git a/src/libcollections/btree/node.rs b/src/liballoc/btree/node.rs similarity index 99% rename from src/libcollections/btree/node.rs rename to src/liballoc/btree/node.rs index 52cdd39d8f963..811174b331e2b 100644 --- a/src/libcollections/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -41,7 +41,6 @@ // - A node of length `n` has `n` keys, `n` values, and (in an internal node) `n + 1` edges. // This implies that even an empty internal node has at least one edge. -use alloc::heap; use core::marker::PhantomData; use core::mem; use core::nonzero::NonZero; @@ -49,6 +48,7 @@ use core::ptr::{self, Unique}; use core::slice; use boxed::Box; +use heap; const B: usize = 6; pub const MIN_LEN: usize = B - 1; diff --git a/src/libcollections/btree/search.rs b/src/liballoc/btree/search.rs similarity index 100% rename from src/libcollections/btree/search.rs rename to src/liballoc/btree/search.rs diff --git a/src/libcollections/btree/set.rs b/src/liballoc/btree/set.rs similarity index 100% rename from src/libcollections/btree/set.rs rename to src/liballoc/btree/set.rs diff --git a/src/libcollections/fmt.rs b/src/liballoc/fmt.rs similarity index 100% rename from src/libcollections/fmt.rs rename to src/liballoc/fmt.rs diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 418a084da6787..5252dabc12791 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2014-2017 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,18 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! # The Rust core allocation library +//! # The Rust core allocation and collections library //! -//! This is the lowest level library through which allocation in Rust can be -//! performed. +//! This library provides smart pointers and collections for managing +//! heap-allocated values. //! //! This library, like libcore, is not intended for general usage, but rather as //! a building block of other libraries. The types and interfaces in this //! library are reexported through the [standard library](../std/index.html), //! and should not be used through this library. //! -//! Currently, there are four major definitions in this library. -//! //! ## Boxed values //! //! The [`Box`](boxed/index.html) type is a smart pointer type. There can @@ -51,6 +49,12 @@ //! paired with synchronization primitives such as mutexes to allow mutation of //! shared resources. //! +//! ## Collections +//! +//! Implementations of the most common general purpose data structures are +//! defined in this library. They are reexported through the +//! [standard collections library](../std/collections/index.html). +//! //! ## Heap interfaces //! //! The [`heap`](heap/index.html) module defines the low-level interface to the @@ -71,8 +75,20 @@ #![no_std] #![needs_allocator] #![deny(warnings)] +#![deny(missing_debug_implementations)] +#![cfg_attr(test, allow(deprecated))] // rand +#![cfg_attr(test, feature(placement_in))] +#![cfg_attr(not(test), feature(char_escape_debug))] +#![cfg_attr(not(test), feature(core_float))] +#![cfg_attr(not(test), feature(exact_size_is_empty))] +#![cfg_attr(not(test), feature(slice_rotate))] +#![cfg_attr(not(test), feature(sort_unstable))] +#![cfg_attr(not(test), feature(str_checked_slicing))] +#![cfg_attr(test, feature(rand, test))] #![feature(allocator)] +#![feature(allow_internal_unstable)] +#![feature(box_patterns)] #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] #![feature(coerce_unsized)] @@ -80,16 +96,33 @@ #![feature(core_intrinsics)] #![feature(custom_attribute)] #![feature(dropck_eyepatch)] -#![cfg_attr(not(test), feature(exact_size_is_empty))] +#![feature(exact_size_is_empty)] +#![feature(fmt_internals)] #![feature(fundamental)] +#![feature(fused)] #![feature(generic_param_attrs)] +#![feature(i128_type)] +#![feature(inclusive_range)] #![feature(lang_items)] +#![feature(manually_drop)] #![feature(needs_allocator)] +#![feature(nonzero)] +#![feature(offset_to)] #![feature(optin_builtin_traits)] +#![feature(pattern)] #![feature(placement_in_syntax)] +#![feature(placement_new_protocol)] #![feature(shared)] +#![feature(slice_get_slice)] +#![feature(slice_patterns)] +#![feature(slice_rsplit)] +#![feature(specialization)] #![feature(staged_api)] +#![feature(str_internals)] +#![feature(str_mut_extras)] +#![feature(trusted_len)] #![feature(unboxed_closures)] +#![feature(unicode)] #![feature(unique)] #![feature(unsize)] @@ -101,6 +134,10 @@ #[cfg(test)] #[macro_use] extern crate std; +#[cfg(test)] +extern crate test; + +extern crate std_unicode; // Module with internal macros used by other modules (needs to be included before other modules). #[macro_use] @@ -120,7 +157,7 @@ pub mod heap; pub mod boxed; #[cfg(test)] mod boxed { - pub use std::boxed::{Box, HEAP}; + pub use std::boxed::{Box, IntermediateBox, HEAP}; } #[cfg(test)] mod boxed_test; @@ -128,8 +165,111 @@ mod boxed_test; pub mod arc; pub mod rc; pub mod raw_vec; -#[unstable(feature = "str_box_extras", issue = "41119")] -pub mod str; pub mod oom; +// collections modules +pub mod binary_heap; +mod btree; +pub mod borrow; +pub mod fmt; +pub mod linked_list; +pub mod range; +pub mod slice; +pub mod str; +pub mod string; +pub mod vec; +pub mod vec_deque; + +#[stable(feature = "rust1", since = "1.0.0")] +pub mod btree_map { + //! A map based on a B-Tree. + #[stable(feature = "rust1", since = "1.0.0")] + pub use btree::map::*; +} + +#[stable(feature = "rust1", since = "1.0.0")] +pub mod btree_set { + //! A set based on a B-Tree. + #[stable(feature = "rust1", since = "1.0.0")] + pub use btree::set::*; +} + +#[cfg(not(test))] +mod std { + pub use core::ops; // RangeFull +} + +/// An endpoint of a range of keys. +/// +/// # Examples +/// +/// `Bound`s are range endpoints: +/// +/// ``` +/// #![feature(collections_range)] +/// +/// use std::collections::range::RangeArgument; +/// use std::collections::Bound::*; +/// +/// assert_eq!((..100).start(), Unbounded); +/// assert_eq!((1..12).start(), Included(&1)); +/// assert_eq!((1..12).end(), Excluded(&12)); +/// ``` +/// +/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`]. +/// Note that in most cases, it's better to use range syntax (`1..5`) instead. +/// +/// ``` +/// use std::collections::BTreeMap; +/// use std::collections::Bound::{Excluded, Included, Unbounded}; +/// +/// let mut map = BTreeMap::new(); +/// map.insert(3, "a"); +/// map.insert(5, "b"); +/// map.insert(8, "c"); +/// +/// for (key, value) in map.range((Excluded(3), Included(8))) { +/// println!("{}: {}", key, value); +/// } +/// +/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next()); +/// ``` +/// +/// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range +#[stable(feature = "collections_bound", since = "1.17.0")] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] +pub enum Bound { + /// An inclusive bound. + #[stable(feature = "collections_bound", since = "1.17.0")] + Included(T), + /// An exclusive bound. + #[stable(feature = "collections_bound", since = "1.17.0")] + Excluded(T), + /// An infinite endpoint. Indicates that there is no bound in this direction. + #[stable(feature = "collections_bound", since = "1.17.0")] + Unbounded, +} + +/// An intermediate trait for specialization of `Extend`. +#[doc(hidden)] +trait SpecExtend { + /// Extends `self` with the contents of the given iterator. + fn spec_extend(&mut self, iter: I); +} + pub use oom::oom; + +#[doc(no_inline)] +pub use binary_heap::BinaryHeap; +#[doc(no_inline)] +pub use btree_map::BTreeMap; +#[doc(no_inline)] +pub use btree_set::BTreeSet; +#[doc(no_inline)] +pub use linked_list::LinkedList; +#[doc(no_inline)] +pub use vec_deque::VecDeque; +#[doc(no_inline)] +pub use string::String; +#[doc(no_inline)] +pub use vec::Vec; diff --git a/src/libcollections/linked_list.rs b/src/liballoc/linked_list.rs similarity index 99% rename from src/libcollections/linked_list.rs rename to src/liballoc/linked_list.rs index ae258083546f4..e8973b7d28537 100644 --- a/src/libcollections/linked_list.rs +++ b/src/liballoc/linked_list.rs @@ -22,7 +22,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use alloc::boxed::{Box, IntermediateBox}; use core::cmp::Ordering; use core::fmt; use core::hash::{Hasher, Hash}; @@ -32,6 +31,7 @@ use core::mem; use core::ops::{BoxPlace, InPlace, Place, Placer}; use core::ptr::{self, Shared}; +use boxed::{Box, IntermediateBox}; use super::SpecExtend; /// A doubly-linked list with owned nodes. diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs index 7da91c87e967e..763f04fcd0dcd 100644 --- a/src/liballoc/macros.rs +++ b/src/liballoc/macros.rs @@ -8,6 +8,89 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +/// Creates a `Vec` containing the arguments. +/// +/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions. +/// There are two forms of this macro: +/// +/// - Create a `Vec` containing a given list of elements: +/// +/// ``` +/// let v = vec![1, 2, 3]; +/// assert_eq!(v[0], 1); +/// assert_eq!(v[1], 2); +/// assert_eq!(v[2], 3); +/// ``` +/// +/// - Create a `Vec` from a given element and size: +/// +/// ``` +/// let v = vec![1; 3]; +/// assert_eq!(v, [1, 1, 1]); +/// ``` +/// +/// Note that unlike array expressions this syntax supports all elements +/// which implement `Clone` and the number of elements doesn't have to be +/// a constant. +/// +/// This will use `clone()` to duplicate an expression, so one should be careful +/// using this with types having a nonstandard `Clone` implementation. For +/// example, `vec![Rc::new(1); 5]` will create a vector of five references +/// to the same boxed integer value, not five references pointing to independently +/// boxed integers. +#[cfg(not(test))] +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +#[allow_internal_unstable] +macro_rules! vec { + ($elem:expr; $n:expr) => ( + $crate::vec::from_elem($elem, $n) + ); + ($($x:expr),*) => ( + <[_]>::into_vec(box [$($x),*]) + ); + ($($x:expr,)*) => (vec![$($x),*]) +} + +// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is +// required for this macro definition, is not available. Instead use the +// `slice::into_vec` function which is only available with cfg(test) +// NB see the slice::hack module in slice.rs for more information +#[cfg(test)] +macro_rules! vec { + ($elem:expr; $n:expr) => ( + $crate::vec::from_elem($elem, $n) + ); + ($($x:expr),*) => ( + $crate::slice::into_vec(box [$($x),*]) + ); + ($($x:expr,)*) => (vec![$($x),*]) +} + +/// Use the syntax described in `std::fmt` to create a value of type `String`. +/// See [`std::fmt`][fmt] for more information. +/// +/// [fmt]: ../std/fmt/index.html +/// +/// # Panics +/// +/// `format!` panics if a formatting trait implementation returns an error. +/// This indicates an incorrect implementation +/// since `fmt::Write for String` never returns an error itself. +/// +/// # Examples +/// +/// ``` +/// format!("test"); +/// format!("hello {}", "world!"); +/// format!("x = {}, y = {y}", 10, y = 30); +/// ``` +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +macro_rules! format { + ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*))) +} + // Private macro to get the offset of a struct field in bytes from the address of the struct. macro_rules! offset_of { ($container:path, $field:ident) => {{ diff --git a/src/libcollections/range.rs b/src/liballoc/range.rs similarity index 92% rename from src/libcollections/range.rs rename to src/liballoc/range.rs index bc8566e8cbeb3..f862da0d61e01 100644 --- a/src/libcollections/range.rs +++ b/src/liballoc/range.rs @@ -27,14 +27,14 @@ pub trait RangeArgument { /// # Examples /// /// ``` - /// #![feature(collections)] + /// #![feature(alloc)] /// #![feature(collections_range)] /// - /// extern crate collections; + /// extern crate alloc; /// /// # fn main() { - /// use collections::range::RangeArgument; - /// use collections::Bound::*; + /// use alloc::range::RangeArgument; + /// use alloc::Bound::*; /// /// assert_eq!((..10).start(), Unbounded); /// assert_eq!((3..10).start(), Included(&3)); @@ -49,14 +49,14 @@ pub trait RangeArgument { /// # Examples /// /// ``` - /// #![feature(collections)] + /// #![feature(alloc)] /// #![feature(collections_range)] /// - /// extern crate collections; + /// extern crate alloc; /// /// # fn main() { - /// use collections::range::RangeArgument; - /// use collections::Bound::*; + /// use alloc::range::RangeArgument; + /// use alloc::Bound::*; /// /// assert_eq!((3..).end(), Unbounded); /// assert_eq!((3..10).end(), Excluded(&10)); diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 7edf07944ec50..34ab0a19d4e09 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -44,6 +44,7 @@ use core::cmp; /// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity /// field. This allows zero-sized types to not be special-cased by consumers of /// this type. +#[allow(missing_debug_implementations)] pub struct RawVec { ptr: Unique, cap: usize, diff --git a/src/libcollections/slice.rs b/src/liballoc/slice.rs similarity index 99% rename from src/libcollections/slice.rs rename to src/liballoc/slice.rs index 97d6687c79b57..88876999d765a 100644 --- a/src/libcollections/slice.rs +++ b/src/liballoc/slice.rs @@ -97,7 +97,6 @@ // It's cleaner to just turn off the unused_imports warning than to fix them. #![cfg_attr(test, allow(unused_imports, dead_code))] -use alloc::boxed::Box; use core::cmp::Ordering::{self, Less}; use core::mem::size_of; use core::mem; @@ -105,6 +104,7 @@ use core::ptr; use core::slice as core_slice; use borrow::{Borrow, BorrowMut, ToOwned}; +use boxed::Box; use vec::Vec; #[stable(feature = "rust1", since = "1.0.0")] @@ -141,7 +141,7 @@ pub use self::hack::to_vec; // `core::slice::SliceExt` - we need to supply these functions for the // `test_permutations` test mod hack { - use alloc::boxed::Box; + use boxed::Box; use core::mem; #[cfg(test)] diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index c87db16a0f417..f56288c30132c 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -8,11 +8,1992 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Methods for dealing with boxed strings. +//! Unicode string slices. +//! +//! The `&str` type is one of the two main string types, the other being `String`. +//! Unlike its `String` counterpart, its contents are borrowed. +//! +//! # Basic Usage +//! +//! A basic string declaration of `&str` type: +//! +//! ``` +//! let hello_world = "Hello, World!"; +//! ``` +//! +//! Here we have declared a string literal, also known as a string slice. +//! String literals have a static lifetime, which means the string `hello_world` +//! is guaranteed to be valid for the duration of the entire program. +//! We can explicitly specify `hello_world`'s lifetime as well: +//! +//! ``` +//! let hello_world: &'static str = "Hello, world!"; +//! ``` +//! +//! *[See also the `str` primitive type](../../std/primitive.str.html).* + +#![stable(feature = "rust1", since = "1.0.0")] + +// Many of the usings in this module are only used in the test configuration. +// It's cleaner to just turn off the unused_imports warning than to fix them. +#![allow(unused_imports)] + +use core::fmt; +use core::str as core_str; +use core::str::pattern::Pattern; +use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; use core::mem; +use core::iter::FusedIterator; +use std_unicode::str::{UnicodeStr, Utf16Encoder}; +use vec_deque::VecDeque; +use borrow::{Borrow, ToOwned}; +use string::String; +use std_unicode; +use vec::Vec; +use slice::{SliceConcatExt, SliceIndex}; use boxed::Box; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::{FromStr, Utf8Error}; +#[allow(deprecated)] +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::{Lines, LinesAny}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::{Split, RSplit}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::{SplitN, RSplitN}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::{SplitTerminator, RSplitTerminator}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::{Matches, RMatches}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::{MatchIndices, RMatchIndices}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::{from_utf8, from_utf8_mut, Chars, CharIndices, Bytes}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError}; +#[stable(feature = "rust1", since = "1.0.0")] +pub use std_unicode::str::SplitWhitespace; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::str::pattern; + + +#[unstable(feature = "slice_concat_ext", + reason = "trait should not have to exist", + issue = "27747")] +impl> SliceConcatExt for [S] { + type Output = String; + + fn concat(&self) -> String { + if self.is_empty() { + return String::new(); + } + + // `len` calculation may overflow but push_str will check boundaries + let len = self.iter().map(|s| s.borrow().len()).sum(); + let mut result = String::with_capacity(len); + + for s in self { + result.push_str(s.borrow()) + } + + result + } + + fn join(&self, sep: &str) -> String { + if self.is_empty() { + return String::new(); + } + + // concat is faster + if sep.is_empty() { + return self.concat(); + } + + // this is wrong without the guarantee that `self` is non-empty + // `len` calculation may overflow but push_str but will check boundaries + let len = sep.len() * (self.len() - 1) + + self.iter().map(|s| s.borrow().len()).sum::(); + let mut result = String::with_capacity(len); + let mut first = true; + + for s in self { + if first { + first = false; + } else { + result.push_str(sep); + } + result.push_str(s.borrow()); + } + result + } + + fn connect(&self, sep: &str) -> String { + self.join(sep) + } +} + +/// 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> { + encoder: Utf16Encoder>, +} + +#[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 { + self.encoder.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.encoder.size_hint() + } +} + +#[unstable(feature = "fused", issue = "35602")] +impl<'a> FusedIterator for EncodeUtf16<'a> {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Borrow for String { + #[inline] + fn borrow(&self) -> &str { + &self[..] + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ToOwned for str { + type Owned = String; + fn to_owned(&self) -> String { + unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) } + } + + fn clone_into(&self, target: &mut String) { + let mut b = mem::replace(target, String::new()).into_bytes(); + self.as_bytes().clone_into(&mut b); + *target = unsafe { String::from_utf8_unchecked(b) } + } +} + +/// Methods for string slices. +#[lang = "str"] +#[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. + /// + /// # 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. + #[unstable(feature = "str_mut_extras", issue = "41119")] + #[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 + /// + /// ``` + /// # #![feature(str_checked_slicing)] + /// let v = "🗻∈🌏"; + /// assert_eq!(Some("🗻"), v.get(0..4)); + /// assert!(v.get(1..).is_none()); + /// assert!(v.get(..8).is_none()); + /// assert!(v.get(..42).is_none()); + /// ``` + #[unstable(feature = "str_checked_slicing", issue = "39932")] + #[inline] + pub fn get>(&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 + /// + /// ``` + /// # #![feature(str_checked_slicing)] + /// let mut v = String::from("🗻∈🌏"); + /// assert_eq!(Some("🗻"), v.get_mut(0..4).map(|v| &*v)); + /// assert!(v.get_mut(1..).is_none()); + /// assert!(v.get_mut(..8).is_none()); + /// assert!(v.get_mut(..42).is_none()); + /// ``` + #[unstable(feature = "str_checked_slicing", issue = "39932")] + #[inline] + pub fn get_mut>(&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 + /// + /// ``` + /// # #![feature(str_checked_slicing)] + /// let v = "🗻∈🌏"; + /// unsafe { + /// assert_eq!("🗻", v.get_unchecked(0..4)); + /// assert_eq!("∈", v.get_unchecked(4..7)); + /// assert_eq!("🌏", v.get_unchecked(7..11)); + /// } + /// ``` + #[unstable(feature = "str_checked_slicing", issue = "39932")] + #[inline] + pub unsafe fn get_unchecked>(&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 + /// + /// ``` + /// # #![feature(str_checked_slicing)] + /// 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)); + /// } + /// ``` + #[unstable(feature = "str_checked_slicing", issue = "39932")] + #[inline] + pub unsafe fn get_unchecked_mut>(&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); + /// + /// assert_eq!("Per", first); + /// assert_eq!(" Martin-Löf", last); + /// ``` + #[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 y = "y̆"; + /// + /// let mut char_indices = y.char_indices(); + /// + /// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆') + /// assert_eq!(Some((1, '\u{0306}')), 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 { + UnicodeStr::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. + #[stable(feature = "encode_utf16", since = "1.8.0")] + pub fn encode_utf16(&self) -> EncodeUtf16 { + EncodeUtf16 { encoder: Utf16Encoder::new(self[..].chars()) } + } + + /// 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 with 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)); + /// ``` + /// + /// 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 { + 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 + 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 { + UnicodeStr::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 { + UnicodeStr::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 { + UnicodeStr::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_left_matches(|c| c == '1' || c == 'X'), "fooX"); + /// ``` + #[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 + /// + /// # Example + /// + /// Basic usage + /// + /// ``` + /// let four: u32 = "4".parse().unwrap(); + /// + /// assert_eq!(4, four); + /// ``` + /// + /// Using the 'turbofish' instead of annotating `four`: + /// + /// ``` + /// let four = "4".parse::(); + /// + /// assert_eq!(Ok(4), four); + /// ``` + /// + /// Failing to parse: + /// + /// ``` + /// let nope = "j".parse::(); + /// + /// assert!(nope.is_err()); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn parse(&self) -> Result { + core_str::StrExt::parse(self) + } + + /// Converts a `Box` into a `Box<[u8]>` without copying or allocating. + #[unstable(feature = "str_box_extras", issue = "41119")] + pub fn into_boxed_bytes(self: Box) -> Box<[u8]> { + self.into() + } + + /// Replaces all matches of a pattern with another string. + /// + /// `replace` creates a new [`String`], and copies the data from this string slice into it. + /// While doing so, it attempts to find matches of a pattern. If it finds any, it + /// replaces them with the replacement string slice. + /// + /// [`String`]: string/struct.String.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s = "this is old"; + /// + /// assert_eq!("this is new", s.replace("old", "new")); + /// ``` + /// + /// When the pattern doesn't match: + /// + /// ``` + /// let s = "this is old"; + /// assert_eq!(s, s.replace("cookie monster", "little lamb")); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String { + let mut result = String::new(); + let mut last_end = 0; + for (start, part) in self.match_indices(from) { + result.push_str(unsafe { self.slice_unchecked(last_end, start) }); + result.push_str(to); + last_end = start + part.len(); + } + result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) }); + result + } + + /// Replaces first N matches of a pattern with another string. + /// + /// `replacen` creates a new [`String`], and copies the data from this string slice into it. + /// While doing so, it attempts to find matches of a pattern. If it finds any, it + /// replaces them with the replacement string slice at most `count` times. + /// + /// [`String`]: string/struct.String.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s = "foo foo 123 foo"; + /// assert_eq!("new new 123 foo", s.replacen("foo", "new", 2)); + /// assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3)); + /// assert_eq!("foo foo new23 foo", s.replacen(char::is_numeric, "new", 1)); + /// ``` + /// + /// When the pattern doesn't match: + /// + /// ``` + /// let s = "this is old"; + /// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10)); + /// ``` + #[stable(feature = "str_replacen", since = "1.16.0")] + pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String { + // Hope to reduce the times of re-allocation + let mut result = String::with_capacity(32); + let mut last_end = 0; + for (start, part) in self.match_indices(pat).take(count) { + result.push_str(unsafe { self.slice_unchecked(last_end, start) }); + result.push_str(to); + last_end = start + part.len(); + } + result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) }); + result + } + + /// Returns the lowercase equivalent of this string slice, as a new [`String`]. + /// + /// 'Lowercase' is defined according to the terms of the Unicode Derived Core Property + /// `Lowercase`. + /// + /// Since some characters can expand into multiple characters when changing + /// the case, this function returns a [`String`] instead of modifying the + /// parameter in-place. + /// + /// [`String`]: string/struct.String.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s = "HELLO"; + /// + /// assert_eq!("hello", s.to_lowercase()); + /// ``` + /// + /// A tricky example, with sigma: + /// + /// ``` + /// let sigma = "Σ"; + /// + /// assert_eq!("σ", sigma.to_lowercase()); + /// + /// // but at the end of a word, it's ς, not σ: + /// let odysseus = "ὈΔΥΣΣΕΎΣ"; + /// + /// assert_eq!("ὀδυσσεύς", odysseus.to_lowercase()); + /// ``` + /// + /// Languages without case are not changed: + /// + /// ``` + /// let new_year = "农历新年"; + /// + /// assert_eq!(new_year, new_year.to_lowercase()); + /// ``` + #[stable(feature = "unicode_case_mapping", since = "1.2.0")] + pub fn to_lowercase(&self) -> String { + let mut s = String::with_capacity(self.len()); + for (i, c) in self[..].char_indices() { + if c == 'Σ' { + // Σ maps to σ, except at the end of a word where it maps to ς. + // This is the only conditional (contextual) but language-independent mapping + // in `SpecialCasing.txt`, + // so hard-code it rather than have a generic "condition" mechanism. + // See https://github.com/rust-lang/rust/issues/26035 + map_uppercase_sigma(self, i, &mut s) + } else { + s.extend(c.to_lowercase()); + } + } + return s; + + fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) { + // See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 + // for the definition of `Final_Sigma`. + debug_assert!('Σ'.len_utf8() == 2); + let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) && + !case_ignoreable_then_cased(from[i + 2..].chars()); + to.push_str(if is_word_final { "ς" } else { "σ" }); + } + + fn case_ignoreable_then_cased>(iter: I) -> bool { + use std_unicode::derived_property::{Cased, Case_Ignorable}; + match iter.skip_while(|&c| Case_Ignorable(c)).next() { + Some(c) => Cased(c), + None => false, + } + } + } + + /// Returns the uppercase equivalent of this string slice, as a new [`String`]. + /// + /// 'Uppercase' is defined according to the terms of the Unicode Derived Core Property + /// `Uppercase`. + /// + /// Since some characters can expand into multiple characters when changing + /// the case, this function returns a [`String`] instead of modifying the + /// parameter in-place. + /// + /// [`String`]: string/struct.String.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s = "hello"; + /// + /// assert_eq!("HELLO", s.to_uppercase()); + /// ``` + /// + /// Scripts without case are not changed: + /// + /// ``` + /// let new_year = "农历新年"; + /// + /// assert_eq!(new_year, new_year.to_uppercase()); + /// ``` + #[stable(feature = "unicode_case_mapping", since = "1.2.0")] + pub fn to_uppercase(&self) -> String { + let mut s = String::with_capacity(self.len()); + s.extend(self.chars().flat_map(|c| c.to_uppercase())); + return s; + } + + /// Escapes each char in `s` with [`char::escape_debug`]. + /// + /// [`char::escape_debug`]: primitive.char.html#method.escape_debug + #[unstable(feature = "str_escape", + reason = "return type may change to be an iterator", + issue = "27791")] + pub fn escape_debug(&self) -> String { + self.chars().flat_map(|c| c.escape_debug()).collect() + } + + /// Escapes each char in `s` with [`char::escape_default`]. + /// + /// [`char::escape_default`]: primitive.char.html#method.escape_default + #[unstable(feature = "str_escape", + reason = "return type may change to be an iterator", + issue = "27791")] + pub fn escape_default(&self) -> String { + self.chars().flat_map(|c| c.escape_default()).collect() + } + + /// Escapes each char in `s` with [`char::escape_unicode`]. + /// + /// [`char::escape_unicode`]: primitive.char.html#method.escape_unicode + #[unstable(feature = "str_escape", + reason = "return type may change to be an iterator", + issue = "27791")] + pub fn escape_unicode(&self) -> String { + self.chars().flat_map(|c| c.escape_unicode()).collect() + } + + /// Converts a [`Box`] into a [`String`] without copying or allocating. + /// + /// [`String`]: string/struct.String.html + /// [`Box`]: boxed/struct.Box.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let string = String::from("birthday gift"); + /// let boxed_str = string.clone().into_boxed_str(); + /// + /// assert_eq!(boxed_str.into_string(), string); + /// ``` + #[stable(feature = "box_str", since = "1.4.0")] + pub fn into_string(self: Box) -> String { + unsafe { + let slice = mem::transmute::, Box<[u8]>>(self); + String::from_utf8_unchecked(slice.into_vec()) + } + } + + /// Create a [`String`] by repeating a string `n` times. + /// + /// [`String`]: string/struct.String.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!("abc".repeat(4), String::from("abcabcabcabc")); + /// ``` + #[stable(feature = "repeat_str", since = "1.16.0")] + pub fn repeat(&self, n: usize) -> String { + let mut s = String::with_capacity(self.len() * n); + s.extend((0..n).map(|_| self)); + s + } +} + /// Converts a boxed slice of bytes to a boxed string slice without checking /// that the string contains valid UTF-8. #[unstable(feature = "str_box_extras", issue = "41119")] diff --git a/src/libcollections/string.rs b/src/liballoc/string.rs similarity index 99% rename from src/libcollections/string.rs rename to src/liballoc/string.rs index 55f0e01548fee..1d98626e90b09 100644 --- a/src/libcollections/string.rs +++ b/src/liballoc/string.rs @@ -56,8 +56,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use alloc::str as alloc_str; - use core::fmt; use core::hash; use core::iter::{FromIterator, FusedIterator}; @@ -70,7 +68,7 @@ use std_unicode::char::{decode_utf16, REPLACEMENT_CHARACTER}; use borrow::{Cow, ToOwned}; use range::RangeArgument; use Bound::{Excluded, Included, Unbounded}; -use str::{self, FromStr, Utf8Error, Chars}; +use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}; use vec::Vec; use boxed::Box; @@ -1464,7 +1462,7 @@ impl String { #[stable(feature = "box_str", since = "1.4.0")] pub fn into_boxed_str(self) -> Box { let slice = self.vec.into_boxed_slice(); - unsafe { alloc_str::from_boxed_utf8_unchecked(slice) } + unsafe { from_boxed_utf8_unchecked(slice) } } } diff --git a/src/libcollections/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs similarity index 100% rename from src/libcollections/tests/binary_heap.rs rename to src/liballoc/tests/binary_heap.rs diff --git a/src/libcollections/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs similarity index 100% rename from src/libcollections/tests/btree/map.rs rename to src/liballoc/tests/btree/map.rs diff --git a/src/libcollections/tests/btree/mod.rs b/src/liballoc/tests/btree/mod.rs similarity index 100% rename from src/libcollections/tests/btree/mod.rs rename to src/liballoc/tests/btree/mod.rs diff --git a/src/libcollections/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs similarity index 100% rename from src/libcollections/tests/btree/set.rs rename to src/liballoc/tests/btree/set.rs diff --git a/src/libcollections/tests/cow_str.rs b/src/liballoc/tests/cow_str.rs similarity index 100% rename from src/libcollections/tests/cow_str.rs rename to src/liballoc/tests/cow_str.rs diff --git a/src/libcollections/tests/fmt.rs b/src/liballoc/tests/fmt.rs similarity index 100% rename from src/libcollections/tests/fmt.rs rename to src/liballoc/tests/fmt.rs diff --git a/src/libcollections/tests/lib.rs b/src/liballoc/tests/lib.rs similarity index 96% rename from src/libcollections/tests/lib.rs rename to src/liballoc/tests/lib.rs index c6f0b4436bb31..c6d70ee7575f8 100644 --- a/src/libcollections/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -10,11 +10,11 @@ #![deny(warnings)] +#![feature(alloc)] #![feature(attr_literals)] #![feature(box_syntax)] #![feature(inclusive_range_syntax)] #![feature(collection_placement)] -#![feature(collections)] #![feature(const_fn)] #![feature(exact_size_is_empty)] #![feature(iterator_step_by)] @@ -31,7 +31,7 @@ #![feature(unicode)] #![feature(utf8_error_error_len)] -extern crate collections; +extern crate alloc; extern crate test; extern crate std_unicode; extern crate core; diff --git a/src/libcollections/tests/linked_list.rs b/src/liballoc/tests/linked_list.rs similarity index 100% rename from src/libcollections/tests/linked_list.rs rename to src/liballoc/tests/linked_list.rs diff --git a/src/libcollections/tests/slice.rs b/src/liballoc/tests/slice.rs similarity index 100% rename from src/libcollections/tests/slice.rs rename to src/liballoc/tests/slice.rs diff --git a/src/libcollections/tests/str.rs b/src/liballoc/tests/str.rs similarity index 100% rename from src/libcollections/tests/str.rs rename to src/liballoc/tests/str.rs diff --git a/src/libcollections/tests/string.rs b/src/liballoc/tests/string.rs similarity index 100% rename from src/libcollections/tests/string.rs rename to src/liballoc/tests/string.rs diff --git a/src/libcollections/tests/vec.rs b/src/liballoc/tests/vec.rs similarity index 100% rename from src/libcollections/tests/vec.rs rename to src/liballoc/tests/vec.rs diff --git a/src/libcollections/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs similarity index 100% rename from src/libcollections/tests/vec_deque.rs rename to src/liballoc/tests/vec_deque.rs diff --git a/src/libcollections/vec.rs b/src/liballoc/vec.rs similarity index 99% rename from src/libcollections/vec.rs rename to src/liballoc/vec.rs index 2de27725e956c..8bb16febb0483 100644 --- a/src/libcollections/vec.rs +++ b/src/liballoc/vec.rs @@ -66,10 +66,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use alloc::boxed::Box; -use alloc::raw_vec::RawVec; -use borrow::ToOwned; -use borrow::Cow; use core::cmp::Ordering; use core::fmt; use core::hash::{self, Hash}; @@ -84,6 +80,10 @@ use core::ptr; use core::ptr::Shared; use core::slice; +use borrow::ToOwned; +use borrow::Cow; +use boxed::Box; +use raw_vec::RawVec; use super::range::RangeArgument; use Bound::{Excluded, Included, Unbounded}; diff --git a/src/libcollections/vec_deque.rs b/src/liballoc/vec_deque.rs similarity index 99% rename from src/libcollections/vec_deque.rs rename to src/liballoc/vec_deque.rs index e826c9432b516..18175a5d01bd2 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -29,7 +29,7 @@ use core::slice; use core::hash::{Hash, Hasher}; use core::cmp; -use alloc::raw_vec::RawVec; +use raw_vec::RawVec; use super::range::RangeArgument; use Bound::{Excluded, Included, Unbounded}; diff --git a/src/libcollections/Cargo.toml b/src/libcollections/Cargo.toml deleted file mode 100644 index 7e92404bc0d6f..0000000000000 --- a/src/libcollections/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "collections" -version = "0.0.0" - -[lib] -name = "collections" -path = "lib.rs" - -[dependencies] -alloc = { path = "../liballoc" } -core = { path = "../libcore" } -std_unicode = { path = "../libstd_unicode" } - -[[test]] -name = "collectionstests" -path = "../libcollections/tests/lib.rs" - -[[bench]] -name = "collectionsbenches" -path = "../libcollections/benches/lib.rs" diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs deleted file mode 100644 index 34626326c221c..0000000000000 --- a/src/libcollections/lib.rs +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Collection types. -//! -//! See [`std::collections`](../std/collections/index.html) for a detailed -//! discussion of collections in Rust. - -#![crate_name = "collections"] -#![crate_type = "rlib"] -#![unstable(feature = "collections", - reason = "library is unlikely to be stabilized with the current \ - layout and name, use std::collections instead", - issue = "27783")] -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/", - html_playground_url = "https://play.rust-lang.org/", - issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", - test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))] - -#![cfg_attr(test, allow(deprecated))] // rand -#![deny(warnings)] -#![deny(missing_debug_implementations)] - -#![feature(alloc)] -#![feature(allow_internal_unstable)] -#![feature(box_patterns)] -#![feature(box_syntax)] -#![cfg_attr(not(test), feature(char_escape_debug))] -#![cfg_attr(not(test), feature(core_float))] -#![feature(core_intrinsics)] -#![feature(dropck_eyepatch)] -#![feature(exact_size_is_empty)] -#![feature(fmt_internals)] -#![feature(fused)] -#![feature(generic_param_attrs)] -#![feature(heap_api)] -#![feature(i128_type)] -#![feature(inclusive_range)] -#![feature(lang_items)] -#![feature(manually_drop)] -#![feature(nonzero)] -#![feature(pattern)] -#![feature(placement_in)] -#![feature(placement_in_syntax)] -#![feature(placement_new_protocol)] -#![feature(shared)] -#![feature(slice_get_slice)] -#![feature(slice_patterns)] -#![cfg_attr(not(test), feature(slice_rotate))] -#![feature(slice_rsplit)] -#![cfg_attr(not(test), feature(sort_unstable))] -#![feature(specialization)] -#![feature(staged_api)] -#![feature(str_internals)] -#![feature(str_box_extras)] -#![feature(str_mut_extras)] -#![feature(trusted_len)] -#![feature(unicode)] -#![feature(unique)] -#![cfg_attr(not(test), feature(str_checked_slicing))] -#![cfg_attr(test, feature(rand, test))] -#![feature(offset_to)] - -#![no_std] - -extern crate std_unicode; -extern crate alloc; - -#[cfg(test)] -#[macro_use] -extern crate std; -#[cfg(test)] -extern crate test; - -#[doc(no_inline)] -pub use binary_heap::BinaryHeap; -#[doc(no_inline)] -pub use btree_map::BTreeMap; -#[doc(no_inline)] -pub use btree_set::BTreeSet; -#[doc(no_inline)] -pub use linked_list::LinkedList; -#[doc(no_inline)] -pub use vec_deque::VecDeque; -#[doc(no_inline)] -pub use string::String; -#[doc(no_inline)] -pub use vec::Vec; - -// Needed for the vec! macro -pub use alloc::boxed; - -#[macro_use] -mod macros; - -pub mod binary_heap; -mod btree; -pub mod borrow; -pub mod fmt; -pub mod linked_list; -pub mod range; -pub mod slice; -pub mod str; -pub mod string; -pub mod vec; -pub mod vec_deque; - -#[stable(feature = "rust1", since = "1.0.0")] -pub mod btree_map { - //! A map based on a B-Tree. - #[stable(feature = "rust1", since = "1.0.0")] - pub use btree::map::*; -} - -#[stable(feature = "rust1", since = "1.0.0")] -pub mod btree_set { - //! A set based on a B-Tree. - #[stable(feature = "rust1", since = "1.0.0")] - pub use btree::set::*; -} - -#[cfg(not(test))] -mod std { - pub use core::ops; // RangeFull -} - -/// An endpoint of a range of keys. -/// -/// # Examples -/// -/// `Bound`s are range endpoints: -/// -/// ``` -/// #![feature(collections_range)] -/// -/// use std::collections::range::RangeArgument; -/// use std::collections::Bound::*; -/// -/// assert_eq!((..100).start(), Unbounded); -/// assert_eq!((1..12).start(), Included(&1)); -/// assert_eq!((1..12).end(), Excluded(&12)); -/// ``` -/// -/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`]. -/// Note that in most cases, it's better to use range syntax (`1..5`) instead. -/// -/// ``` -/// use std::collections::BTreeMap; -/// use std::collections::Bound::{Excluded, Included, Unbounded}; -/// -/// let mut map = BTreeMap::new(); -/// map.insert(3, "a"); -/// map.insert(5, "b"); -/// map.insert(8, "c"); -/// -/// for (key, value) in map.range((Excluded(3), Included(8))) { -/// println!("{}: {}", key, value); -/// } -/// -/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next()); -/// ``` -/// -/// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range -#[stable(feature = "collections_bound", since = "1.17.0")] -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] -pub enum Bound { - /// An inclusive bound. - #[stable(feature = "collections_bound", since = "1.17.0")] - Included(T), - /// An exclusive bound. - #[stable(feature = "collections_bound", since = "1.17.0")] - Excluded(T), - /// An infinite endpoint. Indicates that there is no bound in this direction. - #[stable(feature = "collections_bound", since = "1.17.0")] - Unbounded, -} - -/// An intermediate trait for specialization of `Extend`. -#[doc(hidden)] -trait SpecExtend { - /// Extends `self` with the contents of the given iterator. - fn spec_extend(&mut self, iter: I); -} diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs deleted file mode 100644 index 396a917dfde26..0000000000000 --- a/src/libcollections/macros.rs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/// Creates a `Vec` containing the arguments. -/// -/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions. -/// There are two forms of this macro: -/// -/// - Create a `Vec` containing a given list of elements: -/// -/// ``` -/// let v = vec![1, 2, 3]; -/// assert_eq!(v[0], 1); -/// assert_eq!(v[1], 2); -/// assert_eq!(v[2], 3); -/// ``` -/// -/// - Create a `Vec` from a given element and size: -/// -/// ``` -/// let v = vec![1; 3]; -/// assert_eq!(v, [1, 1, 1]); -/// ``` -/// -/// Note that unlike array expressions this syntax supports all elements -/// which implement `Clone` and the number of elements doesn't have to be -/// a constant. -/// -/// This will use `clone()` to duplicate an expression, so one should be careful -/// using this with types having a nonstandard `Clone` implementation. For -/// example, `vec![Rc::new(1); 5]` will create a vector of five references -/// to the same boxed integer value, not five references pointing to independently -/// boxed integers. -#[cfg(not(test))] -#[macro_export] -#[stable(feature = "rust1", since = "1.0.0")] -#[allow_internal_unstable] -macro_rules! vec { - ($elem:expr; $n:expr) => ( - $crate::vec::from_elem($elem, $n) - ); - ($($x:expr),*) => ( - <[_]>::into_vec(box [$($x),*]) - ); - ($($x:expr,)*) => (vec![$($x),*]) -} - -// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is -// required for this macro definition, is not available. Instead use the -// `slice::into_vec` function which is only available with cfg(test) -// NB see the slice::hack module in slice.rs for more information -#[cfg(test)] -macro_rules! vec { - ($elem:expr; $n:expr) => ( - $crate::vec::from_elem($elem, $n) - ); - ($($x:expr),*) => ( - $crate::slice::into_vec(box [$($x),*]) - ); - ($($x:expr,)*) => (vec![$($x),*]) -} - -/// Use the syntax described in `std::fmt` to create a value of type `String`. -/// See [`std::fmt`][fmt] for more information. -/// -/// [fmt]: ../std/fmt/index.html -/// -/// # Panics -/// -/// `format!` panics if a formatting trait implementation returns an error. -/// This indicates an incorrect implementation -/// since `fmt::Write for String` never returns an error itself. -/// -/// # Examples -/// -/// ``` -/// format!("test"); -/// format!("hello {}", "world!"); -/// format!("x = {}, y = {y}", 10, y = 30); -/// ``` -#[macro_export] -#[stable(feature = "rust1", since = "1.0.0")] -macro_rules! format { - ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*))) -} diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs deleted file mode 100644 index fdb6ee42127b9..0000000000000 --- a/src/libcollections/str.rs +++ /dev/null @@ -1,1997 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Unicode string slices. -//! -//! The `&str` type is one of the two main string types, the other being `String`. -//! Unlike its `String` counterpart, its contents are borrowed. -//! -//! # Basic Usage -//! -//! A basic string declaration of `&str` type: -//! -//! ``` -//! let hello_world = "Hello, World!"; -//! ``` -//! -//! Here we have declared a string literal, also known as a string slice. -//! String literals have a static lifetime, which means the string `hello_world` -//! is guaranteed to be valid for the duration of the entire program. -//! We can explicitly specify `hello_world`'s lifetime as well: -//! -//! ``` -//! let hello_world: &'static str = "Hello, world!"; -//! ``` -//! -//! *[See also the `str` primitive type](../../std/primitive.str.html).* - -#![stable(feature = "rust1", since = "1.0.0")] - -// Many of the usings in this module are only used in the test configuration. -// It's cleaner to just turn off the unused_imports warning than to fix them. -#![allow(unused_imports)] - -use core::fmt; -use core::str as core_str; -use core::str::pattern::Pattern; -use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; -use core::mem; -use core::iter::FusedIterator; -use std_unicode::str::{UnicodeStr, Utf16Encoder}; - -use vec_deque::VecDeque; -use borrow::{Borrow, ToOwned}; -use string::String; -use std_unicode; -use vec::Vec; -use slice::{SliceConcatExt, SliceIndex}; -use boxed::Box; - -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{FromStr, Utf8Error}; -#[allow(deprecated)] -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{Lines, LinesAny}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{Split, RSplit}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{SplitN, RSplitN}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{SplitTerminator, RSplitTerminator}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{Matches, RMatches}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{MatchIndices, RMatchIndices}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{from_utf8, from_utf8_mut, Chars, CharIndices, Bytes}; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError}; -#[unstable(feature = "str_box_extras", issue = "41119")] -pub use alloc::str::from_boxed_utf8_unchecked; -#[stable(feature = "rust1", since = "1.0.0")] -pub use std_unicode::str::SplitWhitespace; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::str::pattern; - - -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] -impl> SliceConcatExt for [S] { - type Output = String; - - fn concat(&self) -> String { - if self.is_empty() { - return String::new(); - } - - // `len` calculation may overflow but push_str will check boundaries - let len = self.iter().map(|s| s.borrow().len()).sum(); - let mut result = String::with_capacity(len); - - for s in self { - result.push_str(s.borrow()) - } - - result - } - - fn join(&self, sep: &str) -> String { - if self.is_empty() { - return String::new(); - } - - // concat is faster - if sep.is_empty() { - return self.concat(); - } - - // this is wrong without the guarantee that `self` is non-empty - // `len` calculation may overflow but push_str but will check boundaries - let len = sep.len() * (self.len() - 1) + - self.iter().map(|s| s.borrow().len()).sum::(); - let mut result = String::with_capacity(len); - let mut first = true; - - for s in self { - if first { - first = false; - } else { - result.push_str(sep); - } - result.push_str(s.borrow()); - } - result - } - - fn connect(&self, sep: &str) -> String { - self.join(sep) - } -} - -/// 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> { - encoder: Utf16Encoder>, -} - -#[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 { - self.encoder.next() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.encoder.size_hint() - } -} - -#[unstable(feature = "fused", issue = "35602")] -impl<'a> FusedIterator for EncodeUtf16<'a> {} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Borrow for String { - #[inline] - fn borrow(&self) -> &str { - &self[..] - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ToOwned for str { - type Owned = String; - fn to_owned(&self) -> String { - unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) } - } - - fn clone_into(&self, target: &mut String) { - let mut b = mem::replace(target, String::new()).into_bytes(); - self.as_bytes().clone_into(&mut b); - *target = unsafe { String::from_utf8_unchecked(b) } - } -} - -/// Methods for string slices. -#[lang = "str"] -#[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. - /// - /// # 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. - #[unstable(feature = "str_mut_extras", issue = "41119")] - #[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 - /// - /// ``` - /// # #![feature(str_checked_slicing)] - /// let v = "🗻∈🌏"; - /// assert_eq!(Some("🗻"), v.get(0..4)); - /// assert!(v.get(1..).is_none()); - /// assert!(v.get(..8).is_none()); - /// assert!(v.get(..42).is_none()); - /// ``` - #[unstable(feature = "str_checked_slicing", issue = "39932")] - #[inline] - pub fn get>(&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 - /// - /// ``` - /// # #![feature(str_checked_slicing)] - /// let mut v = String::from("🗻∈🌏"); - /// assert_eq!(Some("🗻"), v.get_mut(0..4).map(|v| &*v)); - /// assert!(v.get_mut(1..).is_none()); - /// assert!(v.get_mut(..8).is_none()); - /// assert!(v.get_mut(..42).is_none()); - /// ``` - #[unstable(feature = "str_checked_slicing", issue = "39932")] - #[inline] - pub fn get_mut>(&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 - /// - /// ``` - /// # #![feature(str_checked_slicing)] - /// let v = "🗻∈🌏"; - /// unsafe { - /// assert_eq!("🗻", v.get_unchecked(0..4)); - /// assert_eq!("∈", v.get_unchecked(4..7)); - /// assert_eq!("🌏", v.get_unchecked(7..11)); - /// } - /// ``` - #[unstable(feature = "str_checked_slicing", issue = "39932")] - #[inline] - pub unsafe fn get_unchecked>(&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 - /// - /// ``` - /// # #![feature(str_checked_slicing)] - /// 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)); - /// } - /// ``` - #[unstable(feature = "str_checked_slicing", issue = "39932")] - #[inline] - pub unsafe fn get_unchecked_mut>(&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); - /// - /// assert_eq!("Per", first); - /// assert_eq!(" Martin-Löf", last); - /// ``` - #[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 y = "y̆"; - /// - /// let mut char_indices = y.char_indices(); - /// - /// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆') - /// assert_eq!(Some((1, '\u{0306}')), 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 { - UnicodeStr::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. - #[stable(feature = "encode_utf16", since = "1.8.0")] - pub fn encode_utf16(&self) -> EncodeUtf16 { - EncodeUtf16 { encoder: Utf16Encoder::new(self[..].chars()) } - } - - /// 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 with 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)); - /// ``` - /// - /// 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 { - 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 - 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 { - UnicodeStr::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 { - UnicodeStr::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 { - UnicodeStr::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_left_matches(|c| c == '1' || c == 'X'), "fooX"); - /// ``` - #[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 - /// - /// # Example - /// - /// Basic usage - /// - /// ``` - /// let four: u32 = "4".parse().unwrap(); - /// - /// assert_eq!(4, four); - /// ``` - /// - /// Using the 'turbofish' instead of annotating `four`: - /// - /// ``` - /// let four = "4".parse::(); - /// - /// assert_eq!(Ok(4), four); - /// ``` - /// - /// Failing to parse: - /// - /// ``` - /// let nope = "j".parse::(); - /// - /// assert!(nope.is_err()); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - pub fn parse(&self) -> Result { - core_str::StrExt::parse(self) - } - - /// Converts a `Box` into a `Box<[u8]>` without copying or allocating. - #[unstable(feature = "str_box_extras", issue = "41119")] - pub fn into_boxed_bytes(self: Box) -> Box<[u8]> { - self.into() - } - - /// Replaces all matches of a pattern with another string. - /// - /// `replace` creates a new [`String`], and copies the data from this string slice into it. - /// While doing so, it attempts to find matches of a pattern. If it finds any, it - /// replaces them with the replacement string slice. - /// - /// [`String`]: string/struct.String.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let s = "this is old"; - /// - /// assert_eq!("this is new", s.replace("old", "new")); - /// ``` - /// - /// When the pattern doesn't match: - /// - /// ``` - /// let s = "this is old"; - /// assert_eq!(s, s.replace("cookie monster", "little lamb")); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String { - let mut result = String::new(); - let mut last_end = 0; - for (start, part) in self.match_indices(from) { - result.push_str(unsafe { self.slice_unchecked(last_end, start) }); - result.push_str(to); - last_end = start + part.len(); - } - result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) }); - result - } - - /// Replaces first N matches of a pattern with another string. - /// - /// `replacen` creates a new [`String`], and copies the data from this string slice into it. - /// While doing so, it attempts to find matches of a pattern. If it finds any, it - /// replaces them with the replacement string slice at most `count` times. - /// - /// [`String`]: string/struct.String.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let s = "foo foo 123 foo"; - /// assert_eq!("new new 123 foo", s.replacen("foo", "new", 2)); - /// assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3)); - /// assert_eq!("foo foo new23 foo", s.replacen(char::is_numeric, "new", 1)); - /// ``` - /// - /// When the pattern doesn't match: - /// - /// ``` - /// let s = "this is old"; - /// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10)); - /// ``` - #[stable(feature = "str_replacen", since = "1.16.0")] - pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String { - // Hope to reduce the times of re-allocation - let mut result = String::with_capacity(32); - let mut last_end = 0; - for (start, part) in self.match_indices(pat).take(count) { - result.push_str(unsafe { self.slice_unchecked(last_end, start) }); - result.push_str(to); - last_end = start + part.len(); - } - result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) }); - result - } - - /// Returns the lowercase equivalent of this string slice, as a new [`String`]. - /// - /// 'Lowercase' is defined according to the terms of the Unicode Derived Core Property - /// `Lowercase`. - /// - /// Since some characters can expand into multiple characters when changing - /// the case, this function returns a [`String`] instead of modifying the - /// parameter in-place. - /// - /// [`String`]: string/struct.String.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let s = "HELLO"; - /// - /// assert_eq!("hello", s.to_lowercase()); - /// ``` - /// - /// A tricky example, with sigma: - /// - /// ``` - /// let sigma = "Σ"; - /// - /// assert_eq!("σ", sigma.to_lowercase()); - /// - /// // but at the end of a word, it's ς, not σ: - /// let odysseus = "ὈΔΥΣΣΕΎΣ"; - /// - /// assert_eq!("ὀδυσσεύς", odysseus.to_lowercase()); - /// ``` - /// - /// Languages without case are not changed: - /// - /// ``` - /// let new_year = "农历新年"; - /// - /// assert_eq!(new_year, new_year.to_lowercase()); - /// ``` - #[stable(feature = "unicode_case_mapping", since = "1.2.0")] - pub fn to_lowercase(&self) -> String { - let mut s = String::with_capacity(self.len()); - for (i, c) in self[..].char_indices() { - if c == 'Σ' { - // Σ maps to σ, except at the end of a word where it maps to ς. - // This is the only conditional (contextual) but language-independent mapping - // in `SpecialCasing.txt`, - // so hard-code it rather than have a generic "condition" mechanism. - // See https://github.com/rust-lang/rust/issues/26035 - map_uppercase_sigma(self, i, &mut s) - } else { - s.extend(c.to_lowercase()); - } - } - return s; - - fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) { - // See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 - // for the definition of `Final_Sigma`. - debug_assert!('Σ'.len_utf8() == 2); - let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) && - !case_ignoreable_then_cased(from[i + 2..].chars()); - to.push_str(if is_word_final { "ς" } else { "σ" }); - } - - fn case_ignoreable_then_cased>(iter: I) -> bool { - use std_unicode::derived_property::{Cased, Case_Ignorable}; - match iter.skip_while(|&c| Case_Ignorable(c)).next() { - Some(c) => Cased(c), - None => false, - } - } - } - - /// Returns the uppercase equivalent of this string slice, as a new [`String`]. - /// - /// 'Uppercase' is defined according to the terms of the Unicode Derived Core Property - /// `Uppercase`. - /// - /// Since some characters can expand into multiple characters when changing - /// the case, this function returns a [`String`] instead of modifying the - /// parameter in-place. - /// - /// [`String`]: string/struct.String.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let s = "hello"; - /// - /// assert_eq!("HELLO", s.to_uppercase()); - /// ``` - /// - /// Scripts without case are not changed: - /// - /// ``` - /// let new_year = "农历新年"; - /// - /// assert_eq!(new_year, new_year.to_uppercase()); - /// ``` - #[stable(feature = "unicode_case_mapping", since = "1.2.0")] - pub fn to_uppercase(&self) -> String { - let mut s = String::with_capacity(self.len()); - s.extend(self.chars().flat_map(|c| c.to_uppercase())); - return s; - } - - /// Escapes each char in `s` with [`char::escape_debug`]. - /// - /// [`char::escape_debug`]: primitive.char.html#method.escape_debug - #[unstable(feature = "str_escape", - reason = "return type may change to be an iterator", - issue = "27791")] - pub fn escape_debug(&self) -> String { - self.chars().flat_map(|c| c.escape_debug()).collect() - } - - /// Escapes each char in `s` with [`char::escape_default`]. - /// - /// [`char::escape_default`]: primitive.char.html#method.escape_default - #[unstable(feature = "str_escape", - reason = "return type may change to be an iterator", - issue = "27791")] - pub fn escape_default(&self) -> String { - self.chars().flat_map(|c| c.escape_default()).collect() - } - - /// Escapes each char in `s` with [`char::escape_unicode`]. - /// - /// [`char::escape_unicode`]: primitive.char.html#method.escape_unicode - #[unstable(feature = "str_escape", - reason = "return type may change to be an iterator", - issue = "27791")] - pub fn escape_unicode(&self) -> String { - self.chars().flat_map(|c| c.escape_unicode()).collect() - } - - /// Converts a [`Box`] into a [`String`] without copying or allocating. - /// - /// [`String`]: string/struct.String.html - /// [`Box`]: boxed/struct.Box.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let string = String::from("birthday gift"); - /// let boxed_str = string.clone().into_boxed_str(); - /// - /// assert_eq!(boxed_str.into_string(), string); - /// ``` - #[stable(feature = "box_str", since = "1.4.0")] - pub fn into_string(self: Box) -> String { - unsafe { - let slice = mem::transmute::, Box<[u8]>>(self); - String::from_utf8_unchecked(slice.into_vec()) - } - } - - /// Create a [`String`] by repeating a string `n` times. - /// - /// [`String`]: string/struct.String.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// assert_eq!("abc".repeat(4), String::from("abcabcabcabc")); - /// ``` - #[stable(feature = "repeat_str", since = "1.16.0")] - pub fn repeat(&self, n: usize) -> String { - let mut s = String::with_capacity(self.len() * n); - s.extend((0..n).map(|_| self)); - s - } -} diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 34aca592b1e95..c374f40097441 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2015,7 +2015,7 @@ mod traits { issue = "32110")] pub trait StrExt { // NB there are no docs here are they're all located on the StrExt trait in - // libcollections, not here. + // liballoc, not here. #[stable(feature = "core", since = "1.6.0")] fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool; diff --git a/src/librustc_data_structures/fnv.rs b/src/librustc_data_structures/fnv.rs index ae90c2fac8321..5bd57236e7c28 100644 --- a/src/librustc_data_structures/fnv.rs +++ b/src/librustc_data_structures/fnv.rs @@ -26,7 +26,7 @@ pub fn FnvHashSet() -> FnvHashSet { } /// A speedy hash algorithm for node ids and def ids. The hashmap in -/// libcollections by default uses SipHash which isn't quite as speedy as we +/// liballoc by default uses SipHash which isn't quite as speedy as we /// want. In the compiler we're not really worried about DOS attempts, so we /// just default to a non-cryptographic hash. /// diff --git a/src/librustc_data_structures/fx.rs b/src/librustc_data_structures/fx.rs index 1fb7673521d88..00dfc1617a8b6 100644 --- a/src/librustc_data_structures/fx.rs +++ b/src/librustc_data_structures/fx.rs @@ -26,7 +26,7 @@ pub fn FxHashSet() -> FxHashSet { HashSet::default() } -/// A speedy hash algorithm for use within rustc. The hashmap in libcollections +/// A speedy hash algorithm for use within rustc. The hashmap in liballoc /// by default uses SipHash which isn't quite as speedy as we want. In the /// compiler we're not really worried about DOS attempts, so we use a fast /// non-cryptographic hash. diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 1a5cf89f96998..87c85a5fc96b8 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -188,16 +188,16 @@ already been imported. Erroneous code example: ```compile_fail,E0254 -extern crate collections; +extern crate alloc; mod foo { - pub trait collections { + pub trait alloc { fn do_something(); } } -use foo::collections; // error: an extern crate named `collections` has already - // been imported in this module +use foo::alloc; // error: an extern crate named `alloc` has already + // been imported in this module fn main() {} ``` @@ -206,15 +206,15 @@ To fix issue issue, you have to rename at least one of the two imports. Example: ```ignore -extern crate collections as libcollections; // ok! +extern crate alloc as liballoc; // ok! mod foo { - pub trait collections { + pub trait alloc { fn do_something(); } } -use foo::collections; +use foo::alloc; fn main() {} ``` @@ -1425,7 +1425,7 @@ Erroneous code example: ```compile_fail,E0469 #[macro_use(drink, be_merry)] // error: imported macro not found -extern crate collections; +extern crate alloc; fn main() { // ... @@ -1467,7 +1467,7 @@ Erroneous code example: ```compile_fail,E0470 #[macro_reexport(drink, be_merry)] -extern crate collections; +extern crate alloc; fn main() { // ... diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 9cdde0797a0c1..f6103a259dcd6 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -2265,8 +2265,8 @@ If `ForeignTrait` is a trait defined in some external crate `foo`, then the following trait `impl` is an error: ```compile_fail,E0210 -extern crate collections; -use collections::range::RangeArgument; +extern crate alloc; +use alloc::range::RangeArgument; impl RangeArgument for T { } // error diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index 05cfb6352fbb8..1a995276931d8 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Implementations of serialization for structures found in libcollections +//! Implementations of serialization for structures found in liballoc use std::hash::{Hash, BuildHasher}; diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 4eb2cad5c91b9..ca27b34d68100 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -28,15 +28,12 @@ Core encoding and decoding interfaces. #![deny(warnings)] #![feature(box_syntax)] -#![feature(collections)] #![feature(core_intrinsics)] #![feature(i128_type)] #![feature(specialization)] #![cfg_attr(stage0, feature(staged_api))] #![cfg_attr(test, feature(test))] -extern crate collections; - pub use self::serialize::{Decoder, Encoder, Decodable, Encodable}; pub use self::serialize::{SpecializationError, SpecializedEncoder, SpecializedDecoder}; diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index b516cbd08ca02..f93af4c192016 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -15,7 +15,6 @@ alloc_jemalloc = { path = "../liballoc_jemalloc", optional = true } alloc_system = { path = "../liballoc_system" } panic_unwind = { path = "../libpanic_unwind", optional = true } panic_abort = { path = "../libpanic_abort" } -collections = { path = "../libcollections" } core = { path = "../libcore" } libc = { path = "../rustc/libc_shim" } rand = { path = "../librand" } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index 506bf717337bd..b8a6a66eaa65d 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -420,15 +420,15 @@ #![stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::Bound; +pub use alloc::Bound; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::{BinaryHeap, BTreeMap, BTreeSet}; +pub use alloc::{BinaryHeap, BTreeMap, BTreeSet}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::{LinkedList, VecDeque}; +pub use alloc::{LinkedList, VecDeque}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::{binary_heap, btree_map, btree_set}; +pub use alloc::{binary_heap, btree_map, btree_set}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::{linked_list, vec_deque}; +pub use alloc::{linked_list, vec_deque}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::hash_map::HashMap; @@ -436,7 +436,7 @@ pub use self::hash_map::HashMap; pub use self::hash_set::HashSet; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::range; +pub use alloc::range; mod hash; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index b0820d6f05a05..f307fbb7c0033 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -254,7 +254,6 @@ #![feature(cfg_target_vendor)] #![feature(char_escape_debug)] #![feature(char_internals)] -#![feature(collections)] #![feature(collections_range)] #![feature(compiler_builtins_lib)] #![feature(const_fn)] @@ -337,11 +336,9 @@ use prelude::v1::*; debug_assert_ne, unreachable, unimplemented, write, writeln, try)] extern crate core as __core; +#[allow(deprecated)] extern crate rand as core_rand; #[macro_use] #[macro_reexport(vec, format)] -extern crate collections as core_collections; - -#[allow(deprecated)] extern crate rand as core_rand; extern crate alloc; extern crate std_unicode; extern crate libc; @@ -430,17 +427,17 @@ pub use alloc::boxed; #[stable(feature = "rust1", since = "1.0.0")] pub use alloc::rc; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::borrow; +pub use alloc::borrow; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::fmt; +pub use alloc::fmt; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::slice; +pub use alloc::slice; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::str; +pub use alloc::str; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::string; +pub use alloc::string; #[stable(feature = "rust1", since = "1.0.0")] -pub use core_collections::vec; +pub use alloc::vec; #[stable(feature = "rust1", since = "1.0.0")] pub use std_unicode::char; #[unstable(feature = "i128", issue = "35118")] diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs index d63878a7a7c24..19f2ad1c56f2d 100644 --- a/src/libstd_unicode/lib.rs +++ b/src/libstd_unicode/lib.rs @@ -52,7 +52,7 @@ pub mod str { pub use u_str::Utf16Encoder; } -// For use in libcollections, not re-exported in libstd. +// For use in liballoc, not re-exported in libstd. pub mod derived_property { pub use tables::derived_property::{Case_Ignorable, Cased}; } diff --git a/src/libstd_unicode/u_str.rs b/src/libstd_unicode/u_str.rs index 1454168d2d5cc..54a5288a57c8b 100644 --- a/src/libstd_unicode/u_str.rs +++ b/src/libstd_unicode/u_str.rs @@ -32,7 +32,7 @@ pub struct SplitWhitespace<'a> { } /// Methods for Unicode string slices -#[allow(missing_docs)] // docs in libcollections +#[allow(missing_docs)] // docs in liballoc pub trait UnicodeStr { fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>; fn is_whitespace(&self) -> bool; diff --git a/src/test/compile-fail/E0254.rs b/src/test/compile-fail/E0254.rs index fe7ee1c129f81..bc17a46a0172a 100644 --- a/src/test/compile-fail/E0254.rs +++ b/src/test/compile-fail/E0254.rs @@ -8,18 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] +#![feature(alloc)] -extern crate collections; -//~^ NOTE previous import of `collections` here +extern crate alloc; +//~^ NOTE previous import of `alloc` here mod foo { - pub trait collections { + pub trait alloc { fn do_something(); } } -use foo::collections; +use foo::alloc; //~^ ERROR E0254 //~| NOTE already imported diff --git a/src/test/compile-fail/E0259.rs b/src/test/compile-fail/E0259.rs index b2129902ef9c3..259d67fe7cd6c 100644 --- a/src/test/compile-fail/E0259.rs +++ b/src/test/compile-fail/E0259.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections, libc)] +#![feature(alloc, libc)] -extern crate collections; -//~^ NOTE previous import of `collections` here +extern crate alloc; +//~^ NOTE previous import of `alloc` here -extern crate libc as collections; +extern crate libc as alloc; //~^ ERROR E0259 -//~| NOTE `collections` already imported +//~| NOTE `alloc` already imported fn main() {} diff --git a/src/test/compile-fail/E0260.rs b/src/test/compile-fail/E0260.rs index ae018d2ada93c..08d78782e4cd7 100644 --- a/src/test/compile-fail/E0260.rs +++ b/src/test/compile-fail/E0260.rs @@ -8,14 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] +#![feature(alloc)] -extern crate collections; -//~^ NOTE previous import of `collections` here +extern crate alloc; +//~^ NOTE previous import of `alloc` here -mod collections { -//~^ ERROR `collections` has already been imported in this module [E0260] -//~| NOTE `collections` already imported +mod alloc { +//~^ ERROR `alloc` has already been imported in this module [E0260] +//~| NOTE `alloc` already imported pub trait MyTrait { fn do_something(); } diff --git a/src/test/compile-fail/lint-unused-extern-crate.rs b/src/test/compile-fail/lint-unused-extern-crate.rs index 40671353f8ac6..010c55afb2b83 100644 --- a/src/test/compile-fail/lint-unused-extern-crate.rs +++ b/src/test/compile-fail/lint-unused-extern-crate.rs @@ -13,13 +13,13 @@ #![deny(unused_extern_crates)] #![allow(unused_variables)] #![allow(deprecated)] +#![feature(alloc)] #![feature(libc)] -#![feature(collections)] #![feature(rand)] extern crate libc; //~ ERROR: unused extern crate -extern crate collections as collecs; // no error, it is used +extern crate alloc as collecs; // no error, it is used extern crate rand; // no error, the use marks it as used // even if imported objects aren't used diff --git a/src/test/compile-fail/resolve_self_super_hint.rs b/src/test/compile-fail/resolve_self_super_hint.rs index 530dc873f7504..d49f136f11f31 100644 --- a/src/test/compile-fail/resolve_self_super_hint.rs +++ b/src/test/compile-fail/resolve_self_super_hint.rs @@ -8,25 +8,25 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] +#![feature(alloc)] mod a { - extern crate collections; - use collections::HashMap; - //~^ ERROR unresolved import `collections::HashMap` [E0432] - //~| Did you mean `self::collections`? + extern crate alloc; + use alloc::HashMap; + //~^ ERROR unresolved import `alloc::HashMap` [E0432] + //~| Did you mean `self::alloc`? mod b { - use collections::HashMap; - //~^ ERROR unresolved import `collections::HashMap` [E0432] - //~| Did you mean `a::collections`? + use alloc::HashMap; + //~^ ERROR unresolved import `alloc::HashMap` [E0432] + //~| Did you mean `a::alloc`? mod c { - use collections::HashMap; - //~^ ERROR unresolved import `collections::HashMap` [E0432] - //~| Did you mean `a::collections`? + use alloc::HashMap; + //~^ ERROR unresolved import `alloc::HashMap` [E0432] + //~| Did you mean `a::alloc`? mod d { - use collections::HashMap; - //~^ ERROR unresolved import `collections::HashMap` [E0432] - //~| Did you mean `a::collections`? + use alloc::HashMap; + //~^ ERROR unresolved import `alloc::HashMap` [E0432] + //~| Did you mean `a::alloc`? } } } diff --git a/src/test/run-pass-fulldeps/issue-2804.rs b/src/test/run-pass-fulldeps/issue-2804.rs index a2b4e218a079b..f999d2d0ed99c 100644 --- a/src/test/run-pass-fulldeps/issue-2804.rs +++ b/src/test/run-pass-fulldeps/issue-2804.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] #![feature(rustc_private)] -extern crate collections; extern crate serialize; use std::collections::HashMap; diff --git a/src/test/run-pass-fulldeps/regions-mock-tcx.rs b/src/test/run-pass-fulldeps/regions-mock-tcx.rs index ed3cec465eff8..670f5380d81fa 100644 --- a/src/test/run-pass-fulldeps/regions-mock-tcx.rs +++ b/src/test/run-pass-fulldeps/regions-mock-tcx.rs @@ -15,10 +15,9 @@ // - Multiple lifetime parameters // - Arenas -#![feature(rustc_private, libc, collections)] +#![feature(rustc_private, libc)] extern crate arena; -extern crate collections; extern crate libc; use TypeStructure::{TypeInt, TypeFunction}; diff --git a/src/test/run-pass/drop-with-type-ascription-2.rs b/src/test/run-pass/drop-with-type-ascription-2.rs index 53005ea5291fd..1f486c1834c06 100644 --- a/src/test/run-pass/drop-with-type-ascription-2.rs +++ b/src/test/run-pass/drop-with-type-ascription-2.rs @@ -9,8 +9,6 @@ // except according to those terms. -#![feature(collections)] - fn main() { let args = vec!["foobie", "asdf::asdf"]; let arr: Vec<&str> = args[1].split("::").collect(); diff --git a/src/test/run-pass/for-loop-no-std.rs b/src/test/run-pass/for-loop-no-std.rs index 73de1fa9c0de5..856857156c940 100644 --- a/src/test/run-pass/for-loop-no-std.rs +++ b/src/test/run-pass/for-loop-no-std.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items, start, collections)] +#![feature(lang_items, start, alloc)] #![no_std] extern crate std as other; -#[macro_use] extern crate collections; +#[macro_use] extern crate alloc; #[start] fn start(_argc: isize, _argv: *const *const u8) -> isize { diff --git a/src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs b/src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs index cedb960143146..232af7eca419b 100644 --- a/src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs +++ b/src/test/run-pass/foreach-external-iterators-hashmap-break-restart.rs @@ -9,10 +9,6 @@ // except according to those terms. -#![feature(collections)] - -extern crate collections; - use std::collections::HashMap; // This is a fancy one: it uses an external iterator established diff --git a/src/test/run-pass/foreach-external-iterators-hashmap.rs b/src/test/run-pass/foreach-external-iterators-hashmap.rs index 79304fce5c166..2ef420187ded2 100644 --- a/src/test/run-pass/foreach-external-iterators-hashmap.rs +++ b/src/test/run-pass/foreach-external-iterators-hashmap.rs @@ -9,10 +9,6 @@ // except according to those terms. -#![feature(collections)] - -extern crate collections; - use std::collections::HashMap; pub fn main() { diff --git a/src/test/run-pass/format-no-std.rs b/src/test/run-pass/format-no-std.rs index 1b9b4ab32ca40..9e8a32185188a 100644 --- a/src/test/run-pass/format-no-std.rs +++ b/src/test/run-pass/format-no-std.rs @@ -10,14 +10,14 @@ // ignore-emscripten missing rust_begin_unwind -#![feature(lang_items, start, collections)] +#![feature(lang_items, start, alloc)] #![no_std] extern crate std as other; -#[macro_use] extern crate collections; +#[macro_use] extern crate alloc; -use collections::string::ToString; +use alloc::string::ToString; #[start] fn start(_argc: isize, _argv: *const *const u8) -> isize { diff --git a/src/test/run-pass/issue-12860.rs b/src/test/run-pass/issue-12860.rs index 5c9ee74472b12..58ce390cac691 100644 --- a/src/test/run-pass/issue-12860.rs +++ b/src/test/run-pass/issue-12860.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] - -extern crate collections; - use std::collections::HashSet; #[derive(Copy, Clone, PartialEq, Eq, Hash)] diff --git a/src/test/run-pass/issue-1696.rs b/src/test/run-pass/issue-1696.rs index 4c6c200c7164e..b06285b06a5e4 100644 --- a/src/test/run-pass/issue-1696.rs +++ b/src/test/run-pass/issue-1696.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] - -extern crate collections; - use std::collections::HashMap; pub fn main() { diff --git a/src/test/run-pass/issue-19811-escape-unicode.rs b/src/test/run-pass/issue-19811-escape-unicode.rs index cff431065ffed..b447ffd69b4c9 100644 --- a/src/test/run-pass/issue-19811-escape-unicode.rs +++ b/src/test/run-pass/issue-19811-escape-unicode.rs @@ -9,8 +9,6 @@ // except according to those terms. -#![feature(collections)] - fn main() { let mut escaped = String::from(""); for c in '\u{10401}'.escape_unicode() { diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs index 9c400aac1dcf1..a497a9fda6a6a 100644 --- a/src/test/run-pass/issue-2383.rs +++ b/src/test/run-pass/issue-2383.rs @@ -10,9 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(collections)] - -extern crate collections; use std::collections::VecDeque; pub fn main() { diff --git a/src/test/run-pass/issue-2804-2.rs b/src/test/run-pass/issue-2804-2.rs index 6afb31619d1ca..e428ecd4e5bb3 100644 --- a/src/test/run-pass/issue-2804-2.rs +++ b/src/test/run-pass/issue-2804-2.rs @@ -11,10 +11,6 @@ // Minimized version of issue-2804.rs. Both check that callee IDs don't // clobber the previous node ID in a macro expr -#![feature(collections)] - -extern crate collections; - use std::collections::HashMap; fn add_interfaces(managed_ip: String, device: HashMap) { diff --git a/src/test/run-pass/issue-3026.rs b/src/test/run-pass/issue-3026.rs index d8499992f94d1..7c0dc8a004890 100644 --- a/src/test/run-pass/issue-3026.rs +++ b/src/test/run-pass/issue-3026.rs @@ -10,10 +10,7 @@ // pretty-expanded FIXME #23616 -#![allow(unknown_features)] -#![feature(box_syntax, collections)] - -extern crate collections; +#![feature(box_syntax)] use std::collections::HashMap; diff --git a/src/test/run-pass/issue-3559.rs b/src/test/run-pass/issue-3559.rs index c2ea24ac6ba99..64f053d9a8c6d 100644 --- a/src/test/run-pass/issue-3559.rs +++ b/src/test/run-pass/issue-3559.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] - -extern crate collections; - use std::collections::HashMap; fn check_strs(actual: &str, expected: &str) -> bool { diff --git a/src/test/run-pass/issue-6128.rs b/src/test/run-pass/issue-6128.rs index 5fb24fe3ef1ac..8725b13789657 100644 --- a/src/test/run-pass/issue-6128.rs +++ b/src/test/run-pass/issue-6128.rs @@ -9,10 +9,7 @@ // except according to those terms. -#![allow(unknown_features)] -#![feature(box_syntax, collections)] - -extern crate collections; +#![feature(box_syntax)] use std::collections::HashMap; diff --git a/src/test/run-pass/issue-7660.rs b/src/test/run-pass/issue-7660.rs index b0ebc6c9cc82b..3f3e11a2ddb02 100644 --- a/src/test/run-pass/issue-7660.rs +++ b/src/test/run-pass/issue-7660.rs @@ -13,10 +13,6 @@ // pretty-expanded FIXME #23616 -#![feature(collections)] - -extern crate collections; - use std::collections::HashMap; struct A(isize, isize); diff --git a/src/test/run-pass/istr.rs b/src/test/run-pass/istr.rs index 3197d7f0160a6..7ebeb79f56669 100644 --- a/src/test/run-pass/istr.rs +++ b/src/test/run-pass/istr.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] - use std::string::String; fn test_stack_assign() { diff --git a/src/test/run-pass/new-unicode-escapes.rs b/src/test/run-pass/new-unicode-escapes.rs index 83c2dadcd2f7c..2c0417576052e 100644 --- a/src/test/run-pass/new-unicode-escapes.rs +++ b/src/test/run-pass/new-unicode-escapes.rs @@ -9,8 +9,6 @@ // except according to those terms. -#![feature(collections)] - pub fn main() { let s = "\u{2603}"; assert_eq!(s, "☃"); diff --git a/src/test/run-pass/option-ext.rs b/src/test/run-pass/option-ext.rs index 03ba6097cd929..c054171ff008a 100644 --- a/src/test/run-pass/option-ext.rs +++ b/src/test/run-pass/option-ext.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] - pub fn main() { let thing = "{{ f }}"; let f = thing.find("{{"); diff --git a/src/test/run-pass/overloaded-autoderef.rs b/src/test/run-pass/overloaded-autoderef.rs index 97da5fc8c09e9..d9ffbe51aa596 100644 --- a/src/test/run-pass/overloaded-autoderef.rs +++ b/src/test/run-pass/overloaded-autoderef.rs @@ -9,7 +9,7 @@ // except according to those terms. #![allow(unknown_features)] -#![feature(box_syntax, collections, core)] +#![feature(box_syntax, core)] use std::cell::RefCell; use std::rc::Rc; diff --git a/src/test/run-pass/overloaded-deref.rs b/src/test/run-pass/overloaded-deref.rs index e2ca880719a8e..9cdf45b485c1b 100644 --- a/src/test/run-pass/overloaded-deref.rs +++ b/src/test/run-pass/overloaded-deref.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] - use std::cell::RefCell; use std::rc::Rc; use std::string::String; diff --git a/src/test/run-pass/sync-send-iterators-in-libcollections.rs b/src/test/run-pass/sync-send-iterators-in-libcollections.rs index ea154590deef0..903532e9bc80a 100644 --- a/src/test/run-pass/sync-send-iterators-in-libcollections.rs +++ b/src/test/run-pass/sync-send-iterators-in-libcollections.rs @@ -9,21 +9,16 @@ // except according to those terms. #![allow(warnings)] -#![feature(collections)] #![feature(drain, collections_bound, btree_range, vecmap)] -extern crate collections; - -use collections::BinaryHeap; -use collections::{BTreeMap, BTreeSet}; -use collections::LinkedList; -use collections::String; -use collections::Vec; -use collections::VecDeque; +use std::collections::BinaryHeap; +use std::collections::{BTreeMap, BTreeSet}; +use std::collections::LinkedList; +use std::collections::VecDeque; use std::collections::HashMap; use std::collections::HashSet; -use collections::Bound::Included; +use std::collections::Bound::Included; use std::mem; fn is_sync(_: T) where T: Sync {} diff --git a/src/test/run-pass/utf8_chars.rs b/src/test/run-pass/utf8_chars.rs index 0a984429fabbf..b54aed79665aa 100644 --- a/src/test/run-pass/utf8_chars.rs +++ b/src/test/run-pass/utf8_chars.rs @@ -9,7 +9,7 @@ // except according to those terms. // -#![feature(collections, core, str_char)] +#![feature(core, str_char)] use std::str; diff --git a/src/test/run-pass/vec-macro-no-std.rs b/src/test/run-pass/vec-macro-no-std.rs index a51ef73226469..5dd551ff51379 100644 --- a/src/test/run-pass/vec-macro-no-std.rs +++ b/src/test/run-pass/vec-macro-no-std.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items, start, libc, collections)] +#![feature(lang_items, start, libc, alloc)] #![no_std] extern crate std as other; @@ -16,9 +16,9 @@ extern crate std as other; extern crate libc; #[macro_use] -extern crate collections; +extern crate alloc; -use collections::vec::Vec; +use alloc::vec::Vec; // Issue #16806 diff --git a/src/test/run-pass/while-prelude-drop.rs b/src/test/run-pass/while-prelude-drop.rs index e4ca5515653cb..39ed4f53cf7e4 100644 --- a/src/test/run-pass/while-prelude-drop.rs +++ b/src/test/run-pass/while-prelude-drop.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(collections)] - use std::string::String; #[derive(PartialEq)] diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 1b55dc792c2e5..3ea2e6313af4c 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -118,15 +118,15 @@ fn check(cache: &mut Cache, return None; } // FIXME(#32553) - if file.ends_with("collections/string/struct.String.html") { + if file.ends_with("string/struct.String.html") { return None; } // FIXME(#32130) if file.ends_with("btree_set/struct.BTreeSet.html") || - file.ends_with("collections/struct.BTreeSet.html") || - file.ends_with("collections/btree_map/struct.BTreeMap.html") || - file.ends_with("collections/hash_map/struct.HashMap.html") || - file.ends_with("collections/hash_set/struct.HashSet.html") { + file.ends_with("struct.BTreeSet.html") || + file.ends_with("btree_map/struct.BTreeMap.html") || + file.ends_with("hash_map/struct.HashMap.html") || + file.ends_with("hash_set/struct.HashSet.html") { return None; }