rust/library/alloc/src/string.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

3053 lines
93 KiB
Rust
Raw Normal View History

2020-10-18 18:17:49 -07:00
//! A UTF-8encoded, growable string.
//!
2020-10-18 18:17:49 -07:00
//! This module contains the [`String`] type, the [`ToString`] trait for
//! converting to strings, and several error types that may result from
//! working with [`String`]s.
//!
//! # Examples
//!
2016-10-10 18:15:55 +02:00
//! There are multiple ways to create a new [`String`] from a string literal:
//!
//! ```
//! let s = "Hello".to_string();
//!
//! let s = String::from("world");
//! let s: String = "also this".into();
//! ```
//!
2016-10-10 18:15:55 +02:00
//! You can create a new [`String`] from an existing one by concatenating with
//! `+`:
//!
//! ```
//! let s = "Hello".to_string();
//!
//! let message = s + " world!";
//! ```
//!
//! If you have a vector of valid UTF-8 bytes, you can make a [`String`] out of
//! it. You can do the reverse too.
//!
//! ```
//! let sparkle_heart = vec![240, 159, 146, 150];
//!
//! // We know these bytes are valid, so we'll use `unwrap()`.
//! let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
//!
//! assert_eq!("💖", sparkle_heart);
//!
//! let bytes = sparkle_heart.into_bytes();
//!
//! assert_eq!(bytes, [240, 159, 146, 150]);
//! ```
2015-01-23 21:48:20 -08:00
#![stable(feature = "rust1", since = "1.0.0")]
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
2022-07-29 18:54:47 +00:00
use core::error::Error;
use core::fmt;
use core::hash;
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2022-08-09 02:14:43 +02:00
use core::iter::from_fn;
use core::iter::FusedIterator;
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
use core::ops::Add;
#[cfg(not(no_global_oom_handling))]
use core::ops::AddAssign;
#[cfg(not(no_global_oom_handling))]
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{self, Range, RangeBounds};
use core::ptr;
use core::slice;
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
use core::str::pattern::Pattern;
2022-08-20 12:49:20 -04:00
#[cfg(not(no_global_oom_handling))]
use core::str::Utf8Chunks;
std: Recreate a `collections` module As with the previous commit with `librand`, this commit shuffles around some `collections` code. The new state of the world is similar to that of librand: * The libcollections crate now only depends on libcore and liballoc. * The standard library has a new module, `std::collections`. All functionality of libcollections is reexported through this module. I would like to stress that this change is purely cosmetic. There are very few alterations to these primitives. There are a number of notable points about the new organization: * std::{str, slice, string, vec} all moved to libcollections. There is no reason that these primitives shouldn't be necessarily usable in a freestanding context that has allocation. These are all reexported in their usual places in the standard library. * The `hashmap`, and transitively the `lru_cache`, modules no longer reside in `libcollections`, but rather in libstd. The reason for this is because the `HashMap::new` contructor requires access to the OSRng for initially seeding the hash map. Beyond this requirement, there is no reason that the hashmap could not move to libcollections. I do, however, have a plan to move the hash map to the collections module. The `HashMap::new` function could be altered to require that the `H` hasher parameter ascribe to the `Default` trait, allowing the entire `hashmap` module to live in libcollections. The key idea would be that the default hasher would be different in libstd. Something along the lines of: // src/libstd/collections/mod.rs pub type HashMap<K, V, H = RandomizedSipHasher> = core_collections::HashMap<K, V, H>; This is not possible today because you cannot invoke static methods through type aliases. If we modified the compiler, however, to allow invocation of static methods through type aliases, then this type definition would essentially be switching the default hasher from `SipHasher` in libcollections to a libstd-defined `RandomizedSipHasher` type. This type's `Default` implementation would randomly seed the `SipHasher` instance, and otherwise perform the same as `SipHasher`. This future state doesn't seem incredibly far off, but until that time comes, the hashmap module will live in libstd to not compromise on functionality. * In preparation for the hashmap moving to libcollections, the `hash` module has moved from libstd to libcollections. A previously snapshotted commit enables a distinct `Writer` trait to live in the `hash` module which `Hash` implementations are now parameterized over. Due to using a custom trait, the `SipHasher` implementation has lost its specialized methods for writing integers. These can be re-added backwards-compatibly in the future via default methods if necessary, but the FNV hashing should satisfy much of the need for speedier hashing. A list of breaking changes: * HashMap::{get, get_mut} no longer fails with the key formatted into the error message with `{:?}`, instead, a generic message is printed. With backtraces, it should still be not-too-hard to track down errors. * The HashMap, HashSet, and LruCache types are now available through std::collections instead of the collections crate. * Manual implementations of hash should be parameterized over `hash::Writer` instead of just `Writer`. [breaking-change]
2014-05-29 18:50:12 -07:00
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
use crate::borrow::{Cow, ToOwned};
use crate::boxed::Box;
use crate::collections::TryReserveError;
2022-10-19 19:07:45 -07:00
use crate::str::{self, from_utf8_unchecked_mut, Chars, Utf8Error};
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
use crate::str::{from_boxed_utf8_unchecked, FromStr};
use crate::vec::Vec;
2020-10-18 18:17:49 -07:00
/// A UTF-8encoded, growable string.
///
/// `String` is the most common string type. It has ownership over the contents
/// of the string, stored in a heap-allocated buffer (see [Representation](#representation)).
/// It is closely related to its borrowed counterpart, the primitive [`str`].
///
/// # Examples
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// You can create a `String` from [a literal string][`&str`] with [`String::from`]:
///
2020-07-18 10:14:00 -07:00
/// [`String::from`]: From::from
///
/// ```
/// let hello = String::from("Hello, world!");
/// ```
///
/// You can append a [`char`] to a `String` with the [`push`] method, and
/// append a [`&str`] with the [`push_str`] method:
///
/// ```
/// let mut hello = String::from("Hello, ");
///
/// hello.push('w');
/// hello.push_str("orld!");
/// ```
///
2020-07-18 10:14:00 -07:00
/// [`push`]: String::push
/// [`push_str`]: String::push_str
///
/// If you have a vector of UTF-8 bytes, you can create a `String` from it with
/// the [`from_utf8`] method:
///
/// ```
/// // some bytes, in a vector
/// let sparkle_heart = vec![240, 159, 146, 150];
///
/// // We know these bytes are valid, so we'll use `unwrap()`.
/// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
///
/// assert_eq!("💖", sparkle_heart);
/// ```
///
2020-07-18 10:14:00 -07:00
/// [`from_utf8`]: String::from_utf8
///
/// # UTF-8
///
/// `String`s are always valid UTF-8. If you need a non-UTF-8 string, consider
/// [`OsString`]. It is similar, but without the UTF-8 constraint. Because UTF-8
/// is a variable width encoding, `String`s are typically smaller than an array of
/// the same `chars`:
///
/// ```
/// use std::mem;
///
/// // `s` is ASCII which represents each `char` as one byte
/// let s = "hello";
/// assert_eq!(s.len(), 5);
///
/// // A `char` array with the same contents would be longer because
/// // every `char` is four bytes
/// let s = ['h', 'e', 'l', 'l', 'o'];
/// let size: usize = s.into_iter().map(|c| mem::size_of_val(&c)).sum();
/// assert_eq!(size, 20);
///
/// // However, for non-ASCII strings, the difference will be smaller
/// // and sometimes they are the same
/// let s = "💖💖💖💖💖";
/// assert_eq!(s.len(), 20);
///
/// let s = ['💖', '💖', '💖', '💖', '💖'];
/// let size: usize = s.into_iter().map(|c| mem::size_of_val(&c)).sum();
/// assert_eq!(size, 20);
/// ```
///
/// This raises interesting questions as to how `s[i]` should work.
/// What should `i` be here? Several options include byte indices and
/// `char` indices but, because of UTF-8 encoding, only byte indices
/// would provide constant time indexing. Getting the `i`th `char`, for
/// example, is available using [`chars`]:
///
/// ```
/// let s = "hello";
/// let third_character = s.chars().nth(2);
/// assert_eq!(third_character, Some('l'));
///
/// let s = "💖💖💖💖💖";
/// let third_character = s.chars().nth(2);
/// assert_eq!(third_character, Some('💖'));
/// ```
///
/// Next, what should `s[i]` return? Because indexing returns a reference
/// to underlying data it could be `&u8`, `&[u8]`, or something else similar.
/// Since we're only providing one index, `&u8` makes the most sense but that
/// might not be what the user expects and can be explicitly achieved with
/// [`as_bytes()`]:
///
/// ```
/// // The first byte is 104 - the byte value of `'h'`
/// let s = "hello";
/// assert_eq!(s.as_bytes()[0], 104);
/// // or
/// assert_eq!(s.as_bytes()[0], b'h');
///
/// // The first byte is 240 which isn't obviously useful
/// let s = "💖💖💖💖💖";
/// assert_eq!(s.as_bytes()[0], 240);
/// ```
///
/// Due to these ambiguities/restrictions, indexing with a `usize` is simply
/// forbidden:
///
/// ```compile_fail,E0277
/// let s = "hello";
///
/// // The following will not compile!
/// println!("The first letter of s is {}", s[0]);
/// ```
///
/// It is more clear, however, how `&s[i..j]` should work (that is,
/// indexing with a range). It should accept byte indices (to be constant-time)
/// and return a `&str` which is UTF-8 encoded. This is also called "string slicing".
/// Note this will panic if the byte indices provided are not character
/// boundaries - see [`is_char_boundary`] for more details. See the implementations
/// for [`SliceIndex<str>`] for more details on string slicing. For a non-panicking
/// version of string slicing, see [`get`].
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`OsString`]: ../../std/ffi/struct.OsString.html "ffi::OsString"
/// [`SliceIndex<str>`]: core::slice::SliceIndex
/// [`as_bytes()`]: str::as_bytes
/// [`get`]: str::get
/// [`is_char_boundary`]: str::is_char_boundary
///
/// The [`bytes`] and [`chars`] methods return iterators over the bytes and
/// codepoints of the string, respectively. To iterate over codepoints along
/// with byte indices, use [`char_indices`].
///
2020-07-18 10:14:00 -07:00
/// [`bytes`]: str::bytes
/// [`chars`]: str::chars
/// [`char_indices`]: str::char_indices
///
/// # Deref
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// `String` implements <code>[Deref]<Target = [str]></code>, and so inherits all of [`str`]'s
/// methods. In addition, this means that you can pass a `String` to a
/// function which takes a [`&str`] by using an ampersand (`&`):
///
/// ```
/// fn takes_str(s: &str) { }
///
/// let s = String::from("Hello");
///
/// takes_str(&s);
/// ```
///
/// This will create a [`&str`] from the `String` and pass it in. This
/// conversion is very inexpensive, and so generally, functions will accept
/// [`&str`]s as arguments unless they need a `String` for some specific
/// reason.
///
2017-08-07 13:56:20 -04:00
/// In certain cases Rust doesn't have enough information to make this
/// conversion, known as [`Deref`] coercion. In the following example a string
/// slice [`&'a str`][`&str`] implements the trait `TraitExample`, and the function
2017-08-07 13:56:20 -04:00
/// `example_func` takes anything that implements the trait. In this case Rust
/// would need to make two implicit conversions, which Rust doesn't have the
/// means to do. For that reason, the following example will not compile.
///
/// ```compile_fail,E0277
/// trait TraitExample {}
///
/// impl<'a> TraitExample for &'a str {}
///
/// fn example_func<A: TraitExample>(example_arg: A) {}
///
/// let example_string = String::from("example_string");
/// example_func(&example_string);
/// ```
///
/// There are two options that would work instead. The first would be to
/// change the line `example_func(&example_string);` to
/// `example_func(example_string.as_str());`, using the method [`as_str()`]
/// to explicitly extract the string slice containing the string. The second
/// way changes `example_func(&example_string);` to
/// `example_func(&*example_string);`. In this case we are dereferencing a
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// `String` to a [`str`], then referencing the [`str`] back to
/// [`&str`]. The second way is more idiomatic, however both work to do the
/// conversion explicitly rather than relying on the implicit conversion.
///
/// # Representation
///
/// A `String` is made up of three components: a pointer to some bytes, a
2024-03-24 12:20:39 -07:00
/// length, and a capacity. The pointer points to the internal buffer which `String`
/// uses to store its data. The length is the number of bytes currently stored
/// in the buffer, and the capacity is the size of the buffer in bytes. As such,
/// the length will always be less than or equal to the capacity.
///
/// This buffer is always stored on the heap.
///
/// You can look at these with the [`as_ptr`], [`len`], and [`capacity`]
/// methods:
///
/// ```
/// use std::mem;
///
/// let story = String::from("Once upon a time...");
///
2019-10-22 12:48:52 -04:00
// FIXME Update this when vec_into_raw_parts is stabilized
/// // Prevent automatically dropping the String's data
/// let mut story = mem::ManuallyDrop::new(story);
///
2019-10-22 13:54:09 -04:00
/// let ptr = story.as_mut_ptr();
/// let len = story.len();
/// let capacity = story.capacity();
///
/// // story has nineteen bytes
/// assert_eq!(19, len);
///
/// // We can re-build a String out of ptr, len, and capacity. This is all
2016-02-09 11:52:39 -05:00
/// // unsafe because we are responsible for making sure the components are
/// // valid:
2019-10-22 13:54:09 -04:00
/// let s = unsafe { String::from_raw_parts(ptr, len, capacity) } ;
///
/// assert_eq!(String::from("Once upon a time..."), s);
/// ```
///
2020-07-18 10:14:00 -07:00
/// [`as_ptr`]: str::as_ptr
/// [`len`]: String::len
/// [`capacity`]: String::capacity
///
/// If a `String` has enough capacity, adding elements to it will not
/// re-allocate. For example, consider this program:
///
/// ```
/// let mut s = String::new();
///
/// println!("{}", s.capacity());
///
/// for _ in 0..5 {
/// s.push_str("hello");
/// println!("{}", s.capacity());
/// }
/// ```
///
/// This will output the following:
///
/// ```text
/// 0
/// 8
/// 16
/// 16
/// 32
/// 32
/// ```
///
/// At first, we have no memory allocated at all, but as we append to the
/// string, it increases its capacity appropriately. If we instead use the
/// [`with_capacity`] method to allocate the correct capacity initially:
///
/// ```
/// let mut s = String::with_capacity(25);
///
/// println!("{}", s.capacity());
///
/// for _ in 0..5 {
/// s.push_str("hello");
/// println!("{}", s.capacity());
/// }
/// ```
///
2020-07-18 10:14:00 -07:00
/// [`with_capacity`]: String::with_capacity
///
/// We end up with a different output:
///
/// ```text
/// 25
/// 25
/// 25
/// 25
/// 25
/// 25
/// ```
///
/// Here, there's no need to allocate more memory inside the loop.
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [str]: prim@str "str"
/// [`str`]: prim@str "str"
/// [`&str`]: prim@str "&str"
/// [Deref]: core::ops::Deref "ops::Deref"
/// [`Deref`]: core::ops::Deref "ops::Deref"
2020-07-18 10:14:00 -07:00
/// [`as_str()`]: String::as_str
#[derive(PartialEq, PartialOrd, Eq, Ord)]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2022-12-15 09:52:32 +01:00
#[cfg_attr(not(test), lang = "String")]
pub struct String {
vec: Vec<u8>,
}
/// A possible error value when converting a `String` from a UTF-8 byte vector.
///
/// This type is the error type for the [`from_utf8`] method on [`String`]. It
/// is designed in such a way to carefully avoid reallocations: the
/// [`into_bytes`] method will give back the byte vector that was used in the
/// conversion attempt.
///
2020-07-18 10:14:00 -07:00
/// [`from_utf8`]: String::from_utf8
/// [`into_bytes`]: FromUtf8Error::into_bytes
///
/// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
/// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
/// an analogue to `FromUtf8Error`, and you can get one from a `FromUtf8Error`
/// through the [`utf8_error`] method.
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`Utf8Error`]: str::Utf8Error "std::str::Utf8Error"
/// [`std::str`]: core::str "std::str"
/// [`&str`]: prim@str "&str"
/// [`utf8_error`]: FromUtf8Error::utf8_error
///
/// # Examples
///
/// ```
/// // some invalid bytes, in a vector
/// let bytes = vec![0, 159];
///
/// let value = String::from_utf8(bytes);
///
/// assert!(value.is_err());
/// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes());
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg_attr(not(no_global_oom_handling), derive(Clone))]
#[derive(Debug, PartialEq, Eq)]
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
pub struct FromUtf8Error {
bytes: Vec<u8>,
error: Utf8Error,
}
/// A possible error value when converting a `String` from a UTF-16 byte slice.
///
/// This type is the error type for the [`from_utf16`] method on [`String`].
///
2020-07-18 10:14:00 -07:00
/// [`from_utf16`]: String::from_utf16
///
/// # Examples
///
/// ```
/// // 𝄞mu<invalid>ic
/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
/// 0xD800, 0x0069, 0x0063];
///
/// assert!(String::from_utf16(v).is_err());
/// ```
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-28 08:34:18 -05:00
#[derive(Debug)]
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
pub struct FromUtf16Error(());
impl String {
/// Creates a new empty `String`.
///
/// Given that the `String` is empty, this will not allocate any initial
/// buffer. While that means that this initial operation is very
/// inexpensive, it may cause excessive allocation later when you add
/// data. If you have an idea of how much data the `String` will hold,
/// consider the [`with_capacity`] method to prevent excessive
/// re-allocation.
///
2020-07-18 10:14:00 -07:00
/// [`with_capacity`]: String::with_capacity
///
/// # Examples
///
/// ```
/// let s = String::new();
/// ```
#[inline]
2021-03-12 13:45:13 +00:00
#[rustc_const_stable(feature = "const_string_new", since = "1.39.0")]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2021-10-10 01:50:06 -04:00
#[must_use]
2018-05-05 16:34:43 +08:00
pub const fn new() -> String {
2015-11-24 11:23:48 +13:00
String { vec: Vec::new() }
}
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// Creates a new empty `String` with at least the specified capacity.
///
/// `String`s have an internal buffer to hold their data. The capacity is
/// the length of that buffer, and can be queried with the [`capacity`]
/// method. This method creates an empty `String`, but one with an initial
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// buffer that can hold at least `capacity` bytes. This is useful when you
/// may be appending a bunch of data to the `String`, reducing the number of
/// reallocations it needs to do.
///
2020-07-18 10:14:00 -07:00
/// [`capacity`]: String::capacity
///
/// If the given capacity is `0`, no allocation will occur, and this method
/// is identical to the [`new`] method.
///
2020-07-18 10:14:00 -07:00
/// [`new`]: String::new
///
/// # Examples
///
/// ```
/// let mut s = String::with_capacity(10);
///
/// // The String contains no chars, even though it has capacity for more
/// assert_eq!(s.len(), 0);
///
/// // These are all done without reallocating...
/// let cap = s.capacity();
/// for _ in 0..10 {
/// s.push('a');
/// }
///
/// assert_eq!(s.capacity(), cap);
///
/// // ...but this may make the string reallocate
/// s.push('a');
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2021-10-10 01:50:06 -04:00
#[must_use]
2015-02-04 21:17:19 -05:00
pub fn with_capacity(capacity: usize) -> String {
2015-11-24 11:23:48 +13:00
String { vec: Vec::with_capacity(capacity) }
}
/// Creates a new empty `String` with at least the specified capacity.
///
/// # Errors
///
/// Returns [`Err`] if the capacity exceeds `isize::MAX` bytes,
/// or if the memory allocator reports failure.
///
#[inline]
#[unstable(feature = "try_with_capacity", issue = "91913")]
pub fn try_with_capacity(capacity: usize) -> Result<String, TryReserveError> {
Ok(String { vec: Vec::try_with_capacity(capacity)? })
}
2015-03-18 09:36:18 -07:00
// HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
// required for this method definition, is not available. Since we don't
// require this method for testing purposes, I'll just stub it
// NB see the slice::hack module in slice.rs for more information
2015-03-11 19:44:02 -05:00
#[inline]
#[cfg(test)]
pub fn from_str(_: &str) -> String {
panic!("not available with cfg(test)");
2015-03-11 19:44:02 -05:00
}
/// Converts a vector of bytes to a `String`.
///
/// A string ([`String`]) is made of bytes ([`u8`]), and a vector of bytes
/// ([`Vec<u8>`]) is made of bytes, so this function converts between the
/// two. Not all byte slices are valid `String`s, however: `String`
/// requires that it is valid UTF-8. `from_utf8()` checks to ensure that
/// the bytes are valid UTF-8, and then does the conversion.
///
/// If you are sure that the byte slice is valid UTF-8, and you don't want
/// to incur the overhead of the validity check, there is an unsafe version
/// of this function, [`from_utf8_unchecked`], which has the same behavior
/// but skips the check.
///
/// This method will take care to not copy the vector, for efficiency's
/// sake.
///
/// If you need a [`&str`] instead of a `String`, consider
/// [`str::from_utf8`].
///
/// The inverse of this method is [`into_bytes`].
///
/// # Errors
std: Stabilize the std::str module This commit starts out by consolidating all `str` extension traits into one `StrExt` trait to be included in the prelude. This means that `UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into one `StrExt` exported by the standard library. Some functionality is currently duplicated with the `StrExt` present in libcore. This commit also currently avoids any methods which require any form of pattern to operate. These functions will be stabilized via a separate RFC. Next, stability of methods and structures are as follows: Stable * from_utf8_unchecked * CowString - after moving to std::string * StrExt::as_bytes * StrExt::as_ptr * StrExt::bytes/Bytes - also made a struct instead of a typedef * StrExt::char_indices/CharIndices - CharOffsets was renamed * StrExt::chars/Chars * StrExt::is_empty * StrExt::len * StrExt::lines/Lines * StrExt::lines_any/LinesAny * StrExt::slice_unchecked * StrExt::trim * StrExt::trim_left * StrExt::trim_right * StrExt::words/Words - also made a struct instead of a typedef Unstable * from_utf8 - the error type was changed to a `Result`, but the error type has yet to prove itself * from_c_str - this function will be handled by the c_str RFC * FromStr - this trait will have an associated error type eventually * StrExt::escape_default - needs iterators at least, unsure if it should make the cut * StrExt::escape_unicode - needs iterators at least, unsure if it should make the cut * StrExt::slice_chars - this function has yet to prove itself * StrExt::slice_shift_char - awaiting conventions about slicing and shifting * StrExt::graphemes/Graphemes - this functionality may only be in libunicode * StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in libunicode * StrExt::width - this functionality may only be in libunicode * StrExt::utf16_units - this functionality may only be in libunicode * StrExt::nfd_chars - this functionality may only be in libunicode * StrExt::nfkd_chars - this functionality may only be in libunicode * StrExt::nfc_chars - this functionality may only be in libunicode * StrExt::nfkc_chars - this functionality may only be in libunicode * StrExt::is_char_boundary - naming is uncertain with container conventions * StrExt::char_range_at - naming is uncertain with container conventions * StrExt::char_range_at_reverse - naming is uncertain with container conventions * StrExt::char_at - naming is uncertain with container conventions * StrExt::char_at_reverse - naming is uncertain with container conventions * StrVector::concat - this functionality may be replaced with iterators, but it's not certain at this time * StrVector::connect - as with concat, may be deprecated in favor of iterators Deprecated * StrAllocating and UnicodeStrPrelude have been merged into StrExit * eq_slice - compiler implementation detail * from_str - use the inherent parse() method * is_utf8 - call from_utf8 instead * replace - call the method instead * truncate_utf16_at_nul - this is an implementation detail of windows and does not need to be exposed. * utf8_char_width - moved to libunicode * utf16_items - moved to libunicode * is_utf16 - moved to libunicode * Utf16Items - moved to libunicode * Utf16Item - moved to libunicode * Utf16Encoder - moved to libunicode * AnyLines - renamed to LinesAny and made a struct * SendStr - use CowString<'static> instead * str::raw - all functionality is deprecated * StrExt::into_string - call to_string() instead * StrExt::repeat - use iterators instead * StrExt::char_len - use .chars().count() instead * StrExt::is_alphanumeric - use .chars().all(..) * StrExt::is_whitespace - use .chars().all(..) Pending deprecation -- while slicing syntax is being worked out, these methods are all #[unstable] * Str - while currently used for generic programming, this trait will be replaced with one of [], deref coercions, or a generic conversion trait. * StrExt::slice - use slicing syntax instead * StrExt::slice_to - use slicing syntax instead * StrExt::slice_from - use slicing syntax instead * StrExt::lev_distance - deprecated with no replacement Awaiting stabilization due to patterns and/or matching * StrExt::contains * StrExt::contains_char * StrExt::split * StrExt::splitn * StrExt::split_terminator * StrExt::rsplitn * StrExt::match_indices * StrExt::split_str * StrExt::starts_with * StrExt::ends_with * StrExt::trim_chars * StrExt::trim_left_chars * StrExt::trim_right_chars * StrExt::find * StrExt::rfind * StrExt::find_str * StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
///
/// Returns [`Err`] if the slice is not UTF-8 with a description as to why the
/// provided bytes are not UTF-8. The vector you moved in is also included.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// // some bytes, in a vector
/// let sparkle_heart = vec![240, 159, 146, 150];
///
/// // We know these bytes are valid, so we'll use `unwrap()`.
/// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
///
/// assert_eq!("💖", sparkle_heart);
/// ```
///
/// Incorrect bytes:
///
/// ```
/// // some invalid bytes, in a vector
/// let sparkle_heart = vec![0, 159, 146, 150];
///
/// assert!(String::from_utf8(sparkle_heart).is_err());
/// ```
///
/// See the docs for [`FromUtf8Error`] for more details on what you can do
/// with this error.
///
2020-07-18 10:14:00 -07:00
/// [`from_utf8_unchecked`]: String::from_utf8_unchecked
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`Vec<u8>`]: crate::vec::Vec "Vec"
/// [`&str`]: prim@str "&str"
2020-07-18 10:14:00 -07:00
/// [`into_bytes`]: String::into_bytes
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
match str::from_utf8(&vec) {
2018-11-06 15:05:44 -05:00
Ok(..) => Ok(String { vec }),
2015-11-24 11:23:48 +13:00
Err(e) => Err(FromUtf8Error { bytes: vec, error: e }),
}
}
/// Converts a slice of bytes to a string, including invalid characters.
///
/// Strings are made of bytes ([`u8`]), and a slice of bytes
/// ([`&[u8]`][byteslice]) is made of bytes, so this function converts
/// between the two. Not all byte slices are valid strings, however: strings
/// are required to be valid UTF-8. During this conversion,
/// `from_utf8_lossy()` will replace any invalid UTF-8 sequences with
/// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD], which looks like this: <20>
///
/// [byteslice]: prim@slice
2020-07-18 10:14:00 -07:00
/// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
///
/// If you are sure that the byte slice is valid UTF-8, and you don't want
/// to incur the overhead of the conversion, there is an unsafe version
/// of this function, [`from_utf8_unchecked`], which has the same behavior
/// but skips the checks.
///
2020-07-18 10:14:00 -07:00
/// [`from_utf8_unchecked`]: String::from_utf8_unchecked
///
/// This function returns a [`Cow<'a, str>`]. If our byte slice is invalid
/// UTF-8, then we need to insert the replacement characters, which will
/// change the size of the string, and hence, require a `String`. But if
/// it's already valid UTF-8, we don't need a new allocation. This return
/// type allows us to handle both cases.
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`Cow<'a, str>`]: crate::borrow::Cow "borrow::Cow"
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// // some bytes, in a vector
/// let sparkle_heart = vec![240, 159, 146, 150];
///
/// let sparkle_heart = String::from_utf8_lossy(&sparkle_heart);
///
/// assert_eq!("💖", sparkle_heart);
/// ```
///
/// Incorrect bytes:
///
/// ```
/// // some invalid bytes
/// let input = b"Hello \xF0\x90\x80World";
2014-07-04 22:38:13 +02:00
/// let output = String::from_utf8_lossy(input);
///
/// assert_eq!("Hello <20>World", output);
/// ```
#[must_use]
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2019-06-25 19:43:18 +02:00
pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> {
2022-08-20 12:49:20 -04:00
let mut iter = Utf8Chunks::new(v);
let first_valid = if let Some(chunk) = iter.next() {
2022-08-20 12:49:20 -04:00
let valid = chunk.valid();
if chunk.invalid().is_empty() {
debug_assert_eq!(valid.len(), v.len());
return Cow::Borrowed(valid);
}
valid
} else {
return Cow::Borrowed("");
};
const REPLACEMENT: &str = "\u{FFFD}";
let mut res = String::with_capacity(v.len());
res.push_str(first_valid);
res.push_str(REPLACEMENT);
2022-08-20 12:49:20 -04:00
for chunk in iter {
res.push_str(chunk.valid());
if !chunk.invalid().is_empty() {
res.push_str(REPLACEMENT);
}
}
std: Stabilize the std::str module This commit starts out by consolidating all `str` extension traits into one `StrExt` trait to be included in the prelude. This means that `UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into one `StrExt` exported by the standard library. Some functionality is currently duplicated with the `StrExt` present in libcore. This commit also currently avoids any methods which require any form of pattern to operate. These functions will be stabilized via a separate RFC. Next, stability of methods and structures are as follows: Stable * from_utf8_unchecked * CowString - after moving to std::string * StrExt::as_bytes * StrExt::as_ptr * StrExt::bytes/Bytes - also made a struct instead of a typedef * StrExt::char_indices/CharIndices - CharOffsets was renamed * StrExt::chars/Chars * StrExt::is_empty * StrExt::len * StrExt::lines/Lines * StrExt::lines_any/LinesAny * StrExt::slice_unchecked * StrExt::trim * StrExt::trim_left * StrExt::trim_right * StrExt::words/Words - also made a struct instead of a typedef Unstable * from_utf8 - the error type was changed to a `Result`, but the error type has yet to prove itself * from_c_str - this function will be handled by the c_str RFC * FromStr - this trait will have an associated error type eventually * StrExt::escape_default - needs iterators at least, unsure if it should make the cut * StrExt::escape_unicode - needs iterators at least, unsure if it should make the cut * StrExt::slice_chars - this function has yet to prove itself * StrExt::slice_shift_char - awaiting conventions about slicing and shifting * StrExt::graphemes/Graphemes - this functionality may only be in libunicode * StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in libunicode * StrExt::width - this functionality may only be in libunicode * StrExt::utf16_units - this functionality may only be in libunicode * StrExt::nfd_chars - this functionality may only be in libunicode * StrExt::nfkd_chars - this functionality may only be in libunicode * StrExt::nfc_chars - this functionality may only be in libunicode * StrExt::nfkc_chars - this functionality may only be in libunicode * StrExt::is_char_boundary - naming is uncertain with container conventions * StrExt::char_range_at - naming is uncertain with container conventions * StrExt::char_range_at_reverse - naming is uncertain with container conventions * StrExt::char_at - naming is uncertain with container conventions * StrExt::char_at_reverse - naming is uncertain with container conventions * StrVector::concat - this functionality may be replaced with iterators, but it's not certain at this time * StrVector::connect - as with concat, may be deprecated in favor of iterators Deprecated * StrAllocating and UnicodeStrPrelude have been merged into StrExit * eq_slice - compiler implementation detail * from_str - use the inherent parse() method * is_utf8 - call from_utf8 instead * replace - call the method instead * truncate_utf16_at_nul - this is an implementation detail of windows and does not need to be exposed. * utf8_char_width - moved to libunicode * utf16_items - moved to libunicode * is_utf16 - moved to libunicode * Utf16Items - moved to libunicode * Utf16Item - moved to libunicode * Utf16Encoder - moved to libunicode * AnyLines - renamed to LinesAny and made a struct * SendStr - use CowString<'static> instead * str::raw - all functionality is deprecated * StrExt::into_string - call to_string() instead * StrExt::repeat - use iterators instead * StrExt::char_len - use .chars().count() instead * StrExt::is_alphanumeric - use .chars().all(..) * StrExt::is_whitespace - use .chars().all(..) Pending deprecation -- while slicing syntax is being worked out, these methods are all #[unstable] * Str - while currently used for generic programming, this trait will be replaced with one of [], deref coercions, or a generic conversion trait. * StrExt::slice - use slicing syntax instead * StrExt::slice_to - use slicing syntax instead * StrExt::slice_from - use slicing syntax instead * StrExt::lev_distance - deprecated with no replacement Awaiting stabilization due to patterns and/or matching * StrExt::contains * StrExt::contains_char * StrExt::split * StrExt::splitn * StrExt::split_terminator * StrExt::rsplitn * StrExt::match_indices * StrExt::split_str * StrExt::starts_with * StrExt::ends_with * StrExt::trim_chars * StrExt::trim_left_chars * StrExt::trim_right_chars * StrExt::find * StrExt::rfind * StrExt::find_str * StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
Cow::Owned(res)
}
2020-10-18 18:17:49 -07:00
/// Decode a UTF-16encoded vector `v` into a `String`, returning [`Err`]
/// if `v` contains any invalid data.
///
/// # Examples
///
/// ```
2014-07-04 22:38:13 +02:00
/// // 𝄞music
/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
/// 0x0073, 0x0069, 0x0063];
/// assert_eq!(String::from("𝄞music"),
/// String::from_utf16(v).unwrap());
///
2014-07-04 22:38:13 +02:00
/// // 𝄞mu<invalid>ic
/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
/// 0xD800, 0x0069, 0x0063];
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
/// assert!(String::from_utf16(v).is_err());
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error> {
2018-11-21 10:17:54 +01:00
// This isn't done via collect::<Result<_, _>>() for performance reasons.
// FIXME: the function can be simplified again when #48994 is closed.
2018-10-31 10:22:22 +01:00
let mut ret = String::with_capacity(v.len());
for c in char::decode_utf16(v.iter().cloned()) {
2018-10-31 10:22:22 +01:00
if let Ok(c) = c {
ret.push(c);
} else {
return Err(FromUtf16Error(()));
}
}
Ok(ret)
}
2020-10-18 18:17:49 -07:00
/// Decode a UTF-16encoded slice `v` into a `String`, replacing
/// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
///
/// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
/// `from_utf16_lossy` returns a `String` since the UTF-16 to UTF-8
/// conversion requires a memory allocation.
///
2020-07-18 10:14:00 -07:00
/// [`from_utf8_lossy`]: String::from_utf8_lossy
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`Cow<'a, str>`]: crate::borrow::Cow "borrow::Cow"
2020-07-18 10:14:00 -07:00
/// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
///
/// # Examples
///
/// ```
2014-07-04 22:38:13 +02:00
/// // 𝄞mus<invalid>ic<invalid>
2014-11-17 21:39:01 +13:00
/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
/// 0x0073, 0xDD1E, 0x0069, 0x0063,
/// 0xD834];
///
/// assert_eq!(String::from("𝄞mus\u{FFFD}ic\u{FFFD}"),
/// String::from_utf16_lossy(v));
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[must_use]
2015-01-10 11:07:14 +01:00
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_utf16_lossy(v: &[u16]) -> String {
char::decode_utf16(v.iter().cloned())
.map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
.collect()
}
2022-04-12 02:43:35 -05:00
/// Decode a UTF-16LEencoded vector `v` into a `String`, returning [`Err`]
/// if `v` contains any invalid data.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(str_from_utf16_endian)]
/// // 𝄞music
/// let v = &[0x34, 0xD8, 0x1E, 0xDD, 0x6d, 0x00, 0x75, 0x00,
/// 0x73, 0x00, 0x69, 0x00, 0x63, 0x00];
/// assert_eq!(String::from("𝄞music"),
/// String::from_utf16le(v).unwrap());
///
/// // 𝄞mu<invalid>ic
/// let v = &[0x34, 0xD8, 0x1E, 0xDD, 0x6d, 0x00, 0x75, 0x00,
/// 0x00, 0xD8, 0x69, 0x00, 0x63, 0x00];
/// assert!(String::from_utf16le(v).is_err());
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "str_from_utf16_endian", issue = "116258")]
2022-04-12 02:43:35 -05:00
pub fn from_utf16le(v: &[u8]) -> Result<String, FromUtf16Error> {
if v.len() % 2 != 0 {
return Err(FromUtf16Error(()));
}
match (cfg!(target_endian = "little"), unsafe { v.align_to::<u16>() }) {
(true, ([], v, [])) => Self::from_utf16(v),
2023-09-29 00:04:57 -04:00
_ => char::decode_utf16(v.array_chunks::<2>().copied().map(u16::from_le_bytes))
2022-04-12 02:43:35 -05:00
.collect::<Result<_, _>>()
.map_err(|_| FromUtf16Error(())),
}
}
/// Decode a UTF-16LEencoded slice `v` into a `String`, replacing
/// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
///
/// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
/// `from_utf16le_lossy` returns a `String` since the UTF-16 to UTF-8
/// conversion requires a memory allocation.
///
/// [`from_utf8_lossy`]: String::from_utf8_lossy
/// [`Cow<'a, str>`]: crate::borrow::Cow "borrow::Cow"
/// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(str_from_utf16_endian)]
/// // 𝄞mus<invalid>ic<invalid>
/// let v = &[0x34, 0xD8, 0x1E, 0xDD, 0x6d, 0x00, 0x75, 0x00,
/// 0x73, 0x00, 0x1E, 0xDD, 0x69, 0x00, 0x63, 0x00,
/// 0x34, 0xD8];
///
/// assert_eq!(String::from("𝄞mus\u{FFFD}ic\u{FFFD}"),
/// String::from_utf16le_lossy(v));
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "str_from_utf16_endian", issue = "116258")]
2022-04-12 02:43:35 -05:00
pub fn from_utf16le_lossy(v: &[u8]) -> String {
match (cfg!(target_endian = "little"), unsafe { v.align_to::<u16>() }) {
(true, ([], v, [])) => Self::from_utf16_lossy(v),
(true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}",
2022-04-12 02:43:35 -05:00
_ => {
let mut iter = v.array_chunks::<2>();
2023-09-29 00:04:57 -04:00
let string = char::decode_utf16(iter.by_ref().copied().map(u16::from_le_bytes))
.map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
2022-04-12 02:43:35 -05:00
.collect();
if iter.remainder().is_empty() { string } else { string + "\u{FFFD}" }
}
}
}
/// Decode a UTF-16BEencoded vector `v` into a `String`, returning [`Err`]
/// if `v` contains any invalid data.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(str_from_utf16_endian)]
/// // 𝄞music
/// let v = &[0xD8, 0x34, 0xDD, 0x1E, 0x00, 0x6d, 0x00, 0x75,
/// 0x00, 0x73, 0x00, 0x69, 0x00, 0x63];
/// assert_eq!(String::from("𝄞music"),
/// String::from_utf16be(v).unwrap());
///
/// // 𝄞mu<invalid>ic
/// let v = &[0xD8, 0x34, 0xDD, 0x1E, 0x00, 0x6d, 0x00, 0x75,
/// 0xD8, 0x00, 0x00, 0x69, 0x00, 0x63];
/// assert!(String::from_utf16be(v).is_err());
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "str_from_utf16_endian", issue = "116258")]
2022-04-12 02:43:35 -05:00
pub fn from_utf16be(v: &[u8]) -> Result<String, FromUtf16Error> {
if v.len() % 2 != 0 {
return Err(FromUtf16Error(()));
}
match (cfg!(target_endian = "big"), unsafe { v.align_to::<u16>() }) {
(true, ([], v, [])) => Self::from_utf16(v),
2023-09-29 00:04:57 -04:00
_ => char::decode_utf16(v.array_chunks::<2>().copied().map(u16::from_be_bytes))
2022-04-12 02:43:35 -05:00
.collect::<Result<_, _>>()
.map_err(|_| FromUtf16Error(())),
}
}
/// Decode a UTF-16BEencoded slice `v` into a `String`, replacing
/// invalid data with [the replacement character (`U+FFFD`)][U+FFFD].
///
/// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
/// `from_utf16le_lossy` returns a `String` since the UTF-16 to UTF-8
/// conversion requires a memory allocation.
///
/// [`from_utf8_lossy`]: String::from_utf8_lossy
/// [`Cow<'a, str>`]: crate::borrow::Cow "borrow::Cow"
/// [U+FFFD]: core::char::REPLACEMENT_CHARACTER
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(str_from_utf16_endian)]
/// // 𝄞mus<invalid>ic<invalid>
/// let v = &[0xD8, 0x34, 0xDD, 0x1E, 0x00, 0x6d, 0x00, 0x75,
/// 0x00, 0x73, 0xDD, 0x1E, 0x00, 0x69, 0x00, 0x63,
/// 0xD8, 0x34];
///
/// assert_eq!(String::from("𝄞mus\u{FFFD}ic\u{FFFD}"),
/// String::from_utf16be_lossy(v));
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "str_from_utf16_endian", issue = "116258")]
2022-04-12 02:43:35 -05:00
pub fn from_utf16be_lossy(v: &[u8]) -> String {
match (cfg!(target_endian = "big"), unsafe { v.align_to::<u16>() }) {
(true, ([], v, [])) => Self::from_utf16_lossy(v),
(true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}",
2022-04-12 02:43:35 -05:00
_ => {
let mut iter = v.array_chunks::<2>();
2023-09-29 00:04:57 -04:00
let string = char::decode_utf16(iter.by_ref().copied().map(u16::from_be_bytes))
.map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
2022-04-12 02:43:35 -05:00
.collect();
if iter.remainder().is_empty() { string } else { string + "\u{FFFD}" }
}
}
}
/// Decomposes a `String` into its raw components: `(pointer, length, capacity)`.
2019-10-22 12:48:52 -04:00
///
/// Returns the raw pointer to the underlying data, the length of
/// the string (in bytes), and the allocated capacity of the data
/// (in bytes). These are the same arguments in the same order as
/// the arguments to [`from_raw_parts`].
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `String`. The only way to do
/// this is to convert the raw pointer, length, and capacity back
/// into a `String` with the [`from_raw_parts`] function, allowing
/// the destructor to perform the cleanup.
///
2020-07-18 10:14:00 -07:00
/// [`from_raw_parts`]: String::from_raw_parts
2019-10-22 12:48:52 -04:00
///
/// # Examples
///
/// ```
/// #![feature(vec_into_raw_parts)]
/// let s = String::from("hello");
///
/// let (ptr, len, cap) = s.into_raw_parts();
///
/// let rebuilt = unsafe { String::from_raw_parts(ptr, len, cap) };
/// assert_eq!(rebuilt, "hello");
/// ```
#[must_use = "`self` will be dropped if the result is not used"]
2019-10-22 12:48:52 -04:00
#[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
pub fn into_raw_parts(self) -> (*mut u8, usize, usize) {
self.vec.into_raw_parts()
}
/// Creates a new `String` from a pointer, a length and a capacity.
///
/// # Safety
///
/// This is highly unsafe, due to the number of invariants that aren't
/// checked:
///
/// * The memory at `buf` needs to have been previously allocated by the
/// same allocator the standard library uses, with a required alignment of exactly 1.
/// * `length` needs to be less than or equal to `capacity`.
/// * `capacity` needs to be the correct value.
/// * The first `length` bytes at `buf` need to be valid UTF-8.
///
/// Violating these may cause problems like corrupting the allocator's
/// internal data structures. For example, it is normally **not** safe to
/// build a `String` from a pointer to a C `char` array containing UTF-8
/// _unless_ you are certain that array was originally allocated by the
/// Rust standard library's allocator.
///
/// The ownership of `buf` is effectively transferred to the
/// `String` which may then deallocate, reallocate or change the
/// contents of memory pointed to by the pointer at will. Ensure
/// that nothing else uses the pointer after calling this
/// function.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// unsafe {
/// let s = String::from("hello");
///
2019-10-22 12:48:52 -04:00
// FIXME Update this when vec_into_raw_parts is stabilized
/// // Prevent automatically dropping the String's data
/// let mut s = mem::ManuallyDrop::new(s);
///
2019-10-22 13:54:09 -04:00
/// let ptr = s.as_mut_ptr();
/// let len = s.len();
/// let capacity = s.capacity();
///
2019-10-22 13:54:09 -04:00
/// let s = String::from_raw_parts(ptr, len, capacity);
///
/// assert_eq!(String::from("hello"), s);
/// }
/// ```
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String {
unsafe { String { vec: Vec::from_raw_parts(buf, length, capacity) } }
}
/// Converts a vector of bytes to a `String` without checking that the
/// string contains valid UTF-8.
///
/// See the safe version, [`from_utf8`], for more details.
///
2020-07-18 10:14:00 -07:00
/// [`from_utf8`]: String::from_utf8
///
/// # Safety
///
/// This function is unsafe because it does not check that the bytes passed
/// to it are valid UTF-8. If this constraint is violated, it may cause
/// memory unsafety issues with future users of the `String`, as the rest of
/// the standard library assumes that `String`s are valid UTF-8.
///
/// # Examples
///
/// ```
/// // some bytes, in a vector
/// let sparkle_heart = vec![240, 159, 146, 150];
///
/// let sparkle_heart = unsafe {
/// String::from_utf8_unchecked(sparkle_heart)
/// };
///
/// assert_eq!("💖", sparkle_heart);
/// ```
#[inline]
#[must_use]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
String { vec: bytes }
}
/// Converts a `String` into a byte vector.
///
/// This consumes the `String`, so we do not need to copy its contents.
///
/// # Examples
///
/// ```
/// let s = String::from("hello");
/// let bytes = s.into_bytes();
///
/// assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]);
/// ```
#[inline]
#[must_use = "`self` will be dropped if the result is not used"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_bytes(self) -> Vec<u8> {
self.vec
}
/// Extracts a string slice containing the entire `String`.
///
/// # Examples
///
/// ```
/// let s = String::from("foo");
///
/// assert_eq!("foo", s.as_str());
/// ```
#[inline]
2021-10-11 13:57:38 -04:00
#[must_use]
std: Stabilize APIs for the 1.7 release This commit stabilizes and deprecates the FCP (final comment period) APIs for the upcoming 1.7 beta release. The specific APIs which changed were: Stabilized * `Path::strip_prefix` (renamed from `relative_from`) * `path::StripPrefixError` (new error type returned from `strip_prefix`) * `Ipv4Addr::is_loopback` * `Ipv4Addr::is_private` * `Ipv4Addr::is_link_local` * `Ipv4Addr::is_multicast` * `Ipv4Addr::is_broadcast` * `Ipv4Addr::is_documentation` * `Ipv6Addr::is_unspecified` * `Ipv6Addr::is_loopback` * `Ipv6Addr::is_unique_local` * `Ipv6Addr::is_multicast` * `Vec::as_slice` * `Vec::as_mut_slice` * `String::as_str` * `String::as_mut_str` * `<[T]>::clone_from_slice` - the `usize` return value is removed * `<[T]>::sort_by_key` * `i32::checked_rem` (and other signed types) * `i32::checked_neg` (and other signed types) * `i32::checked_shl` (and other signed types) * `i32::checked_shr` (and other signed types) * `i32::saturating_mul` (and other signed types) * `i32::overflowing_add` (and other signed types) * `i32::overflowing_sub` (and other signed types) * `i32::overflowing_mul` (and other signed types) * `i32::overflowing_div` (and other signed types) * `i32::overflowing_rem` (and other signed types) * `i32::overflowing_neg` (and other signed types) * `i32::overflowing_shl` (and other signed types) * `i32::overflowing_shr` (and other signed types) * `u32::checked_rem` (and other unsigned types) * `u32::checked_neg` (and other unsigned types) * `u32::checked_shl` (and other unsigned types) * `u32::saturating_mul` (and other unsigned types) * `u32::overflowing_add` (and other unsigned types) * `u32::overflowing_sub` (and other unsigned types) * `u32::overflowing_mul` (and other unsigned types) * `u32::overflowing_div` (and other unsigned types) * `u32::overflowing_rem` (and other unsigned types) * `u32::overflowing_neg` (and other unsigned types) * `u32::overflowing_shl` (and other unsigned types) * `u32::overflowing_shr` (and other unsigned types) * `ffi::IntoStringError` * `CString::into_string` * `CString::into_bytes` * `CString::into_bytes_with_nul` * `From<CString> for Vec<u8>` * `From<CString> for Vec<u8>` * `IntoStringError::into_cstring` * `IntoStringError::utf8_error` * `Error for IntoStringError` Deprecated * `Path::relative_from` - renamed to `strip_prefix` * `Path::prefix` - use `components().next()` instead * `os::unix::fs` constants - moved to the `libc` crate * `fmt::{radix, Radix, RadixFmt}` - not used enough to stabilize * `IntoCow` - conflicts with `Into` and may come back later * `i32::{BITS, BYTES}` (and other integers) - not pulling their weight * `DebugTuple::formatter` - will be removed * `sync::Semaphore` - not used enough and confused with system semaphores Closes #23284 cc #27709 (still lots more methods though) Closes #27712 Closes #27722 Closes #27728 Closes #27735 Closes #27729 Closes #27755 Closes #27782 Closes #27798
2016-01-15 10:07:52 -08:00
#[stable(feature = "string_as_str", since = "1.7.0")]
pub fn as_str(&self) -> &str {
self
}
/// Converts a `String` into a mutable string slice.
///
/// # Examples
///
/// ```
/// let mut s = String::from("foobar");
/// let s_mut_str = s.as_mut_str();
///
/// s_mut_str.make_ascii_uppercase();
///
/// assert_eq!("FOOBAR", s_mut_str);
/// ```
std: Stabilize APIs for the 1.7 release This commit stabilizes and deprecates the FCP (final comment period) APIs for the upcoming 1.7 beta release. The specific APIs which changed were: Stabilized * `Path::strip_prefix` (renamed from `relative_from`) * `path::StripPrefixError` (new error type returned from `strip_prefix`) * `Ipv4Addr::is_loopback` * `Ipv4Addr::is_private` * `Ipv4Addr::is_link_local` * `Ipv4Addr::is_multicast` * `Ipv4Addr::is_broadcast` * `Ipv4Addr::is_documentation` * `Ipv6Addr::is_unspecified` * `Ipv6Addr::is_loopback` * `Ipv6Addr::is_unique_local` * `Ipv6Addr::is_multicast` * `Vec::as_slice` * `Vec::as_mut_slice` * `String::as_str` * `String::as_mut_str` * `<[T]>::clone_from_slice` - the `usize` return value is removed * `<[T]>::sort_by_key` * `i32::checked_rem` (and other signed types) * `i32::checked_neg` (and other signed types) * `i32::checked_shl` (and other signed types) * `i32::checked_shr` (and other signed types) * `i32::saturating_mul` (and other signed types) * `i32::overflowing_add` (and other signed types) * `i32::overflowing_sub` (and other signed types) * `i32::overflowing_mul` (and other signed types) * `i32::overflowing_div` (and other signed types) * `i32::overflowing_rem` (and other signed types) * `i32::overflowing_neg` (and other signed types) * `i32::overflowing_shl` (and other signed types) * `i32::overflowing_shr` (and other signed types) * `u32::checked_rem` (and other unsigned types) * `u32::checked_neg` (and other unsigned types) * `u32::checked_shl` (and other unsigned types) * `u32::saturating_mul` (and other unsigned types) * `u32::overflowing_add` (and other unsigned types) * `u32::overflowing_sub` (and other unsigned types) * `u32::overflowing_mul` (and other unsigned types) * `u32::overflowing_div` (and other unsigned types) * `u32::overflowing_rem` (and other unsigned types) * `u32::overflowing_neg` (and other unsigned types) * `u32::overflowing_shl` (and other unsigned types) * `u32::overflowing_shr` (and other unsigned types) * `ffi::IntoStringError` * `CString::into_string` * `CString::into_bytes` * `CString::into_bytes_with_nul` * `From<CString> for Vec<u8>` * `From<CString> for Vec<u8>` * `IntoStringError::into_cstring` * `IntoStringError::utf8_error` * `Error for IntoStringError` Deprecated * `Path::relative_from` - renamed to `strip_prefix` * `Path::prefix` - use `components().next()` instead * `os::unix::fs` constants - moved to the `libc` crate * `fmt::{radix, Radix, RadixFmt}` - not used enough to stabilize * `IntoCow` - conflicts with `Into` and may come back later * `i32::{BITS, BYTES}` (and other integers) - not pulling their weight * `DebugTuple::formatter` - will be removed * `sync::Semaphore` - not used enough and confused with system semaphores Closes #23284 cc #27709 (still lots more methods though) Closes #27712 Closes #27722 Closes #27728 Closes #27735 Closes #27729 Closes #27755 Closes #27782 Closes #27798
2016-01-15 10:07:52 -08:00
#[inline]
2021-10-11 13:57:38 -04:00
#[must_use]
std: Stabilize APIs for the 1.7 release This commit stabilizes and deprecates the FCP (final comment period) APIs for the upcoming 1.7 beta release. The specific APIs which changed were: Stabilized * `Path::strip_prefix` (renamed from `relative_from`) * `path::StripPrefixError` (new error type returned from `strip_prefix`) * `Ipv4Addr::is_loopback` * `Ipv4Addr::is_private` * `Ipv4Addr::is_link_local` * `Ipv4Addr::is_multicast` * `Ipv4Addr::is_broadcast` * `Ipv4Addr::is_documentation` * `Ipv6Addr::is_unspecified` * `Ipv6Addr::is_loopback` * `Ipv6Addr::is_unique_local` * `Ipv6Addr::is_multicast` * `Vec::as_slice` * `Vec::as_mut_slice` * `String::as_str` * `String::as_mut_str` * `<[T]>::clone_from_slice` - the `usize` return value is removed * `<[T]>::sort_by_key` * `i32::checked_rem` (and other signed types) * `i32::checked_neg` (and other signed types) * `i32::checked_shl` (and other signed types) * `i32::checked_shr` (and other signed types) * `i32::saturating_mul` (and other signed types) * `i32::overflowing_add` (and other signed types) * `i32::overflowing_sub` (and other signed types) * `i32::overflowing_mul` (and other signed types) * `i32::overflowing_div` (and other signed types) * `i32::overflowing_rem` (and other signed types) * `i32::overflowing_neg` (and other signed types) * `i32::overflowing_shl` (and other signed types) * `i32::overflowing_shr` (and other signed types) * `u32::checked_rem` (and other unsigned types) * `u32::checked_neg` (and other unsigned types) * `u32::checked_shl` (and other unsigned types) * `u32::saturating_mul` (and other unsigned types) * `u32::overflowing_add` (and other unsigned types) * `u32::overflowing_sub` (and other unsigned types) * `u32::overflowing_mul` (and other unsigned types) * `u32::overflowing_div` (and other unsigned types) * `u32::overflowing_rem` (and other unsigned types) * `u32::overflowing_neg` (and other unsigned types) * `u32::overflowing_shl` (and other unsigned types) * `u32::overflowing_shr` (and other unsigned types) * `ffi::IntoStringError` * `CString::into_string` * `CString::into_bytes` * `CString::into_bytes_with_nul` * `From<CString> for Vec<u8>` * `From<CString> for Vec<u8>` * `IntoStringError::into_cstring` * `IntoStringError::utf8_error` * `Error for IntoStringError` Deprecated * `Path::relative_from` - renamed to `strip_prefix` * `Path::prefix` - use `components().next()` instead * `os::unix::fs` constants - moved to the `libc` crate * `fmt::{radix, Radix, RadixFmt}` - not used enough to stabilize * `IntoCow` - conflicts with `Into` and may come back later * `i32::{BITS, BYTES}` (and other integers) - not pulling their weight * `DebugTuple::formatter` - will be removed * `sync::Semaphore` - not used enough and confused with system semaphores Closes #23284 cc #27709 (still lots more methods though) Closes #27712 Closes #27722 Closes #27728 Closes #27735 Closes #27729 Closes #27755 Closes #27782 Closes #27798
2016-01-15 10:07:52 -08:00
#[stable(feature = "string_as_str", since = "1.7.0")]
pub fn as_mut_str(&mut self) -> &mut str {
self
}
/// Appends a given string slice onto the end of this `String`.
///
/// # Examples
///
/// ```
/// let mut s = String::from("foo");
///
/// s.push_str("bar");
///
/// assert_eq!("foobar", s);
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_confusables("append", "push")]
pub fn push_str(&mut self, string: &str) {
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
self.vec.extend_from_slice(string.as_bytes())
}
/// Copies elements from `src` range to the end of the string.
///
/// # Panics
///
/// Panics if the starting point or end point do not lie on a [`char`]
/// boundary, or if they're out of bounds.
///
/// # Examples
///
/// ```
/// #![feature(string_extend_from_within)]
/// let mut string = String::from("abcde");
///
/// string.extend_from_within(2..);
/// assert_eq!(string, "abcdecde");
///
/// string.extend_from_within(..2);
/// assert_eq!(string, "abcdecdeab");
///
/// string.extend_from_within(4..8);
/// assert_eq!(string, "abcdecdeabecde");
/// ```
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "string_extend_from_within", issue = "103806")]
pub fn extend_from_within<R>(&mut self, src: R)
where
R: RangeBounds<usize>,
{
let src @ Range { start, end } = slice::range(src, ..self.len());
assert!(self.is_char_boundary(start));
assert!(self.is_char_boundary(end));
self.vec.extend_from_within(src);
}
/// Returns this `String`'s capacity, in bytes.
collections: Stabilize String # Rationale When dealing with strings, many functions deal with either a `char` (unicode codepoint) or a byte (utf-8 encoding related). There is often an inconsistent way in which methods are referred to as to whether they contain "byte", "char", or nothing in their name. There are also issues open to rename *all* methods to reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or byte_len()). The current state of String seems to largely be what is desired, so this PR proposes the following rationale for methods dealing with bytes or characters: > When constructing a string, the input encoding *must* be mentioned (e.g. > from_utf8). This makes it clear what exactly the input type is expected to be > in terms of encoding. > > When a method operates on anything related to an *index* within the string > such as length, capacity, position, etc, the method *implicitly* operates on > bytes. It is an understood fact that String is a utf-8 encoded string, and > burdening all methods with "bytes" would be redundant. > > When a method operates on the *contents* of a string, such as push() or pop(), > then "char" is the default type. A String can loosely be thought of as being a > collection of unicode codepoints, but not all collection-related operations > make sense because some can be woefully inefficient. # Method stabilization The following methods have been marked #[stable] * The String type itself * String::new * String::with_capacity * String::from_utf16_lossy * String::into_bytes * String::as_bytes * String::len * String::clear * String::as_slice The following methods have been marked #[unstable] * String::from_utf8 - The error type in the returned `Result` may change to provide a nicer message when it's `unwrap()`'d * String::from_utf8_lossy - The returned `MaybeOwned` type still needs stabilization * String::from_utf16 - The return type may change to become a `Result` which includes more contextual information like where the error occurred. * String::from_chars - This is equivalent to iter().collect(), but currently not as ergonomic. * String::from_char - This method is the equivalent of Vec::from_elem, and has been marked #[unstable] becuase it can be seen as a duplicate of iterator-based functionality as well as possibly being renamed. * String::push_str - This *can* be emulated with .extend(foo.chars()), but is less efficient because of decoding/encoding. Due to the desire to minimize API surface this may be able to be removed in the future for something possibly generic with no loss in performance. * String::grow - This is a duplicate of iterator-based functionality, which may become more ergonomic in the future. * String::capacity - This function was just added. * String::push - This function was just added. * String::pop - This function was just added. * String::truncate - The failure conventions around String methods and byte indices isn't totally clear at this time, so the failure semantics and return value of this method are subject to change. * String::as_mut_vec - the naming of this method may change. * string::raw::* - these functions are all waiting on [an RFC][2] [2]: https://github.com/rust-lang/rfcs/pull/240 The following method have been marked #[experimental] * String::from_str - This function only exists as it's more efficient than to_string(), but having a less ergonomic function for performance reasons isn't the greatest reason to keep it around. Like Vec::push_all, this has been marked experimental for now. The following methods have been #[deprecated] * String::append - This method has been deprecated to remain consistent with the deprecation of Vec::append. While convenient, it is one of the only functional-style apis on String, and requires more though as to whether it belongs as a first-class method or now (and how it relates to other collections). * String::from_byte - This is fairly rare functionality and can be emulated with str::from_utf8 plus an assert plus a call to to_string(). Additionally, String::from_char could possibly be used. * String::byte_capacity - Renamed to String::capacity due to the rationale above. * String::push_char - Renamed to String::push due to the rationale above. * String::pop_char - Renamed to String::pop due to the rationale above. * String::push_bytes - There are a number of `unsafe` functions on the `String` type which allow bypassing utf-8 checks. These have all been deprecated in favor of calling `.as_mut_vec()` and then operating directly on the vector returned. These methods were deprecated because naming them with relation to other methods was difficult to rationalize and it's arguably more composable to call .as_mut_vec(). * String::as_mut_bytes - See push_bytes * String::push_byte - See push_bytes * String::pop_byte - See push_bytes * String::shift_byte - See push_bytes # Reservation methods This commit does not yet touch the methods for reserving bytes. The methods on Vec have also not yet been modified. These methods are discussed in the upcoming [Collections reform RFC][1] [1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
///
/// # Examples
collections: Stabilize String # Rationale When dealing with strings, many functions deal with either a `char` (unicode codepoint) or a byte (utf-8 encoding related). There is often an inconsistent way in which methods are referred to as to whether they contain "byte", "char", or nothing in their name. There are also issues open to rename *all* methods to reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or byte_len()). The current state of String seems to largely be what is desired, so this PR proposes the following rationale for methods dealing with bytes or characters: > When constructing a string, the input encoding *must* be mentioned (e.g. > from_utf8). This makes it clear what exactly the input type is expected to be > in terms of encoding. > > When a method operates on anything related to an *index* within the string > such as length, capacity, position, etc, the method *implicitly* operates on > bytes. It is an understood fact that String is a utf-8 encoded string, and > burdening all methods with "bytes" would be redundant. > > When a method operates on the *contents* of a string, such as push() or pop(), > then "char" is the default type. A String can loosely be thought of as being a > collection of unicode codepoints, but not all collection-related operations > make sense because some can be woefully inefficient. # Method stabilization The following methods have been marked #[stable] * The String type itself * String::new * String::with_capacity * String::from_utf16_lossy * String::into_bytes * String::as_bytes * String::len * String::clear * String::as_slice The following methods have been marked #[unstable] * String::from_utf8 - The error type in the returned `Result` may change to provide a nicer message when it's `unwrap()`'d * String::from_utf8_lossy - The returned `MaybeOwned` type still needs stabilization * String::from_utf16 - The return type may change to become a `Result` which includes more contextual information like where the error occurred. * String::from_chars - This is equivalent to iter().collect(), but currently not as ergonomic. * String::from_char - This method is the equivalent of Vec::from_elem, and has been marked #[unstable] becuase it can be seen as a duplicate of iterator-based functionality as well as possibly being renamed. * String::push_str - This *can* be emulated with .extend(foo.chars()), but is less efficient because of decoding/encoding. Due to the desire to minimize API surface this may be able to be removed in the future for something possibly generic with no loss in performance. * String::grow - This is a duplicate of iterator-based functionality, which may become more ergonomic in the future. * String::capacity - This function was just added. * String::push - This function was just added. * String::pop - This function was just added. * String::truncate - The failure conventions around String methods and byte indices isn't totally clear at this time, so the failure semantics and return value of this method are subject to change. * String::as_mut_vec - the naming of this method may change. * string::raw::* - these functions are all waiting on [an RFC][2] [2]: https://github.com/rust-lang/rfcs/pull/240 The following method have been marked #[experimental] * String::from_str - This function only exists as it's more efficient than to_string(), but having a less ergonomic function for performance reasons isn't the greatest reason to keep it around. Like Vec::push_all, this has been marked experimental for now. The following methods have been #[deprecated] * String::append - This method has been deprecated to remain consistent with the deprecation of Vec::append. While convenient, it is one of the only functional-style apis on String, and requires more though as to whether it belongs as a first-class method or now (and how it relates to other collections). * String::from_byte - This is fairly rare functionality and can be emulated with str::from_utf8 plus an assert plus a call to to_string(). Additionally, String::from_char could possibly be used. * String::byte_capacity - Renamed to String::capacity due to the rationale above. * String::push_char - Renamed to String::push due to the rationale above. * String::pop_char - Renamed to String::pop due to the rationale above. * String::push_bytes - There are a number of `unsafe` functions on the `String` type which allow bypassing utf-8 checks. These have all been deprecated in favor of calling `.as_mut_vec()` and then operating directly on the vector returned. These methods were deprecated because naming them with relation to other methods was difficult to rationalize and it's arguably more composable to call .as_mut_vec(). * String::as_mut_bytes - See push_bytes * String::push_byte - See push_bytes * String::pop_byte - See push_bytes * String::shift_byte - See push_bytes # Reservation methods This commit does not yet touch the methods for reserving bytes. The methods on Vec have also not yet been modified. These methods are discussed in the upcoming [Collections reform RFC][1] [1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
///
/// ```
/// let s = String::with_capacity(10);
///
/// assert!(s.capacity() >= 10);
collections: Stabilize String # Rationale When dealing with strings, many functions deal with either a `char` (unicode codepoint) or a byte (utf-8 encoding related). There is often an inconsistent way in which methods are referred to as to whether they contain "byte", "char", or nothing in their name. There are also issues open to rename *all* methods to reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or byte_len()). The current state of String seems to largely be what is desired, so this PR proposes the following rationale for methods dealing with bytes or characters: > When constructing a string, the input encoding *must* be mentioned (e.g. > from_utf8). This makes it clear what exactly the input type is expected to be > in terms of encoding. > > When a method operates on anything related to an *index* within the string > such as length, capacity, position, etc, the method *implicitly* operates on > bytes. It is an understood fact that String is a utf-8 encoded string, and > burdening all methods with "bytes" would be redundant. > > When a method operates on the *contents* of a string, such as push() or pop(), > then "char" is the default type. A String can loosely be thought of as being a > collection of unicode codepoints, but not all collection-related operations > make sense because some can be woefully inefficient. # Method stabilization The following methods have been marked #[stable] * The String type itself * String::new * String::with_capacity * String::from_utf16_lossy * String::into_bytes * String::as_bytes * String::len * String::clear * String::as_slice The following methods have been marked #[unstable] * String::from_utf8 - The error type in the returned `Result` may change to provide a nicer message when it's `unwrap()`'d * String::from_utf8_lossy - The returned `MaybeOwned` type still needs stabilization * String::from_utf16 - The return type may change to become a `Result` which includes more contextual information like where the error occurred. * String::from_chars - This is equivalent to iter().collect(), but currently not as ergonomic. * String::from_char - This method is the equivalent of Vec::from_elem, and has been marked #[unstable] becuase it can be seen as a duplicate of iterator-based functionality as well as possibly being renamed. * String::push_str - This *can* be emulated with .extend(foo.chars()), but is less efficient because of decoding/encoding. Due to the desire to minimize API surface this may be able to be removed in the future for something possibly generic with no loss in performance. * String::grow - This is a duplicate of iterator-based functionality, which may become more ergonomic in the future. * String::capacity - This function was just added. * String::push - This function was just added. * String::pop - This function was just added. * String::truncate - The failure conventions around String methods and byte indices isn't totally clear at this time, so the failure semantics and return value of this method are subject to change. * String::as_mut_vec - the naming of this method may change. * string::raw::* - these functions are all waiting on [an RFC][2] [2]: https://github.com/rust-lang/rfcs/pull/240 The following method have been marked #[experimental] * String::from_str - This function only exists as it's more efficient than to_string(), but having a less ergonomic function for performance reasons isn't the greatest reason to keep it around. Like Vec::push_all, this has been marked experimental for now. The following methods have been #[deprecated] * String::append - This method has been deprecated to remain consistent with the deprecation of Vec::append. While convenient, it is one of the only functional-style apis on String, and requires more though as to whether it belongs as a first-class method or now (and how it relates to other collections). * String::from_byte - This is fairly rare functionality and can be emulated with str::from_utf8 plus an assert plus a call to to_string(). Additionally, String::from_char could possibly be used. * String::byte_capacity - Renamed to String::capacity due to the rationale above. * String::push_char - Renamed to String::push due to the rationale above. * String::pop_char - Renamed to String::pop due to the rationale above. * String::push_bytes - There are a number of `unsafe` functions on the `String` type which allow bypassing utf-8 checks. These have all been deprecated in favor of calling `.as_mut_vec()` and then operating directly on the vector returned. These methods were deprecated because naming them with relation to other methods was difficult to rationalize and it's arguably more composable to call .as_mut_vec(). * String::as_mut_bytes - See push_bytes * String::push_byte - See push_bytes * String::pop_byte - See push_bytes * String::shift_byte - See push_bytes # Reservation methods This commit does not yet touch the methods for reserving bytes. The methods on Vec have also not yet been modified. These methods are discussed in the upcoming [Collections reform RFC][1] [1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
/// ```
#[inline]
#[must_use]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn capacity(&self) -> usize {
collections: Stabilize String # Rationale When dealing with strings, many functions deal with either a `char` (unicode codepoint) or a byte (utf-8 encoding related). There is often an inconsistent way in which methods are referred to as to whether they contain "byte", "char", or nothing in their name. There are also issues open to rename *all* methods to reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or byte_len()). The current state of String seems to largely be what is desired, so this PR proposes the following rationale for methods dealing with bytes or characters: > When constructing a string, the input encoding *must* be mentioned (e.g. > from_utf8). This makes it clear what exactly the input type is expected to be > in terms of encoding. > > When a method operates on anything related to an *index* within the string > such as length, capacity, position, etc, the method *implicitly* operates on > bytes. It is an understood fact that String is a utf-8 encoded string, and > burdening all methods with "bytes" would be redundant. > > When a method operates on the *contents* of a string, such as push() or pop(), > then "char" is the default type. A String can loosely be thought of as being a > collection of unicode codepoints, but not all collection-related operations > make sense because some can be woefully inefficient. # Method stabilization The following methods have been marked #[stable] * The String type itself * String::new * String::with_capacity * String::from_utf16_lossy * String::into_bytes * String::as_bytes * String::len * String::clear * String::as_slice The following methods have been marked #[unstable] * String::from_utf8 - The error type in the returned `Result` may change to provide a nicer message when it's `unwrap()`'d * String::from_utf8_lossy - The returned `MaybeOwned` type still needs stabilization * String::from_utf16 - The return type may change to become a `Result` which includes more contextual information like where the error occurred. * String::from_chars - This is equivalent to iter().collect(), but currently not as ergonomic. * String::from_char - This method is the equivalent of Vec::from_elem, and has been marked #[unstable] becuase it can be seen as a duplicate of iterator-based functionality as well as possibly being renamed. * String::push_str - This *can* be emulated with .extend(foo.chars()), but is less efficient because of decoding/encoding. Due to the desire to minimize API surface this may be able to be removed in the future for something possibly generic with no loss in performance. * String::grow - This is a duplicate of iterator-based functionality, which may become more ergonomic in the future. * String::capacity - This function was just added. * String::push - This function was just added. * String::pop - This function was just added. * String::truncate - The failure conventions around String methods and byte indices isn't totally clear at this time, so the failure semantics and return value of this method are subject to change. * String::as_mut_vec - the naming of this method may change. * string::raw::* - these functions are all waiting on [an RFC][2] [2]: https://github.com/rust-lang/rfcs/pull/240 The following method have been marked #[experimental] * String::from_str - This function only exists as it's more efficient than to_string(), but having a less ergonomic function for performance reasons isn't the greatest reason to keep it around. Like Vec::push_all, this has been marked experimental for now. The following methods have been #[deprecated] * String::append - This method has been deprecated to remain consistent with the deprecation of Vec::append. While convenient, it is one of the only functional-style apis on String, and requires more though as to whether it belongs as a first-class method or now (and how it relates to other collections). * String::from_byte - This is fairly rare functionality and can be emulated with str::from_utf8 plus an assert plus a call to to_string(). Additionally, String::from_char could possibly be used. * String::byte_capacity - Renamed to String::capacity due to the rationale above. * String::push_char - Renamed to String::push due to the rationale above. * String::pop_char - Renamed to String::pop due to the rationale above. * String::push_bytes - There are a number of `unsafe` functions on the `String` type which allow bypassing utf-8 checks. These have all been deprecated in favor of calling `.as_mut_vec()` and then operating directly on the vector returned. These methods were deprecated because naming them with relation to other methods was difficult to rationalize and it's arguably more composable to call .as_mut_vec(). * String::as_mut_bytes - See push_bytes * String::push_byte - See push_bytes * String::pop_byte - See push_bytes * String::shift_byte - See push_bytes # Reservation methods This commit does not yet touch the methods for reserving bytes. The methods on Vec have also not yet been modified. These methods are discussed in the upcoming [Collections reform RFC][1] [1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
self.vec.capacity()
}
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// Reserves capacity for at least `additional` bytes more than the
/// current length. The allocator may reserve more space to speculatively
/// avoid frequent allocations. After calling `reserve`,
/// capacity will be greater than or equal to `self.len() + additional`.
/// Does nothing if capacity is already sufficient.
///
/// # Panics
///
/// Panics if the new capacity overflows [`usize`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let mut s = String::new();
///
/// s.reserve(10);
///
/// assert!(s.capacity() >= 10);
/// ```
///
/// This might not actually increase the capacity:
///
/// ```
/// let mut s = String::with_capacity(10);
/// s.push('a');
/// s.push('b');
///
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// // s now has a length of 2 and a capacity of at least 10
/// let capacity = s.capacity();
/// assert_eq!(2, s.len());
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// assert!(capacity >= 10);
///
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// // Since we already have at least an extra 8 capacity, calling this...
/// s.reserve(8);
///
/// // ... doesn't actually increase.
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// assert_eq!(capacity, s.capacity());
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn reserve(&mut self, additional: usize) {
self.vec.reserve(additional)
}
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// Reserves the minimum capacity for at least `additional` bytes more than
/// the current length. Unlike [`reserve`], this will not
/// deliberately over-allocate to speculatively avoid frequent allocations.
/// After calling `reserve_exact`, capacity will be greater than or equal to
/// `self.len() + additional`. Does nothing if the capacity is already
/// sufficient.
///
2020-07-18 10:14:00 -07:00
/// [`reserve`]: String::reserve
///
/// # Panics
///
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// Panics if the new capacity overflows [`usize`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let mut s = String::new();
///
/// s.reserve_exact(10);
///
/// assert!(s.capacity() >= 10);
/// ```
///
/// This might not actually increase the capacity:
///
/// ```
/// let mut s = String::with_capacity(10);
/// s.push('a');
/// s.push('b');
///
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// // s now has a length of 2 and a capacity of at least 10
/// let capacity = s.capacity();
/// assert_eq!(2, s.len());
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// assert!(capacity >= 10);
///
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// // Since we already have at least an extra 8 capacity, calling this...
/// s.reserve_exact(8);
///
/// // ... doesn't actually increase.
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// assert_eq!(capacity, s.capacity());
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn reserve_exact(&mut self, additional: usize) {
self.vec.reserve_exact(additional)
}
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// Tries to reserve capacity for at least `additional` bytes more than the
/// current length. The allocator may reserve more space to speculatively
/// avoid frequent allocations. After calling `try_reserve`, capacity will be
/// greater than or equal to `self.len() + additional` if it returns
/// `Ok(())`. Does nothing if capacity is already sufficient. This method
/// preserves the contents even if an error occurs.
///
/// # Errors
///
/// If the capacity overflows, or the allocator reports a failure, then an error
/// is returned.
///
/// # Examples
///
/// ```
/// use std::collections::TryReserveError;
///
/// fn process_data(data: &str) -> Result<String, TryReserveError> {
/// let mut output = String::new();
///
/// // Pre-reserve the memory, exiting if we can't
/// output.try_reserve(data.len())?;
///
/// // Now we know this can't OOM in the middle of our complex work
/// output.push_str(data);
///
/// Ok(output)
/// }
/// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
/// ```
2021-08-29 23:21:33 +01:00
#[stable(feature = "try_reserve", since = "1.57.0")]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.vec.try_reserve(additional)
}
Fix documentation for with_capacity and reserve families of methods Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-04-09 16:42:26 +01:00
/// Tries to reserve the minimum capacity for at least `additional` bytes
/// more than the current length. Unlike [`try_reserve`], this will not
/// deliberately over-allocate to speculatively avoid frequent allocations.
/// After calling `try_reserve_exact`, capacity will be greater than or
/// equal to `self.len() + additional` if it returns `Ok(())`.
/// Does nothing if the capacity is already sufficient.
///
/// Note that the allocator may give the collection more space than it
2019-02-09 22:16:58 +00:00
/// requests. Therefore, capacity can not be relied upon to be precisely
/// minimal. Prefer [`try_reserve`] if future insertions are expected.
///
/// [`try_reserve`]: String::try_reserve
///
/// # Errors
///
/// If the capacity overflows, or the allocator reports a failure, then an error
/// is returned.
///
/// # Examples
///
/// ```
/// use std::collections::TryReserveError;
///
/// fn process_data(data: &str) -> Result<String, TryReserveError> {
/// let mut output = String::new();
///
/// // Pre-reserve the memory, exiting if we can't
/// output.try_reserve_exact(data.len())?;
///
/// // Now we know this can't OOM in the middle of our complex work
/// output.push_str(data);
///
/// Ok(output)
/// }
/// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
/// ```
2021-08-29 23:21:33 +01:00
#[stable(feature = "try_reserve", since = "1.57.0")]
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.vec.try_reserve_exact(additional)
}
/// Shrinks the capacity of this `String` to match its length.
///
/// # Examples
///
/// ```
/// let mut s = String::from("foo");
///
/// s.reserve(100);
/// assert!(s.capacity() >= 100);
///
/// s.shrink_to_fit();
/// assert_eq!(3, s.capacity());
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn shrink_to_fit(&mut self) {
self.vec.shrink_to_fit()
}
/// Shrinks the capacity of this `String` with a lower bound.
///
/// The capacity will remain at least as large as both the length
/// and the supplied value.
///
/// If the current capacity is less than the lower limit, this is a no-op.
///
/// # Examples
///
/// ```
/// let mut s = String::from("foo");
///
/// s.reserve(100);
/// assert!(s.capacity() >= 100);
///
/// s.shrink_to(10);
/// assert!(s.capacity() >= 10);
/// s.shrink_to(0);
/// assert!(s.capacity() >= 3);
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[inline]
#[stable(feature = "shrink_to", since = "1.56.0")]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.vec.shrink_to(min_capacity)
}
/// Appends the given [`char`] to the end of this `String`.
///
/// # Examples
///
/// ```
/// let mut s = String::from("abc");
///
collections: Stabilize String # Rationale When dealing with strings, many functions deal with either a `char` (unicode codepoint) or a byte (utf-8 encoding related). There is often an inconsistent way in which methods are referred to as to whether they contain "byte", "char", or nothing in their name. There are also issues open to rename *all* methods to reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or byte_len()). The current state of String seems to largely be what is desired, so this PR proposes the following rationale for methods dealing with bytes or characters: > When constructing a string, the input encoding *must* be mentioned (e.g. > from_utf8). This makes it clear what exactly the input type is expected to be > in terms of encoding. > > When a method operates on anything related to an *index* within the string > such as length, capacity, position, etc, the method *implicitly* operates on > bytes. It is an understood fact that String is a utf-8 encoded string, and > burdening all methods with "bytes" would be redundant. > > When a method operates on the *contents* of a string, such as push() or pop(), > then "char" is the default type. A String can loosely be thought of as being a > collection of unicode codepoints, but not all collection-related operations > make sense because some can be woefully inefficient. # Method stabilization The following methods have been marked #[stable] * The String type itself * String::new * String::with_capacity * String::from_utf16_lossy * String::into_bytes * String::as_bytes * String::len * String::clear * String::as_slice The following methods have been marked #[unstable] * String::from_utf8 - The error type in the returned `Result` may change to provide a nicer message when it's `unwrap()`'d * String::from_utf8_lossy - The returned `MaybeOwned` type still needs stabilization * String::from_utf16 - The return type may change to become a `Result` which includes more contextual information like where the error occurred. * String::from_chars - This is equivalent to iter().collect(), but currently not as ergonomic. * String::from_char - This method is the equivalent of Vec::from_elem, and has been marked #[unstable] becuase it can be seen as a duplicate of iterator-based functionality as well as possibly being renamed. * String::push_str - This *can* be emulated with .extend(foo.chars()), but is less efficient because of decoding/encoding. Due to the desire to minimize API surface this may be able to be removed in the future for something possibly generic with no loss in performance. * String::grow - This is a duplicate of iterator-based functionality, which may become more ergonomic in the future. * String::capacity - This function was just added. * String::push - This function was just added. * String::pop - This function was just added. * String::truncate - The failure conventions around String methods and byte indices isn't totally clear at this time, so the failure semantics and return value of this method are subject to change. * String::as_mut_vec - the naming of this method may change. * string::raw::* - these functions are all waiting on [an RFC][2] [2]: https://github.com/rust-lang/rfcs/pull/240 The following method have been marked #[experimental] * String::from_str - This function only exists as it's more efficient than to_string(), but having a less ergonomic function for performance reasons isn't the greatest reason to keep it around. Like Vec::push_all, this has been marked experimental for now. The following methods have been #[deprecated] * String::append - This method has been deprecated to remain consistent with the deprecation of Vec::append. While convenient, it is one of the only functional-style apis on String, and requires more though as to whether it belongs as a first-class method or now (and how it relates to other collections). * String::from_byte - This is fairly rare functionality and can be emulated with str::from_utf8 plus an assert plus a call to to_string(). Additionally, String::from_char could possibly be used. * String::byte_capacity - Renamed to String::capacity due to the rationale above. * String::push_char - Renamed to String::push due to the rationale above. * String::pop_char - Renamed to String::pop due to the rationale above. * String::push_bytes - There are a number of `unsafe` functions on the `String` type which allow bypassing utf-8 checks. These have all been deprecated in favor of calling `.as_mut_vec()` and then operating directly on the vector returned. These methods were deprecated because naming them with relation to other methods was difficult to rationalize and it's arguably more composable to call .as_mut_vec(). * String::as_mut_bytes - See push_bytes * String::push_byte - See push_bytes * String::pop_byte - See push_bytes * String::shift_byte - See push_bytes # Reservation methods This commit does not yet touch the methods for reserving bytes. The methods on Vec have also not yet been modified. These methods are discussed in the upcoming [Collections reform RFC][1] [1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
/// s.push('1');
/// s.push('2');
/// s.push('3');
///
/// assert_eq!("abc123", s);
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
collections: Stabilize String # Rationale When dealing with strings, many functions deal with either a `char` (unicode codepoint) or a byte (utf-8 encoding related). There is often an inconsistent way in which methods are referred to as to whether they contain "byte", "char", or nothing in their name. There are also issues open to rename *all* methods to reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or byte_len()). The current state of String seems to largely be what is desired, so this PR proposes the following rationale for methods dealing with bytes or characters: > When constructing a string, the input encoding *must* be mentioned (e.g. > from_utf8). This makes it clear what exactly the input type is expected to be > in terms of encoding. > > When a method operates on anything related to an *index* within the string > such as length, capacity, position, etc, the method *implicitly* operates on > bytes. It is an understood fact that String is a utf-8 encoded string, and > burdening all methods with "bytes" would be redundant. > > When a method operates on the *contents* of a string, such as push() or pop(), > then "char" is the default type. A String can loosely be thought of as being a > collection of unicode codepoints, but not all collection-related operations > make sense because some can be woefully inefficient. # Method stabilization The following methods have been marked #[stable] * The String type itself * String::new * String::with_capacity * String::from_utf16_lossy * String::into_bytes * String::as_bytes * String::len * String::clear * String::as_slice The following methods have been marked #[unstable] * String::from_utf8 - The error type in the returned `Result` may change to provide a nicer message when it's `unwrap()`'d * String::from_utf8_lossy - The returned `MaybeOwned` type still needs stabilization * String::from_utf16 - The return type may change to become a `Result` which includes more contextual information like where the error occurred. * String::from_chars - This is equivalent to iter().collect(), but currently not as ergonomic. * String::from_char - This method is the equivalent of Vec::from_elem, and has been marked #[unstable] becuase it can be seen as a duplicate of iterator-based functionality as well as possibly being renamed. * String::push_str - This *can* be emulated with .extend(foo.chars()), but is less efficient because of decoding/encoding. Due to the desire to minimize API surface this may be able to be removed in the future for something possibly generic with no loss in performance. * String::grow - This is a duplicate of iterator-based functionality, which may become more ergonomic in the future. * String::capacity - This function was just added. * String::push - This function was just added. * String::pop - This function was just added. * String::truncate - The failure conventions around String methods and byte indices isn't totally clear at this time, so the failure semantics and return value of this method are subject to change. * String::as_mut_vec - the naming of this method may change. * string::raw::* - these functions are all waiting on [an RFC][2] [2]: https://github.com/rust-lang/rfcs/pull/240 The following method have been marked #[experimental] * String::from_str - This function only exists as it's more efficient than to_string(), but having a less ergonomic function for performance reasons isn't the greatest reason to keep it around. Like Vec::push_all, this has been marked experimental for now. The following methods have been #[deprecated] * String::append - This method has been deprecated to remain consistent with the deprecation of Vec::append. While convenient, it is one of the only functional-style apis on String, and requires more though as to whether it belongs as a first-class method or now (and how it relates to other collections). * String::from_byte - This is fairly rare functionality and can be emulated with str::from_utf8 plus an assert plus a call to to_string(). Additionally, String::from_char could possibly be used. * String::byte_capacity - Renamed to String::capacity due to the rationale above. * String::push_char - Renamed to String::push due to the rationale above. * String::pop_char - Renamed to String::pop due to the rationale above. * String::push_bytes - There are a number of `unsafe` functions on the `String` type which allow bypassing utf-8 checks. These have all been deprecated in favor of calling `.as_mut_vec()` and then operating directly on the vector returned. These methods were deprecated because naming them with relation to other methods was difficult to rationalize and it's arguably more composable to call .as_mut_vec(). * String::as_mut_bytes - See push_bytes * String::push_byte - See push_bytes * String::pop_byte - See push_bytes * String::shift_byte - See push_bytes # Reservation methods This commit does not yet touch the methods for reserving bytes. The methods on Vec have also not yet been modified. These methods are discussed in the upcoming [Collections reform RFC][1] [1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
pub fn push(&mut self, ch: char) {
match ch.len_utf8() {
1 => self.vec.push(ch as u8),
2016-12-20 09:54:00 +05:30
_ => self.vec.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()),
}
}
/// Returns a byte slice of this `String`'s contents.
///
/// The inverse of this method is [`from_utf8`].
///
2020-07-18 10:14:00 -07:00
/// [`from_utf8`]: String::from_utf8
///
/// # Examples
///
/// ```
/// let s = String::from("hello");
///
/// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
/// ```
#[inline]
2021-10-11 13:57:38 -04:00
#[must_use]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn as_bytes(&self) -> &[u8] {
&self.vec
}
/// Shortens this `String` to the specified length.
///
/// If `new_len` is greater than the string's current length, this has no
/// effect.
///
/// Note that this method has no effect on the allocated capacity
/// of the string
///
/// # Panics
///
/// Panics if `new_len` does not lie on a [`char`] boundary.
///
/// # Examples
///
/// ```
/// let mut s = String::from("hello");
///
/// s.truncate(2);
///
/// assert_eq!("he", s);
/// ```
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-02-04 21:17:19 -05:00
pub fn truncate(&mut self, new_len: usize) {
if new_len <= self.len() {
assert!(self.is_char_boundary(new_len));
self.vec.truncate(new_len)
}
}
/// Removes the last character from the string buffer and returns it.
///
/// Returns [`None`] if this `String` is empty.
///
/// # Examples
///
/// ```
/// let mut s = String::from("abč");
///
/// assert_eq!(s.pop(), Some('č'));
/// assert_eq!(s.pop(), Some('b'));
/// assert_eq!(s.pop(), Some('a'));
///
collections: Stabilize String # Rationale When dealing with strings, many functions deal with either a `char` (unicode codepoint) or a byte (utf-8 encoding related). There is often an inconsistent way in which methods are referred to as to whether they contain "byte", "char", or nothing in their name. There are also issues open to rename *all* methods to reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or byte_len()). The current state of String seems to largely be what is desired, so this PR proposes the following rationale for methods dealing with bytes or characters: > When constructing a string, the input encoding *must* be mentioned (e.g. > from_utf8). This makes it clear what exactly the input type is expected to be > in terms of encoding. > > When a method operates on anything related to an *index* within the string > such as length, capacity, position, etc, the method *implicitly* operates on > bytes. It is an understood fact that String is a utf-8 encoded string, and > burdening all methods with "bytes" would be redundant. > > When a method operates on the *contents* of a string, such as push() or pop(), > then "char" is the default type. A String can loosely be thought of as being a > collection of unicode codepoints, but not all collection-related operations > make sense because some can be woefully inefficient. # Method stabilization The following methods have been marked #[stable] * The String type itself * String::new * String::with_capacity * String::from_utf16_lossy * String::into_bytes * String::as_bytes * String::len * String::clear * String::as_slice The following methods have been marked #[unstable] * String::from_utf8 - The error type in the returned `Result` may change to provide a nicer message when it's `unwrap()`'d * String::from_utf8_lossy - The returned `MaybeOwned` type still needs stabilization * String::from_utf16 - The return type may change to become a `Result` which includes more contextual information like where the error occurred. * String::from_chars - This is equivalent to iter().collect(), but currently not as ergonomic. * String::from_char - This method is the equivalent of Vec::from_elem, and has been marked #[unstable] becuase it can be seen as a duplicate of iterator-based functionality as well as possibly being renamed. * String::push_str - This *can* be emulated with .extend(foo.chars()), but is less efficient because of decoding/encoding. Due to the desire to minimize API surface this may be able to be removed in the future for something possibly generic with no loss in performance. * String::grow - This is a duplicate of iterator-based functionality, which may become more ergonomic in the future. * String::capacity - This function was just added. * String::push - This function was just added. * String::pop - This function was just added. * String::truncate - The failure conventions around String methods and byte indices isn't totally clear at this time, so the failure semantics and return value of this method are subject to change. * String::as_mut_vec - the naming of this method may change. * string::raw::* - these functions are all waiting on [an RFC][2] [2]: https://github.com/rust-lang/rfcs/pull/240 The following method have been marked #[experimental] * String::from_str - This function only exists as it's more efficient than to_string(), but having a less ergonomic function for performance reasons isn't the greatest reason to keep it around. Like Vec::push_all, this has been marked experimental for now. The following methods have been #[deprecated] * String::append - This method has been deprecated to remain consistent with the deprecation of Vec::append. While convenient, it is one of the only functional-style apis on String, and requires more though as to whether it belongs as a first-class method or now (and how it relates to other collections). * String::from_byte - This is fairly rare functionality and can be emulated with str::from_utf8 plus an assert plus a call to to_string(). Additionally, String::from_char could possibly be used. * String::byte_capacity - Renamed to String::capacity due to the rationale above. * String::push_char - Renamed to String::push due to the rationale above. * String::pop_char - Renamed to String::pop due to the rationale above. * String::push_bytes - There are a number of `unsafe` functions on the `String` type which allow bypassing utf-8 checks. These have all been deprecated in favor of calling `.as_mut_vec()` and then operating directly on the vector returned. These methods were deprecated because naming them with relation to other methods was difficult to rationalize and it's arguably more composable to call .as_mut_vec(). * String::as_mut_bytes - See push_bytes * String::push_byte - See push_bytes * String::pop_byte - See push_bytes * String::shift_byte - See push_bytes # Reservation methods This commit does not yet touch the methods for reserving bytes. The methods on Vec have also not yet been modified. These methods are discussed in the upcoming [Collections reform RFC][1] [1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
/// assert_eq!(s.pop(), None);
/// ```
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
collections: Stabilize String # Rationale When dealing with strings, many functions deal with either a `char` (unicode codepoint) or a byte (utf-8 encoding related). There is often an inconsistent way in which methods are referred to as to whether they contain "byte", "char", or nothing in their name. There are also issues open to rename *all* methods to reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or byte_len()). The current state of String seems to largely be what is desired, so this PR proposes the following rationale for methods dealing with bytes or characters: > When constructing a string, the input encoding *must* be mentioned (e.g. > from_utf8). This makes it clear what exactly the input type is expected to be > in terms of encoding. > > When a method operates on anything related to an *index* within the string > such as length, capacity, position, etc, the method *implicitly* operates on > bytes. It is an understood fact that String is a utf-8 encoded string, and > burdening all methods with "bytes" would be redundant. > > When a method operates on the *contents* of a string, such as push() or pop(), > then "char" is the default type. A String can loosely be thought of as being a > collection of unicode codepoints, but not all collection-related operations > make sense because some can be woefully inefficient. # Method stabilization The following methods have been marked #[stable] * The String type itself * String::new * String::with_capacity * String::from_utf16_lossy * String::into_bytes * String::as_bytes * String::len * String::clear * String::as_slice The following methods have been marked #[unstable] * String::from_utf8 - The error type in the returned `Result` may change to provide a nicer message when it's `unwrap()`'d * String::from_utf8_lossy - The returned `MaybeOwned` type still needs stabilization * String::from_utf16 - The return type may change to become a `Result` which includes more contextual information like where the error occurred. * String::from_chars - This is equivalent to iter().collect(), but currently not as ergonomic. * String::from_char - This method is the equivalent of Vec::from_elem, and has been marked #[unstable] becuase it can be seen as a duplicate of iterator-based functionality as well as possibly being renamed. * String::push_str - This *can* be emulated with .extend(foo.chars()), but is less efficient because of decoding/encoding. Due to the desire to minimize API surface this may be able to be removed in the future for something possibly generic with no loss in performance. * String::grow - This is a duplicate of iterator-based functionality, which may become more ergonomic in the future. * String::capacity - This function was just added. * String::push - This function was just added. * String::pop - This function was just added. * String::truncate - The failure conventions around String methods and byte indices isn't totally clear at this time, so the failure semantics and return value of this method are subject to change. * String::as_mut_vec - the naming of this method may change. * string::raw::* - these functions are all waiting on [an RFC][2] [2]: https://github.com/rust-lang/rfcs/pull/240 The following method have been marked #[experimental] * String::from_str - This function only exists as it's more efficient than to_string(), but having a less ergonomic function for performance reasons isn't the greatest reason to keep it around. Like Vec::push_all, this has been marked experimental for now. The following methods have been #[deprecated] * String::append - This method has been deprecated to remain consistent with the deprecation of Vec::append. While convenient, it is one of the only functional-style apis on String, and requires more though as to whether it belongs as a first-class method or now (and how it relates to other collections). * String::from_byte - This is fairly rare functionality and can be emulated with str::from_utf8 plus an assert plus a call to to_string(). Additionally, String::from_char could possibly be used. * String::byte_capacity - Renamed to String::capacity due to the rationale above. * String::push_char - Renamed to String::push due to the rationale above. * String::pop_char - Renamed to String::pop due to the rationale above. * String::push_bytes - There are a number of `unsafe` functions on the `String` type which allow bypassing utf-8 checks. These have all been deprecated in favor of calling `.as_mut_vec()` and then operating directly on the vector returned. These methods were deprecated because naming them with relation to other methods was difficult to rationalize and it's arguably more composable to call .as_mut_vec(). * String::as_mut_bytes - See push_bytes * String::push_byte - See push_bytes * String::pop_byte - See push_bytes * String::shift_byte - See push_bytes # Reservation methods This commit does not yet touch the methods for reserving bytes. The methods on Vec have also not yet been modified. These methods are discussed in the upcoming [Collections reform RFC][1] [1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
pub fn pop(&mut self) -> Option<char> {
let ch = self.chars().rev().next()?;
std: Stabilize APIs for the 1.9 release This commit applies all stabilizations, renamings, and deprecations that the library team has decided on for the upcoming 1.9 release. All tracking issues have gone through a cycle-long "final comment period" and the specific APIs stabilized/deprecated are: Stable * `std::panic` * `std::panic::catch_unwind` (renamed from `recover`) * `std::panic::resume_unwind` (renamed from `propagate`) * `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`) * `std::panic::UnwindSafe` (renamed from `RecoverSafe`) * `str::is_char_boundary` * `<*const T>::as_ref` * `<*mut T>::as_ref` * `<*mut T>::as_mut` * `AsciiExt::make_ascii_uppercase` * `AsciiExt::make_ascii_lowercase` * `char::decode_utf16` * `char::DecodeUtf16` * `char::DecodeUtf16Error` * `char::DecodeUtf16Error::unpaired_surrogate` * `BTreeSet::take` * `BTreeSet::replace` * `BTreeSet::get` * `HashSet::take` * `HashSet::replace` * `HashSet::get` * `OsString::with_capacity` * `OsString::clear` * `OsString::capacity` * `OsString::reserve` * `OsString::reserve_exact` * `OsStr::is_empty` * `OsStr::len` * `std::os::unix::thread` * `RawPthread` * `JoinHandleExt` * `JoinHandleExt::as_pthread_t` * `JoinHandleExt::into_pthread_t` * `HashSet::hasher` * `HashMap::hasher` * `CommandExt::exec` * `File::try_clone` * `SocketAddr::set_ip` * `SocketAddr::set_port` * `SocketAddrV4::set_ip` * `SocketAddrV4::set_port` * `SocketAddrV6::set_ip` * `SocketAddrV6::set_port` * `SocketAddrV6::set_flowinfo` * `SocketAddrV6::set_scope_id` * `<[T]>::copy_from_slice` * `ptr::read_volatile` * `ptr::write_volatile` * The `#[deprecated]` attribute * `OpenOptions::create_new` Deprecated * `std::raw::Slice` - use raw parts of `slice` module instead * `std::raw::Repr` - use raw parts of `slice` module instead * `str::char_range_at` - use slicing plus `chars()` plus `len_utf8` * `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8` * `str::char_at` - use slicing plus `chars()` * `str::char_at_reverse` - use slicing plus `chars().rev()` * `str::slice_shift_char` - use `chars()` plus `Chars::as_str` * `CommandExt::session_leader` - use `before_exec` instead. Closes #27719 cc #27751 (deprecating the `Slice` bits) Closes #27754 Closes #27780 Closes #27809 Closes #27811 Closes #27830 Closes #28050 Closes #29453 Closes #29791 Closes #29935 Closes #30014 Closes #30752 Closes #31262 cc #31398 (still need to deal with `before_exec`) Closes #31405 Closes #31572 Closes #31755 Closes #31756
2016-04-07 10:42:53 -07:00
let newlen = self.len() - ch.len_utf8();
unsafe {
std: Stabilize APIs for the 1.9 release This commit applies all stabilizations, renamings, and deprecations that the library team has decided on for the upcoming 1.9 release. All tracking issues have gone through a cycle-long "final comment period" and the specific APIs stabilized/deprecated are: Stable * `std::panic` * `std::panic::catch_unwind` (renamed from `recover`) * `std::panic::resume_unwind` (renamed from `propagate`) * `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`) * `std::panic::UnwindSafe` (renamed from `RecoverSafe`) * `str::is_char_boundary` * `<*const T>::as_ref` * `<*mut T>::as_ref` * `<*mut T>::as_mut` * `AsciiExt::make_ascii_uppercase` * `AsciiExt::make_ascii_lowercase` * `char::decode_utf16` * `char::DecodeUtf16` * `char::DecodeUtf16Error` * `char::DecodeUtf16Error::unpaired_surrogate` * `BTreeSet::take` * `BTreeSet::replace` * `BTreeSet::get` * `HashSet::take` * `HashSet::replace` * `HashSet::get` * `OsString::with_capacity` * `OsString::clear` * `OsString::capacity` * `OsString::reserve` * `OsString::reserve_exact` * `OsStr::is_empty` * `OsStr::len` * `std::os::unix::thread` * `RawPthread` * `JoinHandleExt` * `JoinHandleExt::as_pthread_t` * `JoinHandleExt::into_pthread_t` * `HashSet::hasher` * `HashMap::hasher` * `CommandExt::exec` * `File::try_clone` * `SocketAddr::set_ip` * `SocketAddr::set_port` * `SocketAddrV4::set_ip` * `SocketAddrV4::set_port` * `SocketAddrV6::set_ip` * `SocketAddrV6::set_port` * `SocketAddrV6::set_flowinfo` * `SocketAddrV6::set_scope_id` * `<[T]>::copy_from_slice` * `ptr::read_volatile` * `ptr::write_volatile` * The `#[deprecated]` attribute * `OpenOptions::create_new` Deprecated * `std::raw::Slice` - use raw parts of `slice` module instead * `std::raw::Repr` - use raw parts of `slice` module instead * `str::char_range_at` - use slicing plus `chars()` plus `len_utf8` * `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8` * `str::char_at` - use slicing plus `chars()` * `str::char_at_reverse` - use slicing plus `chars().rev()` * `str::slice_shift_char` - use `chars()` plus `Chars::as_str` * `CommandExt::session_leader` - use `before_exec` instead. Closes #27719 cc #27751 (deprecating the `Slice` bits) Closes #27754 Closes #27780 Closes #27809 Closes #27811 Closes #27830 Closes #28050 Closes #29453 Closes #29791 Closes #29935 Closes #30014 Closes #30752 Closes #31262 cc #31398 (still need to deal with `before_exec`) Closes #31405 Closes #31572 Closes #31755 Closes #31756
2016-04-07 10:42:53 -07:00
self.vec.set_len(newlen);
}
Some(ch)
}
/// Removes a [`char`] from this `String` at a byte position and returns it.
///
/// This is an *O*(*n*) operation, as it requires copying every element in the
/// buffer.
///
/// # Panics
///
/// Panics if `idx` is larger than or equal to the `String`'s length,
/// or if it does not lie on a [`char`] boundary.
///
/// # Examples
///
/// ```
/// let mut s = String::from("abç");
///
/// assert_eq!(s.remove(0), 'a');
/// assert_eq!(s.remove(1), 'ç');
/// assert_eq!(s.remove(0), 'b');
/// ```
2015-01-10 11:07:14 +01:00
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_confusables("delete", "take")]
2015-02-04 21:17:19 -05:00
pub fn remove(&mut self, idx: usize) -> char {
std: Stabilize APIs for the 1.9 release This commit applies all stabilizations, renamings, and deprecations that the library team has decided on for the upcoming 1.9 release. All tracking issues have gone through a cycle-long "final comment period" and the specific APIs stabilized/deprecated are: Stable * `std::panic` * `std::panic::catch_unwind` (renamed from `recover`) * `std::panic::resume_unwind` (renamed from `propagate`) * `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`) * `std::panic::UnwindSafe` (renamed from `RecoverSafe`) * `str::is_char_boundary` * `<*const T>::as_ref` * `<*mut T>::as_ref` * `<*mut T>::as_mut` * `AsciiExt::make_ascii_uppercase` * `AsciiExt::make_ascii_lowercase` * `char::decode_utf16` * `char::DecodeUtf16` * `char::DecodeUtf16Error` * `char::DecodeUtf16Error::unpaired_surrogate` * `BTreeSet::take` * `BTreeSet::replace` * `BTreeSet::get` * `HashSet::take` * `HashSet::replace` * `HashSet::get` * `OsString::with_capacity` * `OsString::clear` * `OsString::capacity` * `OsString::reserve` * `OsString::reserve_exact` * `OsStr::is_empty` * `OsStr::len` * `std::os::unix::thread` * `RawPthread` * `JoinHandleExt` * `JoinHandleExt::as_pthread_t` * `JoinHandleExt::into_pthread_t` * `HashSet::hasher` * `HashMap::hasher` * `CommandExt::exec` * `File::try_clone` * `SocketAddr::set_ip` * `SocketAddr::set_port` * `SocketAddrV4::set_ip` * `SocketAddrV4::set_port` * `SocketAddrV6::set_ip` * `SocketAddrV6::set_port` * `SocketAddrV6::set_flowinfo` * `SocketAddrV6::set_scope_id` * `<[T]>::copy_from_slice` * `ptr::read_volatile` * `ptr::write_volatile` * The `#[deprecated]` attribute * `OpenOptions::create_new` Deprecated * `std::raw::Slice` - use raw parts of `slice` module instead * `std::raw::Repr` - use raw parts of `slice` module instead * `str::char_range_at` - use slicing plus `chars()` plus `len_utf8` * `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8` * `str::char_at` - use slicing plus `chars()` * `str::char_at_reverse` - use slicing plus `chars().rev()` * `str::slice_shift_char` - use `chars()` plus `Chars::as_str` * `CommandExt::session_leader` - use `before_exec` instead. Closes #27719 cc #27751 (deprecating the `Slice` bits) Closes #27754 Closes #27780 Closes #27809 Closes #27811 Closes #27830 Closes #28050 Closes #29453 Closes #29791 Closes #29935 Closes #30014 Closes #30752 Closes #31262 cc #31398 (still need to deal with `before_exec`) Closes #31405 Closes #31572 Closes #31755 Closes #31756
2016-04-07 10:42:53 -07:00
let ch = match self[idx..].chars().next() {
Some(ch) => ch,
None => panic!("cannot remove a char from the end of a string"),
};
let next = idx + ch.len_utf8();
std: Stabilize APIs for the 1.9 release This commit applies all stabilizations, renamings, and deprecations that the library team has decided on for the upcoming 1.9 release. All tracking issues have gone through a cycle-long "final comment period" and the specific APIs stabilized/deprecated are: Stable * `std::panic` * `std::panic::catch_unwind` (renamed from `recover`) * `std::panic::resume_unwind` (renamed from `propagate`) * `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`) * `std::panic::UnwindSafe` (renamed from `RecoverSafe`) * `str::is_char_boundary` * `<*const T>::as_ref` * `<*mut T>::as_ref` * `<*mut T>::as_mut` * `AsciiExt::make_ascii_uppercase` * `AsciiExt::make_ascii_lowercase` * `char::decode_utf16` * `char::DecodeUtf16` * `char::DecodeUtf16Error` * `char::DecodeUtf16Error::unpaired_surrogate` * `BTreeSet::take` * `BTreeSet::replace` * `BTreeSet::get` * `HashSet::take` * `HashSet::replace` * `HashSet::get` * `OsString::with_capacity` * `OsString::clear` * `OsString::capacity` * `OsString::reserve` * `OsString::reserve_exact` * `OsStr::is_empty` * `OsStr::len` * `std::os::unix::thread` * `RawPthread` * `JoinHandleExt` * `JoinHandleExt::as_pthread_t` * `JoinHandleExt::into_pthread_t` * `HashSet::hasher` * `HashMap::hasher` * `CommandExt::exec` * `File::try_clone` * `SocketAddr::set_ip` * `SocketAddr::set_port` * `SocketAddrV4::set_ip` * `SocketAddrV4::set_port` * `SocketAddrV6::set_ip` * `SocketAddrV6::set_port` * `SocketAddrV6::set_flowinfo` * `SocketAddrV6::set_scope_id` * `<[T]>::copy_from_slice` * `ptr::read_volatile` * `ptr::write_volatile` * The `#[deprecated]` attribute * `OpenOptions::create_new` Deprecated * `std::raw::Slice` - use raw parts of `slice` module instead * `std::raw::Repr` - use raw parts of `slice` module instead * `str::char_range_at` - use slicing plus `chars()` plus `len_utf8` * `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8` * `str::char_at` - use slicing plus `chars()` * `str::char_at_reverse` - use slicing plus `chars().rev()` * `str::slice_shift_char` - use `chars()` plus `Chars::as_str` * `CommandExt::session_leader` - use `before_exec` instead. Closes #27719 cc #27751 (deprecating the `Slice` bits) Closes #27754 Closes #27780 Closes #27809 Closes #27811 Closes #27830 Closes #28050 Closes #29453 Closes #29791 Closes #29935 Closes #30014 Closes #30752 Closes #31262 cc #31398 (still need to deal with `before_exec`) Closes #31405 Closes #31572 Closes #31755 Closes #31756
2016-04-07 10:42:53 -07:00
let len = self.len();
unsafe {
ptr::copy(self.vec.as_ptr().add(next), self.vec.as_mut_ptr().add(idx), len - next);
self.vec.set_len(len - (next - idx));
}
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
ch
}
2021-03-05 11:27:58 -05:00
/// Remove all matches of pattern `pat` in the `String`.
///
/// # Examples
///
/// ```
/// #![feature(string_remove_matches)]
/// let mut s = String::from("Trees are not green, the sky is not blue.");
/// s.remove_matches("not ");
/// assert_eq!("Trees are green, the sky is blue.", s);
/// ```
///
/// Matches will be detected and removed iteratively, so in cases where
/// patterns overlap, only the first pattern will be removed:
///
/// ```
/// #![feature(string_remove_matches)]
/// let mut s = String::from("banana");
/// s.remove_matches("ana");
/// assert_eq!("bna", s);
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2021-03-05 11:27:58 -05:00
#[unstable(feature = "string_remove_matches", reason = "new API", issue = "72826")]
pub fn remove_matches<'a, P>(&'a mut self, pat: P)
where
P: for<'x> Pattern<'x>,
{
use core::str::pattern::Searcher;
let rejections = {
2021-03-05 11:27:58 -05:00
let mut searcher = pat.into_searcher(self);
// Per Searcher::next:
//
// A Match result needs to contain the whole matched pattern,
// however Reject results may be split up into arbitrary many
// adjacent fragments. Both ranges may have zero length.
//
// In practice the implementation of Searcher::next_match tends to
// be more efficient, so we use it here and do some work to invert
// matches into rejections since that's what we want to copy below.
let mut front = 0;
let rejections: Vec<_> = from_fn(|| {
let (start, end) = searcher.next_match()?;
let prev_front = front;
front = end;
Some((prev_front, start))
})
.collect();
rejections.into_iter().chain(core::iter::once((front, self.len())))
2021-03-05 11:27:58 -05:00
};
let mut len = 0;
let ptr = self.vec.as_mut_ptr();
2021-03-05 11:27:58 -05:00
for (start, end) in rejections {
let count = end - start;
if start != len {
// SAFETY: per Searcher::next:
//
// The stream of Match and Reject values up to a Done will
// contain index ranges that are adjacent, non-overlapping,
// covering the whole haystack, and laying on utf8
// boundaries.
unsafe {
ptr::copy(ptr.add(start), ptr.add(len), count);
}
2021-03-05 11:27:58 -05:00
}
len += count;
}
unsafe {
self.vec.set_len(len);
2021-03-05 11:27:58 -05:00
}
}
/// Retains only the characters specified by the predicate.
///
/// In other words, remove all characters `c` such that `f(c)` returns `false`.
/// This method operates in place, visiting each character exactly once in the
/// original order, and preserves the order of the retained characters.
///
/// # Examples
///
/// ```
/// let mut s = String::from("f_o_ob_ar");
///
/// s.retain(|c| c != '_');
///
/// assert_eq!(s, "foobar");
/// ```
2019-05-10 18:01:50 -07:00
///
/// Because the elements are visited exactly once in the original order,
/// external state may be used to decide which elements to keep.
2019-05-10 18:01:50 -07:00
///
/// ```
/// let mut s = String::from("abcde");
/// let keep = [false, true, true, false, true];
/// let mut iter = keep.iter();
/// s.retain(|_| *iter.next().unwrap());
2019-05-10 18:01:50 -07:00
/// assert_eq!(s, "bce");
/// ```
#[inline]
2018-03-21 10:47:03 -07:00
#[stable(feature = "string_retain", since = "1.26.0")]
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(char) -> bool,
{
struct SetLenOnDrop<'a> {
s: &'a mut String,
idx: usize,
del_bytes: usize,
}
impl<'a> Drop for SetLenOnDrop<'a> {
fn drop(&mut self) {
let new_len = self.idx - self.del_bytes;
debug_assert!(new_len <= self.s.len());
unsafe { self.s.vec.set_len(new_len) };
}
}
let len = self.len();
let mut guard = SetLenOnDrop { s: self, idx: 0, del_bytes: 0 };
while guard.idx < len {
let ch =
// SAFETY: `guard.idx` is positive-or-zero and less that len so the `get_unchecked`
// is in bound. `self` is valid UTF-8 like string and the returned slice starts at
// a unicode code point so the `Chars` always return one character.
unsafe { guard.s.get_unchecked(guard.idx..len).chars().next().unwrap_unchecked() };
let ch_len = ch.len_utf8();
if !f(ch) {
guard.del_bytes += ch_len;
} else if guard.del_bytes > 0 {
// SAFETY: `guard.idx` is in bound and `guard.del_bytes` represent the number of
// bytes that are erased from the string so the resulting `guard.idx -
// guard.del_bytes` always represent a valid unicode code point.
//
// `guard.del_bytes` >= `ch.len_utf8()`, so taking a slice with `ch.len_utf8()` len
// is safe.
ch.encode_utf8(unsafe {
crate::slice::from_raw_parts_mut(
guard.s.as_mut_ptr().add(guard.idx - guard.del_bytes),
ch.len_utf8(),
)
});
}
// Point idx to the next char
guard.idx += ch_len;
}
drop(guard);
}
/// Inserts a character into this `String` at a byte position.
///
/// This is an *O*(*n*) operation as it requires copying every element in the
/// buffer.
///
/// # Panics
///
/// Panics if `idx` is larger than the `String`'s length, or if it does not
/// lie on a [`char`] boundary.
///
/// # Examples
///
/// ```
/// let mut s = String::with_capacity(3);
///
/// s.insert(0, 'f');
/// s.insert(1, 'o');
/// s.insert(2, 'o');
///
/// assert_eq!("foo", s);
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2015-01-10 11:07:14 +01:00
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_confusables("set")]
2015-02-04 21:17:19 -05:00
pub fn insert(&mut self, idx: usize, ch: char) {
assert!(self.is_char_boundary(idx));
let mut bits = [0; 4];
let bits = ch.encode_utf8(&mut bits).as_bytes();
2016-07-11 15:06:28 -07:00
unsafe {
self.insert_bytes(idx, bits);
2016-07-11 15:06:28 -07:00
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2016-07-11 15:06:28 -07:00
unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
let len = self.len();
let amt = bytes.len();
self.vec.reserve(amt);
unsafe {
ptr::copy(self.vec.as_ptr().add(idx), self.vec.as_mut_ptr().add(idx + amt), len - idx);
ptr::copy_nonoverlapping(bytes.as_ptr(), self.vec.as_mut_ptr().add(idx), amt);
self.vec.set_len(len + amt);
}
2016-07-11 15:06:28 -07:00
}
/// Inserts a string slice into this `String` at a byte position.
2016-07-11 15:06:28 -07:00
///
/// This is an *O*(*n*) operation as it requires copying every element in the
2016-07-11 15:06:28 -07:00
/// buffer.
///
/// # Panics
///
/// Panics if `idx` is larger than the `String`'s length, or if it does not
/// lie on a [`char`] boundary.
///
/// # Examples
///
/// ```
/// let mut s = String::from("bar");
///
/// s.insert_str(0, "foo");
///
/// assert_eq!("foobar", s);
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2016-07-11 15:06:28 -07:00
#[inline]
#[stable(feature = "insert_str", since = "1.16.0")]
2016-07-11 15:06:28 -07:00
pub fn insert_str(&mut self, idx: usize, string: &str) {
assert!(self.is_char_boundary(idx));
unsafe {
2016-07-11 15:06:28 -07:00
self.insert_bytes(idx, string.as_bytes());
}
}
/// Returns a mutable reference to the contents of this `String`.
///
/// # Safety
///
/// This function is unsafe because the returned `&mut Vec` allows writing
/// bytes which are not valid UTF-8. If this constraint is violated, using
/// the original `String` after dropping the `&mut Vec` may violate memory
/// safety, as the rest of the standard library assumes that `String`s are
/// valid UTF-8.
///
/// # Examples
///
/// ```
/// let mut s = String::from("hello");
///
/// unsafe {
/// let vec = s.as_mut_vec();
/// assert_eq!(&[104, 101, 108, 108, 111][..], &vec[..]);
///
/// vec.reverse();
/// }
/// assert_eq!(s, "olleh");
/// ```
2015-01-10 11:07:14 +01:00
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
&mut self.vec
}
/// Returns the length of this `String`, in bytes, not [`char`]s or
/// graphemes. In other words, it might not be what a human considers the
/// length of the string.
///
/// # Examples
///
/// ```
/// let a = String::from("foo");
/// assert_eq!(a.len(), 3);
///
/// let fancy_f = String::from("ƒoo");
/// assert_eq!(fancy_f.len(), 4);
/// assert_eq!(fancy_f.chars().count(), 3);
/// ```
#[inline]
2021-10-11 16:15:50 -04:00
#[must_use]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_confusables("length", "size")]
2015-11-24 11:23:48 +13:00
pub fn len(&self) -> usize {
self.vec.len()
}
2019-02-09 22:16:58 +00:00
/// Returns `true` if this `String` has a length of zero, and `false` otherwise.
///
/// # Examples
///
/// ```
/// let mut v = String::new();
/// assert!(v.is_empty());
///
/// v.push('a');
/// assert!(!v.is_empty());
/// ```
2015-01-10 11:07:14 +01:00
#[inline]
2021-10-11 16:15:50 -04:00
#[must_use]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-11-24 11:23:48 +13:00
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Splits the string into two at the given byte index.
2016-11-28 13:54:55 -05:00
///
/// Returns a newly allocated `String`. `self` contains bytes `[0, at)`, and
/// the returned `String` contains bytes `[at, len)`. `at` must be on the
/// boundary of a UTF-8 code point.
2016-11-28 13:54:55 -05:00
///
/// Note that the capacity of `self` does not change.
2016-11-28 13:54:55 -05:00
///
/// # Panics
///
/// Panics if `at` is not on a `UTF-8` code point boundary, or if it is beyond the last
2016-11-28 13:54:55 -05:00
/// code point of the string.
///
/// # Examples
///
/// ```
/// # fn main() {
/// let mut hello = String::from("Hello, World!");
/// let world = hello.split_off(7);
/// assert_eq!(hello, "Hello, ");
/// assert_eq!(world, "World!");
/// # }
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2016-11-28 13:54:55 -05:00
#[inline]
#[stable(feature = "string_split_off", since = "1.16.0")]
2020-03-24 13:33:35 +00:00
#[must_use = "use `.truncate()` if you don't need the other half"]
pub fn split_off(&mut self, at: usize) -> String {
assert!(self.is_char_boundary(at));
let other = self.vec.split_off(at);
2016-11-28 13:54:55 -05:00
unsafe { String::from_utf8_unchecked(other) }
}
/// Truncates this `String`, removing all contents.
///
/// While this means the `String` will have a length of zero, it does not
/// touch its capacity.
///
/// # Examples
///
/// ```
/// let mut s = String::from("foo");
///
/// s.clear();
///
/// assert!(s.is_empty());
/// assert_eq!(0, s.len());
/// assert_eq!(3, s.capacity());
/// ```
2014-05-11 03:49:09 -07:00
#[inline]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub fn clear(&mut self) {
2014-05-11 03:49:09 -07:00
self.vec.clear()
}
/// Removes the specified range from the string in bulk, returning all
/// removed characters as an iterator.
///
/// The returned iterator keeps a mutable borrow on the string to optimize
/// its implementation.
///
/// # Panics
///
/// Panics if the starting point or end point do not lie on a [`char`]
/// boundary, or if they're out of bounds.
///
/// # Leaking
///
/// If the returned iterator goes out of scope without being dropped (due to
/// [`core::mem::forget`], for example), the string may still contain a copy
/// of any drained characters, or may have lost characters arbitrarily,
/// including characters outside the range.
///
/// # Examples
///
/// ```
/// let mut s = String::from("α is alpha, β is beta");
/// let beta_offset = s.find('β').unwrap_or(s.len());
///
/// // Remove the range up until the β from the string
/// let t: String = s.drain(..beta_offset).collect();
/// assert_eq!(t, "α is alpha, ");
/// assert_eq!(s, "β is beta");
///
/// // A full range clears the string, like `clear()` does
/// s.drain(..);
/// assert_eq!(s, "");
/// ```
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
2019-02-02 12:48:12 +01:00
pub fn drain<R>(&mut self, range: R) -> Drain<'_>
where
R: RangeBounds<usize>,
2015-11-24 11:23:48 +13:00
{
// Memory safety
//
// The String version of Drain does not have the memory safety issues
// of the vector version. The data is just plain bytes.
// Because the range removal happens in Drop, if the Drain iterator is leaked,
// the removal will not happen.
let Range { start, end } = slice::range(range, ..self.len());
assert!(self.is_char_boundary(start));
assert!(self.is_char_boundary(end));
// Take out two simultaneous borrows. The &mut String won't be accessed
// until iteration is over, in Drop.
let self_ptr = self as *mut _;
// SAFETY: `slice::range` and `is_char_boundary` do the appropriate bounds checks.
let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
Drain { start, end, iter: chars_iter, string: self_ptr }
}
/// Removes the specified range in the string,
/// and replaces it with the given string.
/// The given string doesn't need to be the same length as the range.
2017-04-08 15:55:53 -05:00
///
/// # Panics
///
/// Panics if the starting point or end point do not lie on a [`char`]
/// boundary, or if they're out of bounds.
///
/// # Examples
///
/// ```
/// let mut s = String::from("α is alpha, β is beta");
/// let beta_offset = s.find('β').unwrap_or(s.len());
///
/// // Replace the range up until the β from the string
/// s.replace_range(..beta_offset, "Α is capital alpha; ");
2017-04-08 15:55:53 -05:00
/// assert_eq!(s, "Α is capital alpha; β is beta");
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "splice", since = "1.27.0")]
pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
where
R: RangeBounds<usize>,
2017-04-08 15:55:53 -05:00
{
// Memory safety
//
// Replace_range does not have the memory safety issues of a vector Splice.
2017-04-08 15:55:53 -05:00
// of the vector version. The data is just plain bytes.
// WARNING: Inlining this variable would be unsound (#81138)
let start = range.start_bound();
match start {
Included(&n) => assert!(self.is_char_boundary(n)),
Excluded(&n) => assert!(self.is_char_boundary(n + 1)),
Unbounded => {}
2017-04-08 16:12:58 -05:00
};
// WARNING: Inlining this variable would be unsound (#81138)
let end = range.end_bound();
match end {
Included(&n) => assert!(self.is_char_boundary(n + 1)),
Excluded(&n) => assert!(self.is_char_boundary(n)),
Unbounded => {}
2017-04-08 16:12:58 -05:00
};
2017-04-08 15:55:53 -05:00
// Using `range` again would be unsound (#81138)
// We assume the bounds reported by `range` remain the same, but
// an adversarial implementation could change between calls
unsafe { self.as_mut_vec() }.splice((start, end), replace_with.bytes());
2017-04-08 15:55:53 -05:00
}
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// Converts this `String` into a <code>[Box]<[str]></code>.
///
/// This will drop any excess capacity.
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [str]: prim@str "str"
///
/// # Examples
///
/// ```
/// let s = String::from("hello");
///
/// let b = s.into_boxed_str();
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
std: Stabilize/deprecate features for 1.4 The FCP is coming to a close and 1.4 is coming out soon, so this brings in the libs team decision for all library features this cycle. Stabilized APIs: * `<Box<str>>::into_string` * `Arc::downgrade` * `Arc::get_mut` * `Arc::make_mut` * `Arc::try_unwrap` * `Box::from_raw` * `Box::into_raw` * `CStr::to_str` * `CStr::to_string_lossy` * `CString::from_raw` * `CString::into_raw` * `IntoRawFd::into_raw_fd` * `IntoRawFd` * `IntoRawHandle::into_raw_handle` * `IntoRawHandle` * `IntoRawSocket::into_raw_socket` * `IntoRawSocket` * `Rc::downgrade` * `Rc::get_mut` * `Rc::make_mut` * `Rc::try_unwrap` * `Result::expect` * `String::into_boxed_slice` * `TcpSocket::read_timeout` * `TcpSocket::set_read_timeout` * `TcpSocket::set_write_timeout` * `TcpSocket::write_timeout` * `UdpSocket::read_timeout` * `UdpSocket::set_read_timeout` * `UdpSocket::set_write_timeout` * `UdpSocket::write_timeout` * `Vec::append` * `Vec::split_off` * `VecDeque::append` * `VecDeque::retain` * `VecDeque::split_off` * `rc::Weak::upgrade` * `rc::Weak` * `slice::Iter::as_slice` * `slice::IterMut::into_slice` * `str::CharIndices::as_str` * `str::Chars::as_str` * `str::split_at_mut` * `str::split_at` * `sync::Weak::upgrade` * `sync::Weak` * `thread::park_timeout` * `thread::sleep` Deprecated APIs * `BTreeMap::with_b` * `BTreeSet::with_b` * `Option::as_mut_slice` * `Option::as_slice` * `Result::as_mut_slice` * `Result::as_slice` * `f32::from_str_radix` * `f64::from_str_radix` Closes #27277 Closes #27718 Closes #27736 Closes #27764 Closes #27765 Closes #27766 Closes #27767 Closes #27768 Closes #27769 Closes #27771 Closes #27773 Closes #27775 Closes #27776 Closes #27785 Closes #27792 Closes #27795 Closes #27797
2015-09-10 13:26:44 -07:00
#[stable(feature = "box_str", since = "1.4.0")]
#[must_use = "`self` will be dropped if the result is not used"]
#[inline]
pub fn into_boxed_str(self) -> Box<str> {
let slice = self.vec.into_boxed_slice();
2017-06-13 15:52:59 -07:00
unsafe { from_boxed_utf8_unchecked(slice) }
}
2022-10-19 19:15:58 -07:00
/// Consumes and leaks the `String`, returning a mutable reference to the contents,
/// `&'a mut str`.
2022-10-19 19:15:58 -07:00
///
2023-03-31 13:39:27 +02:00
/// The caller has free choice over the returned lifetime, including `'static`. Indeed,
/// this function is ideally used for data that lives for the remainder of the program's life,
/// as dropping the returned reference will cause a memory leak.
2022-10-19 19:15:58 -07:00
///
/// It does not reallocate or shrink the `String`,
/// so the leaked allocation may include unused capacity that is not part
2023-03-31 13:39:27 +02:00
/// of the returned slice. If you don't want that, call [`into_boxed_str`],
/// and then [`Box::leak`].
///
/// [`into_boxed_str`]: Self::into_boxed_str
2022-10-19 19:15:58 -07:00
///
/// # Examples
///
/// ```
/// let x = String::from("bucket");
/// let static_ref: &'static mut str = x.leak();
/// assert_eq!(static_ref, "bucket");
/// ```
2023-07-10 10:41:13 -04:00
#[stable(feature = "string_leak", since = "1.72.0")]
2022-10-19 19:15:58 -07:00
#[inline]
pub fn leak<'a>(self) -> &'a mut str {
2022-10-19 19:15:58 -07:00
let slice = self.vec.leak();
unsafe { from_utf8_unchecked_mut(slice) }
}
2014-05-11 03:49:09 -07:00
}
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
impl FromUtf8Error {
/// Returns a slice of [`u8`]s bytes that were attempted to convert to a `String`.
///
/// # Examples
///
/// ```
/// // some invalid bytes, in a vector
/// let bytes = vec![0, 159];
///
/// let value = String::from_utf8(bytes);
///
/// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());
/// ```
2021-10-11 13:57:38 -04:00
#[must_use]
#[stable(feature = "from_utf8_error_as_bytes", since = "1.26.0")]
pub fn as_bytes(&self) -> &[u8] {
&self.bytes[..]
}
/// Returns the bytes that were attempted to convert to a `String`.
///
/// This method is carefully constructed to avoid allocation. It will
/// consume the error, moving out the bytes, so that a copy of the bytes
/// does not need to be made.
///
/// # Examples
///
/// ```
/// // some invalid bytes, in a vector
/// let bytes = vec![0, 159];
///
/// let value = String::from_utf8(bytes);
///
/// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes());
/// ```
#[must_use = "`self` will be dropped if the result is not used"]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-11-24 11:23:48 +13:00
pub fn into_bytes(self) -> Vec<u8> {
self.bytes
}
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
/// Fetch a `Utf8Error` to get more details about the conversion failure.
///
/// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
/// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
/// an analogue to `FromUtf8Error`. See its documentation for more details
/// on using it.
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`std::str`]: core::str "std::str"
/// [`&str`]: prim@str "&str"
///
/// # Examples
///
/// ```
/// // some invalid bytes, in a vector
/// let bytes = vec![0, 159];
///
/// let error = String::from_utf8(bytes).unwrap_err().utf8_error();
///
/// // the first byte is invalid here
/// assert_eq!(1, error.valid_up_to());
/// ```
#[must_use]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-11-24 11:23:48 +13:00
pub fn utf8_error(&self) -> Utf8Error {
self.error
}
std: Second pass stabilization for `string` This commit performs a second pass over the `std::string` module, performing the following actions: * The name `std::string` is now stable. * The `String::from_utf8` function is now stable after having been altered to return a new `FromUtf8Error` structure. The `FromUtf8Error` structure is now stable as well as its `into_bytes` and `utf8_error` methods. * The `String::from_utf8_lossy` function is now stable. * The `String::from_chars` method is now deprecated in favor of `.collect()` * The `String::from_raw_parts` method is now stable * The `String::from_str` function remains experimental * The `String::from_raw_buf` function remains experimental * The `String::from_raw_buf_len` function remains experimental * The `String::from_utf8_unchecked` function is now stable * The `String::from_char` function is now deprecated in favor of `repeat(c).take(n).collect()` * The `String::grow` function is now deprecated in favor of `.extend(repeat(c).take(n)` * The `String::capacity` method is now stable * The `String::reserve` method is now stable * The `String::reserve_exact` method is now stable * The `String::shrink_to_fit` method is now stable * The `String::pop` method is now stable * The `String::as_mut_vec` method is now stable * The `String::is_empty` method is now stable * The `IntoString` trait is now deprecated (there are no implementors) * The `String::truncate` method is now stable * The `String::insert` method is now stable * The `String::remove` method is now stable * The `String::push` method is now stable * The `String::push_str` method is now stable * The `String::from_utf16` function is now stable after its error type has now become an opaque structure to carry more semantic information in the future. A number of these changes are breaking changes, but the migrations should be fairly straightforward on a case-by-case basis (outlined above where possible). [breaking-change]
2014-12-28 10:29:56 -08:00
}
#[stable(feature = "rust1", since = "1.0.0")]
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
impl fmt::Display for FromUtf8Error {
2019-02-02 12:48:12 +01:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
fmt::Display::fmt(&self.error, f)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
impl fmt::Display for FromUtf16Error {
2019-02-02 12:48:12 +01:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
fmt::Display::fmt("invalid utf-16: lone surrogate found", f)
}
}
2022-07-29 18:54:47 +00:00
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for FromUtf8Error {
#[allow(deprecated)]
fn description(&self) -> &str {
"invalid utf-8"
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for FromUtf16Error {
#[allow(deprecated)]
fn description(&self) -> &str {
"invalid utf-16"
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for String {
fn clone(&self) -> Self {
String { vec: self.vec.clone() }
}
/// Clones the contents of `source` into `self`.
///
/// This method is preferred over simply assigning `source.clone()` to `self`,
/// as it avoids reallocation if possible.
fn clone_from(&mut self, source: &Self) {
self.vec.clone_from(&source.vec);
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl FromIterator<char> for String {
fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String {
let mut buf = String::new();
buf.extend(iter);
buf
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2017-02-22 00:06:40 -08:00
#[stable(feature = "string_from_iter_by_ref", since = "1.17.0")]
impl<'a> FromIterator<&'a char> for String {
fn from_iter<I: IntoIterator<Item = &'a char>>(iter: I) -> String {
let mut buf = String::new();
buf.extend(iter);
buf
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> FromIterator<&'a str> for String {
fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> String {
let mut buf = String::new();
buf.extend(iter);
buf
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "extend_string", since = "1.4.0")]
impl FromIterator<String> for String {
fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String {
2018-12-05 15:11:32 -08:00
let mut iterator = iter.into_iter();
2018-12-05 14:37:38 -08:00
2018-12-05 17:46:03 -08:00
// Because we're iterating over `String`s, we can avoid at least
// one allocation by getting the first string from the iterator
// and appending to it all the subsequent strings.
2018-12-05 14:37:38 -08:00
match iterator.next() {
None => String::new(),
2018-12-05 15:11:32 -08:00
Some(mut buf) => {
2018-12-05 14:37:38 -08:00
buf.extend(iterator);
buf
}
}
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_str2", since = "1.45.0")]
impl FromIterator<Box<str>> for String {
fn from_iter<I: IntoIterator<Item = Box<str>>>(iter: I) -> String {
let mut buf = String::new();
buf.extend(iter);
buf
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2017-04-21 13:25:48 -04:00
#[stable(feature = "herd_cows", since = "1.19.0")]
impl<'a> FromIterator<Cow<'a, str>> for String {
fn from_iter<I: IntoIterator<Item = Cow<'a, str>>>(iter: I) -> String {
2018-12-05 15:11:32 -08:00
let mut iterator = iter.into_iter();
2018-12-05 14:37:38 -08:00
2018-12-05 17:46:03 -08:00
// Because we're iterating over CoWs, we can (potentially) avoid at least
// one allocation by getting the first item and appending to it all the
// subsequent items.
2018-12-05 14:37:38 -08:00
match iterator.next() {
None => String::new(),
Some(cow) => {
2018-12-05 15:11:32 -08:00
let mut buf = cow.into_owned();
2018-12-05 14:37:38 -08:00
buf.extend(iterator);
buf
}
}
2017-04-21 13:25:48 -04:00
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl Extend<char> for String {
fn extend<I: IntoIterator<Item = char>>(&mut self, iter: I) {
let iterator = iter.into_iter();
let (lower_bound, _) = iterator.size_hint();
self.reserve(lower_bound);
2018-12-05 14:37:38 -08:00
iterator.for_each(move |c| self.push(c));
}
#[inline]
fn extend_one(&mut self, c: char) {
self.push(c);
}
#[inline]
fn extend_reserve(&mut self, additional: usize) {
self.reserve(additional);
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2015-06-03 12:38:42 +02:00
#[stable(feature = "extend_ref", since = "1.2.0")]
impl<'a> Extend<&'a char> for String {
fn extend<I: IntoIterator<Item = &'a char>>(&mut self, iter: I) {
self.extend(iter.into_iter().cloned());
2015-06-03 12:38:42 +02:00
}
#[inline]
fn extend_one(&mut self, &c: &'a char) {
self.push(c);
}
#[inline]
fn extend_reserve(&mut self, additional: usize) {
self.reserve(additional);
}
2015-06-03 12:38:42 +02:00
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Extend<&'a str> for String {
fn extend<I: IntoIterator<Item = &'a str>>(&mut self, iter: I) {
2018-12-05 14:37:38 -08:00
iter.into_iter().for_each(move |s| self.push_str(s));
}
#[inline]
fn extend_one(&mut self, s: &'a str) {
self.push_str(s);
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_str2", since = "1.45.0")]
impl Extend<Box<str>> for String {
fn extend<I: IntoIterator<Item = Box<str>>>(&mut self, iter: I) {
iter.into_iter().for_each(move |s| self.push_str(&s));
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "extend_string", since = "1.4.0")]
impl Extend<String> for String {
fn extend<I: IntoIterator<Item = String>>(&mut self, iter: I) {
2018-12-05 14:37:38 -08:00
iter.into_iter().for_each(move |s| self.push_str(&s));
}
#[inline]
fn extend_one(&mut self, s: String) {
self.push_str(&s);
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2017-04-21 13:25:48 -04:00
#[stable(feature = "herd_cows", since = "1.19.0")]
impl<'a> Extend<Cow<'a, str>> for String {
fn extend<I: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: I) {
2018-12-05 14:37:38 -08:00
iter.into_iter().for_each(move |s| self.push_str(&s));
2017-04-21 13:25:48 -04:00
}
#[inline]
fn extend_one(&mut self, s: Cow<'a, str>) {
self.push_str(&s);
}
2017-04-21 13:25:48 -04:00
}
2020-04-13 22:24:58 +08:00
/// A convenience impl that delegates to the impl for `&str`.
2020-04-13 22:25:15 +08:00
///
/// # Examples
///
/// ```
/// assert_eq!(String::from("Hello world").find("world"), Some(6));
/// ```
2015-11-16 19:54:28 +03:00
#[unstable(
feature = "pattern",
reason = "API not fully fleshed out and ready to be stabilized",
issue = "27721"
)]
impl<'a, 'b> Pattern<'a> for &'b String {
type Searcher = <&'b str as Pattern<'a>>::Searcher;
fn into_searcher(self, haystack: &'a str) -> <&'b str as Pattern<'a>>::Searcher {
self[..].into_searcher(haystack)
}
#[inline]
fn is_contained_in(self, haystack: &'a str) -> bool {
self[..].is_contained_in(haystack)
}
#[inline]
fn is_prefix_of(self, haystack: &'a str) -> bool {
self[..].is_prefix_of(haystack)
}
#[inline]
fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
self[..].strip_prefix_of(haystack)
}
#[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool {
self[..].is_suffix_of(haystack)
}
#[inline]
fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> {
self[..].strip_suffix_of(haystack)
}
}
macro_rules! impl_eq {
($lhs:ty, $rhs: ty) => {
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(unused_lifetimes)]
impl<'a, 'b> PartialEq<$rhs> for $lhs {
#[inline]
fn eq(&self, other: &$rhs) -> bool {
PartialEq::eq(&self[..], &other[..])
}
#[inline]
fn ne(&self, other: &$rhs) -> bool {
PartialEq::ne(&self[..], &other[..])
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(unused_lifetimes)]
impl<'a, 'b> PartialEq<$lhs> for $rhs {
#[inline]
fn eq(&self, other: &$lhs) -> bool {
PartialEq::eq(&self[..], &other[..])
}
#[inline]
fn ne(&self, other: &$lhs) -> bool {
PartialEq::ne(&self[..], &other[..])
}
}
};
}
impl_eq! { String, str }
impl_eq! { String, &'a str }
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
impl_eq! { Cow<'a, str>, str }
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
impl_eq! { Cow<'a, str>, &'b str }
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
impl_eq! { Cow<'a, str>, String }
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2023-04-16 06:49:27 +00:00
impl Default for String {
/// Creates an empty `String`.
2015-01-10 11:07:14 +01:00
#[inline]
fn default() -> String {
String::new()
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
impl fmt::Display for String {
2015-01-10 11:07:14 +01:00
#[inline]
2019-02-02 12:48:12 +01:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
fmt::Display::fmt(&**self, f)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
impl fmt::Debug for String {
2015-01-10 11:07:14 +01:00
#[inline]
2019-02-02 12:48:12 +01:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
fmt::Debug::fmt(&**self, f)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl hash::Hash for String {
#[inline]
fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
(**self).hash(hasher)
}
}
/// Implements the `+` operator for concatenating two strings.
///
/// This consumes the `String` on the left-hand side and re-uses its buffer (growing it if
/// necessary). This is done to avoid allocating a new `String` and copying the entire contents on
/// every operation, which would lead to *O*(*n*^2) running time when building an *n*-byte string by
/// repeated concatenation.
///
/// The string on the right-hand side is only borrowed; its contents are copied into the returned
/// `String`.
///
/// # Examples
///
/// Concatenating two `String`s takes the first by value and borrows the second:
///
/// ```
/// let a = String::from("hello");
/// let b = String::from(" world");
/// let c = a + &b;
/// // `a` is moved and can no longer be used here.
/// ```
///
/// If you want to keep using the first `String`, you can clone it and append to the clone instead:
///
/// ```
/// let a = String::from("hello");
/// let b = String::from(" world");
/// let c = a.clone() + &b;
/// // `a` is still valid here.
/// ```
///
/// Concatenating `&str` slices can be done by converting the first to a `String`:
///
/// ```
/// let a = "hello";
/// let b = " world";
/// let c = a.to_string() + b;
/// ```
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
2019-02-02 12:23:15 +01:00
impl Add<&str> for String {
2014-12-31 15:45:13 -05:00
type Output = String;
2015-01-10 11:07:14 +01:00
#[inline]
2014-12-01 14:08:56 -05:00
fn add(mut self, other: &str) -> String {
self.push_str(other);
self
}
}
/// Implements the `+=` operator for appending to a `String`.
///
2018-07-01 18:51:39 +02:00
/// This has the same behavior as the [`push_str`][String::push_str] method.
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "stringaddassign", since = "1.12.0")]
2019-02-02 12:23:15 +01:00
impl AddAssign<&str> for String {
2016-07-17 11:31:44 -04:00
#[inline]
fn add_assign(&mut self, other: &str) {
self.push_str(other);
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ops::Index<I> for String
where
I: slice::SliceIndex<str>,
{
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &I::Output {
index.index(self.as_str())
}
2014-12-31 20:20:40 +13:00
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ops::IndexMut<I> for String
where
I: slice::SliceIndex<str>,
{
#[inline]
fn index_mut(&mut self, index: I) -> &mut I::Output {
index.index_mut(self.as_mut_str())
}
}
2015-01-23 21:48:20 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2015-01-01 14:53:20 -05:00
impl ops::Deref for String {
type Target = str;
2015-01-10 11:07:14 +01:00
#[inline]
fn deref(&self) -> &str {
unsafe { str::from_utf8_unchecked(&self.vec) }
std: Stabilize the std::str module This commit starts out by consolidating all `str` extension traits into one `StrExt` trait to be included in the prelude. This means that `UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into one `StrExt` exported by the standard library. Some functionality is currently duplicated with the `StrExt` present in libcore. This commit also currently avoids any methods which require any form of pattern to operate. These functions will be stabilized via a separate RFC. Next, stability of methods and structures are as follows: Stable * from_utf8_unchecked * CowString - after moving to std::string * StrExt::as_bytes * StrExt::as_ptr * StrExt::bytes/Bytes - also made a struct instead of a typedef * StrExt::char_indices/CharIndices - CharOffsets was renamed * StrExt::chars/Chars * StrExt::is_empty * StrExt::len * StrExt::lines/Lines * StrExt::lines_any/LinesAny * StrExt::slice_unchecked * StrExt::trim * StrExt::trim_left * StrExt::trim_right * StrExt::words/Words - also made a struct instead of a typedef Unstable * from_utf8 - the error type was changed to a `Result`, but the error type has yet to prove itself * from_c_str - this function will be handled by the c_str RFC * FromStr - this trait will have an associated error type eventually * StrExt::escape_default - needs iterators at least, unsure if it should make the cut * StrExt::escape_unicode - needs iterators at least, unsure if it should make the cut * StrExt::slice_chars - this function has yet to prove itself * StrExt::slice_shift_char - awaiting conventions about slicing and shifting * StrExt::graphemes/Graphemes - this functionality may only be in libunicode * StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in libunicode * StrExt::width - this functionality may only be in libunicode * StrExt::utf16_units - this functionality may only be in libunicode * StrExt::nfd_chars - this functionality may only be in libunicode * StrExt::nfkd_chars - this functionality may only be in libunicode * StrExt::nfc_chars - this functionality may only be in libunicode * StrExt::nfkc_chars - this functionality may only be in libunicode * StrExt::is_char_boundary - naming is uncertain with container conventions * StrExt::char_range_at - naming is uncertain with container conventions * StrExt::char_range_at_reverse - naming is uncertain with container conventions * StrExt::char_at - naming is uncertain with container conventions * StrExt::char_at_reverse - naming is uncertain with container conventions * StrVector::concat - this functionality may be replaced with iterators, but it's not certain at this time * StrVector::connect - as with concat, may be deprecated in favor of iterators Deprecated * StrAllocating and UnicodeStrPrelude have been merged into StrExit * eq_slice - compiler implementation detail * from_str - use the inherent parse() method * is_utf8 - call from_utf8 instead * replace - call the method instead * truncate_utf16_at_nul - this is an implementation detail of windows and does not need to be exposed. * utf8_char_width - moved to libunicode * utf16_items - moved to libunicode * is_utf16 - moved to libunicode * Utf16Items - moved to libunicode * Utf16Item - moved to libunicode * Utf16Encoder - moved to libunicode * AnyLines - renamed to LinesAny and made a struct * SendStr - use CowString<'static> instead * str::raw - all functionality is deprecated * StrExt::into_string - call to_string() instead * StrExt::repeat - use iterators instead * StrExt::char_len - use .chars().count() instead * StrExt::is_alphanumeric - use .chars().all(..) * StrExt::is_whitespace - use .chars().all(..) Pending deprecation -- while slicing syntax is being worked out, these methods are all #[unstable] * Str - while currently used for generic programming, this trait will be replaced with one of [], deref coercions, or a generic conversion trait. * StrExt::slice - use slicing syntax instead * StrExt::slice_to - use slicing syntax instead * StrExt::slice_from - use slicing syntax instead * StrExt::lev_distance - deprecated with no replacement Awaiting stabilization due to patterns and/or matching * StrExt::contains * StrExt::contains_char * StrExt::split * StrExt::splitn * StrExt::split_terminator * StrExt::rsplitn * StrExt::match_indices * StrExt::split_str * StrExt::starts_with * StrExt::ends_with * StrExt::trim_chars * StrExt::trim_left_chars * StrExt::trim_right_chars * StrExt::find * StrExt::rfind * StrExt::find_str * StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
}
}
2024-03-21 14:37:43 -04:00
#[unstable(feature = "deref_pure_trait", issue = "87121")]
unsafe impl ops::DerefPure for String {}
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
impl ops::DerefMut for String {
#[inline]
fn deref_mut(&mut self) -> &mut str {
unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
}
}
/// A type alias for [`Infallible`].
///
/// This alias exists for backwards compatibility, and may be eventually deprecated.
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`Infallible`]: core::convert::Infallible "convert::Infallible"
std: Stabilize library APIs for 1.5 This commit stabilizes and deprecates library APIs whose FCP has closed in the last cycle, specifically: Stabilized APIs: * `fs::canonicalize` * `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists, is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait. * `Formatter::fill` * `Formatter::width` * `Formatter::precision` * `Formatter::sign_plus` * `Formatter::sign_minus` * `Formatter::alternate` * `Formatter::sign_aware_zero_pad` * `string::ParseError` * `Utf8Error::valid_up_to` * `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}` * `<[T]>::split_{first,last}{,_mut}` * `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated but will be once 1.5 is released. * `str::{R,}MatchIndices` * `str::{r,}match_indices` * `char::from_u32_unchecked` * `VecDeque::insert` * `VecDeque::shrink_to_fit` * `VecDeque::as_slices` * `VecDeque::as_mut_slices` * `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`) * `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`) * `Vec::resize` * `str::slice_mut_unchecked` * `FileTypeExt` * `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}` * `BinaryHeap::from` - `from_vec` deprecated in favor of this * `BinaryHeap::into_vec` - plus a `Into` impl * `BinaryHeap::into_sorted_vec` Deprecated APIs * `slice::ref_slice` * `slice::mut_ref_slice` * `iter::{range_inclusive, RangeInclusive}` * `std::dynamic_lib` Closes #27706 Closes #27725 cc #27726 (align not stabilized yet) Closes #27734 Closes #27737 Closes #27742 Closes #27743 Closes #27772 Closes #27774 Closes #27777 Closes #27781 cc #27788 (a few remaining methods though) Closes #27790 Closes #27793 Closes #27796 Closes #27810 cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
#[stable(feature = "str_parse_error", since = "1.5.0")]
pub type ParseError = core::convert::Infallible;
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
2014-11-15 15:52:00 +11:00
impl FromStr for String {
type Err = core::convert::Infallible;
2014-11-15 15:52:00 +11:00
#[inline]
fn from_str(s: &str) -> Result<String, Self::Err> {
Ok(String::from(s))
2014-11-15 15:52:00 +11:00
}
}
/// A trait for converting a value to a `String`.
///
/// This trait is automatically implemented for any type which implements the
/// [`Display`] trait. As such, `ToString` shouldn't be implemented directly:
/// [`Display`] should be implemented instead, and you get the `ToString`
/// implementation for free.
///
2020-07-18 10:14:00 -07:00
/// [`Display`]: fmt::Display
2021-02-16 02:32:21 +00:00
#[cfg_attr(not(test), rustc_diagnostic_item = "ToString")]
std: Stabilize the std::fmt module This commit performs a final stabilization pass over the std::fmt module, marking all necessary APIs as stable. One of the more interesting aspects of this module is that it exposes a good deal of its runtime representation to the outside world in order for `format_args!` to be able to construct the format strings. Instead of hacking the compiler to assume that these items are stable, this commit instead lays out a story for the stabilization and evolution of these APIs. There are three primary details used by the `format_args!` macro: 1. `Arguments` - an opaque package of a "compiled format string". This structure is passed around and the `write` function is the source of truth for transforming a compiled format string into a string at runtime. This must be able to be constructed in stable code. 2. `Argument` - an opaque structure representing an argument to a format string. This is *almost* a trait object as it's just a pointer/function pair, but due to the function originating from one of many traits, it's not actually a trait object. Like `Arguments`, this must be constructed from stable code. 3. `fmt::rt` - this module contains the runtime type definitions primarily for the `rt::Argument` structure. Whenever an argument is formatted with nonstandard flags, a corresponding `rt::Argument` is generated describing how the argument is being formatted. This can be used to construct an `Arguments`. The primary interface to `std::fmt` is the `Arguments` structure, and as such this type name is stabilize as-is today. It is expected for libraries to pass around an `Arguments` structure to represent a pending formatted computation. The remaining portions are largely "cruft" which would rather not be stabilized, but due to the stability checks they must be. As a result, almost all pieces have been renamed to represent that they are "version 1" of the formatting representation. The theory is that at a later date if we change the representation of these types we can add new definitions called "version 2" and corresponding constructors for `Arguments`. One of the other remaining large questions about the fmt module were how the pending I/O reform would affect the signatures of methods in the module. Due to [RFC 526][rfc], however, the writers of fmt are now incompatible with the writers of io, so this question has largely been solved. As a result the interfaces are largely stabilized as-is today. [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md Specifically, the following changes were made: * The contents of `fmt::rt` were all moved under `fmt::rt::v1` * `fmt::rt` is stable * `fmt::rt::v1` is stable * `Error` is stable * `Writer` is stable * `Writer::write_str` is stable * `Writer::write_fmt` is stable * `Formatter` is stable * `Argument` has been renamed to `ArgumentV1` and is stable * `ArgumentV1::new` is stable * `ArgumentV1::from_uint` is stable * `Arguments::new_v1` is stable (renamed from `new`) * `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`) * All formatting traits are now stable, as well as the `fmt` method. * `fmt::write` is stable * `fmt::format` is stable * `Formatter::pad_integral` is stable * `Formatter::pad` is stable * `Formatter::write_str` is stable * `Formatter::write_fmt` is stable * Some assorted top level items which were only used by `format_args!` were removed in favor of static functions on `ArgumentV1` as well. * The formatting-flag-accessing methods remain unstable Within the contents of the `fmt::rt::v1` module, the following actions were taken: * Reexports of all enum variants were removed * All prefixes on enum variants were removed * A few miscellaneous enum variants were renamed * Otherwise all structs, fields, and variants were marked stable. In addition to these actions in the `std::fmt` module, many implementations of `Show` and `String` were stabilized as well. In some other modules: * `ToString` is now stable * `ToString::to_string` is now stable * `Vec` no longer implements `fmt::Writer` (this has moved to `String`) This is a breaking change due to all of the changes to the `fmt::rt` module, but this likely will not have much impact on existing programs. Closes #20661 [breaking-change]
2015-01-13 15:42:53 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ToString {
/// Converts the given value to a `String`.
///
/// # Examples
///
/// ```
/// let i = 5;
/// let five = String::from("5");
///
/// assert_eq!(five, i.to_string());
/// ```
type error method suggestions use whitelisted identity-like conversions Previously, on a type mismatch (and if this wasn't preëmpted by a higher-priority suggestion), we would look for argumentless methods returning the expected type, and list them in a `help` note. This had two major shortcomings. Firstly, a lot of the suggestions didn't really make sense (if you used a &str where a String was expected, `.to_ascii_uppercase()` is probably not the solution you were hoping for). Secondly, we weren't generating suggestions from the most useful traits! We address the first problem with an internal `#[rustc_conversion_suggestion]` attribute meant to mark methods that keep the "same value" in the relevant sense, just converting the type. We address the second problem by making `FnCtxt.probe_for_return_type` pass the `ProbeScope::AllTraits` to `probe_op`: this would seem to be safe because grep reveals no other callers of `probe_for_return_type`. Also, structured suggestions are preferred (because they're pretty, but also for RLS and friends). Also also, we make the E0055 autoderef recursion limit error use the one-time-diagnostics set, because we can potentially hit the limit a lot during probing. (Without this, test/ui/did_you_mean/recursion_limit_deref.rs would report "aborting due to 51 errors"). Unfortunately, the trait probing is still not all one would hope for: at a minimum, we don't know how to rule out `into()` in cases where it wouldn't actually work, and we don't know how to rule in `.to_owned()` where it would. Issues #46459 and #46460 have been filed and are ref'd in a FIXME. This is hoped to resolve #42929, #44672, and #45777.
2017-11-19 11:25:35 -08:00
#[rustc_conversion_suggestion]
std: Stabilize the std::fmt module This commit performs a final stabilization pass over the std::fmt module, marking all necessary APIs as stable. One of the more interesting aspects of this module is that it exposes a good deal of its runtime representation to the outside world in order for `format_args!` to be able to construct the format strings. Instead of hacking the compiler to assume that these items are stable, this commit instead lays out a story for the stabilization and evolution of these APIs. There are three primary details used by the `format_args!` macro: 1. `Arguments` - an opaque package of a "compiled format string". This structure is passed around and the `write` function is the source of truth for transforming a compiled format string into a string at runtime. This must be able to be constructed in stable code. 2. `Argument` - an opaque structure representing an argument to a format string. This is *almost* a trait object as it's just a pointer/function pair, but due to the function originating from one of many traits, it's not actually a trait object. Like `Arguments`, this must be constructed from stable code. 3. `fmt::rt` - this module contains the runtime type definitions primarily for the `rt::Argument` structure. Whenever an argument is formatted with nonstandard flags, a corresponding `rt::Argument` is generated describing how the argument is being formatted. This can be used to construct an `Arguments`. The primary interface to `std::fmt` is the `Arguments` structure, and as such this type name is stabilize as-is today. It is expected for libraries to pass around an `Arguments` structure to represent a pending formatted computation. The remaining portions are largely "cruft" which would rather not be stabilized, but due to the stability checks they must be. As a result, almost all pieces have been renamed to represent that they are "version 1" of the formatting representation. The theory is that at a later date if we change the representation of these types we can add new definitions called "version 2" and corresponding constructors for `Arguments`. One of the other remaining large questions about the fmt module were how the pending I/O reform would affect the signatures of methods in the module. Due to [RFC 526][rfc], however, the writers of fmt are now incompatible with the writers of io, so this question has largely been solved. As a result the interfaces are largely stabilized as-is today. [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md Specifically, the following changes were made: * The contents of `fmt::rt` were all moved under `fmt::rt::v1` * `fmt::rt` is stable * `fmt::rt::v1` is stable * `Error` is stable * `Writer` is stable * `Writer::write_str` is stable * `Writer::write_fmt` is stable * `Formatter` is stable * `Argument` has been renamed to `ArgumentV1` and is stable * `ArgumentV1::new` is stable * `ArgumentV1::from_uint` is stable * `Arguments::new_v1` is stable (renamed from `new`) * `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`) * All formatting traits are now stable, as well as the `fmt` method. * `fmt::write` is stable * `fmt::format` is stable * `Formatter::pad_integral` is stable * `Formatter::pad` is stable * `Formatter::write_str` is stable * `Formatter::write_fmt` is stable * Some assorted top level items which were only used by `format_args!` were removed in favor of static functions on `ArgumentV1` as well. * The formatting-flag-accessing methods remain unstable Within the contents of the `fmt::rt::v1` module, the following actions were taken: * Reexports of all enum variants were removed * All prefixes on enum variants were removed * A few miscellaneous enum variants were renamed * Otherwise all structs, fields, and variants were marked stable. In addition to these actions in the `std::fmt` module, many implementations of `Show` and `String` were stabilized as well. In some other modules: * `ToString` is now stable * `ToString::to_string` is now stable * `Vec` no longer implements `fmt::Writer` (this has moved to `String`) This is a breaking change due to all of the changes to the `fmt::rt` module, but this likely will not have much impact on existing programs. Closes #20661 [breaking-change]
2015-01-13 15:42:53 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
2023-09-26 23:56:38 -04:00
#[cfg_attr(not(test), rustc_diagnostic_item = "to_string_method")]
fn to_string(&self) -> String;
}
/// # Panics
///
/// In this implementation, the `to_string` method panics
/// if the `Display` implementation returns an error.
/// This indicates an incorrect `Display` implementation
/// since `fmt::Write for String` never returns an error itself.
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
std: Stabilize the std::fmt module This commit performs a final stabilization pass over the std::fmt module, marking all necessary APIs as stable. One of the more interesting aspects of this module is that it exposes a good deal of its runtime representation to the outside world in order for `format_args!` to be able to construct the format strings. Instead of hacking the compiler to assume that these items are stable, this commit instead lays out a story for the stabilization and evolution of these APIs. There are three primary details used by the `format_args!` macro: 1. `Arguments` - an opaque package of a "compiled format string". This structure is passed around and the `write` function is the source of truth for transforming a compiled format string into a string at runtime. This must be able to be constructed in stable code. 2. `Argument` - an opaque structure representing an argument to a format string. This is *almost* a trait object as it's just a pointer/function pair, but due to the function originating from one of many traits, it's not actually a trait object. Like `Arguments`, this must be constructed from stable code. 3. `fmt::rt` - this module contains the runtime type definitions primarily for the `rt::Argument` structure. Whenever an argument is formatted with nonstandard flags, a corresponding `rt::Argument` is generated describing how the argument is being formatted. This can be used to construct an `Arguments`. The primary interface to `std::fmt` is the `Arguments` structure, and as such this type name is stabilize as-is today. It is expected for libraries to pass around an `Arguments` structure to represent a pending formatted computation. The remaining portions are largely "cruft" which would rather not be stabilized, but due to the stability checks they must be. As a result, almost all pieces have been renamed to represent that they are "version 1" of the formatting representation. The theory is that at a later date if we change the representation of these types we can add new definitions called "version 2" and corresponding constructors for `Arguments`. One of the other remaining large questions about the fmt module were how the pending I/O reform would affect the signatures of methods in the module. Due to [RFC 526][rfc], however, the writers of fmt are now incompatible with the writers of io, so this question has largely been solved. As a result the interfaces are largely stabilized as-is today. [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md Specifically, the following changes were made: * The contents of `fmt::rt` were all moved under `fmt::rt::v1` * `fmt::rt` is stable * `fmt::rt::v1` is stable * `Error` is stable * `Writer` is stable * `Writer::write_str` is stable * `Writer::write_fmt` is stable * `Formatter` is stable * `Argument` has been renamed to `ArgumentV1` and is stable * `ArgumentV1::new` is stable * `ArgumentV1::from_uint` is stable * `Arguments::new_v1` is stable (renamed from `new`) * `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`) * All formatting traits are now stable, as well as the `fmt` method. * `fmt::write` is stable * `fmt::format` is stable * `Formatter::pad_integral` is stable * `Formatter::pad` is stable * `Formatter::write_str` is stable * `Formatter::write_fmt` is stable * Some assorted top level items which were only used by `format_args!` were removed in favor of static functions on `ArgumentV1` as well. * The formatting-flag-accessing methods remain unstable Within the contents of the `fmt::rt::v1` module, the following actions were taken: * Reexports of all enum variants were removed * All prefixes on enum variants were removed * A few miscellaneous enum variants were renamed * Otherwise all structs, fields, and variants were marked stable. In addition to these actions in the `std::fmt` module, many implementations of `Show` and `String` were stabilized as well. In some other modules: * `ToString` is now stable * `ToString::to_string` is now stable * `Vec` no longer implements `fmt::Writer` (this has moved to `String`) This is a breaking change due to all of the changes to the `fmt::rt` module, but this likely will not have much impact on existing programs. Closes #20661 [breaking-change]
2015-01-13 15:42:53 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
std: Rename Show/String to Debug/Display This commit is an implementation of [RFC 565][rfc] which is a stabilization of the `std::fmt` module and the implementations of various formatting traits. Specifically, the following changes were performed: [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0565-show-string-guidelines.md * The `Show` trait is now deprecated, it was renamed to `Debug` * The `String` trait is now deprecated, it was renamed to `Display` * Many `Debug` and `Display` implementations were audited in accordance with the RFC and audited implementations now have the `#[stable]` attribute * Integers and floats no longer print a suffix * Smart pointers no longer print details that they are a smart pointer * Paths with `Debug` are now quoted and escape characters * The `unwrap` methods on `Result` now require `Display` instead of `Debug` * The `Error` trait no longer has a `detail` method and now requires that `Display` must be implemented. With the loss of `String`, this has moved into libcore. * `impl<E: Error> FromError<E> for Box<Error>` now exists * `derive(Show)` has been renamed to `derive(Debug)`. This is not currently warned about due to warnings being emitted on stage1+ While backwards compatibility is attempted to be maintained with a blanket implementation of `Display` for the old `String` trait (and the same for `Show`/`Debug`) this is still a breaking change due to primitives no longer implementing `String` as well as modifications such as `unwrap` and the `Error` trait. Most code is fairly straightforward to update with a rename or tweaks of method calls. [breaking-change] Closes #21436
2015-01-20 15:45:07 -08:00
impl<T: fmt::Display + ?Sized> ToString for T {
// A common guideline is to not inline generic functions. However,
2020-10-18 18:17:49 -07:00
// removing `#[inline]` from this method causes non-negligible regressions.
// See <https://github.com/rust-lang/rust/pull/74852>, the last attempt
// to try to remove it.
2015-01-10 11:07:14 +01:00
#[inline]
2016-03-22 19:29:56 -07:00
default fn to_string(&self) -> String {
let mut buf = String::new();
let mut formatter = core::fmt::Formatter::new(&mut buf);
// Bypass format_args!() to avoid write_str with zero-length strs
fmt::Display::fmt(self, &mut formatter)
2018-12-09 14:10:20 -07:00
.expect("a Display implementation returned an error unexpectedly");
buf
}
}
#[doc(hidden)]
2023-04-29 14:45:36 -07:00
#[cfg(not(no_global_oom_handling))]
#[unstable(feature = "ascii_char", issue = "110998")]
impl ToString for core::ascii::Char {
#[inline]
fn to_string(&self) -> String {
self.as_str().to_owned()
}
}
#[doc(hidden)]
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "char_to_string_specialization", since = "1.46.0")]
impl ToString for char {
#[inline]
fn to_string(&self) -> String {
String::from(self.encode_utf8(&mut [0; 4]))
}
}
#[doc(hidden)]
#[cfg(not(no_global_oom_handling))]
2023-01-24 08:40:09 -05:00
#[stable(feature = "bool_to_string_specialization", since = "1.68.0")]
impl ToString for bool {
#[inline]
fn to_string(&self) -> String {
String::from(if *self { "true" } else { "false" })
}
}
#[doc(hidden)]
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "u8_to_string_specialization", since = "1.54.0")]
impl ToString for u8 {
#[inline]
fn to_string(&self) -> String {
2021-03-08 22:35:37 +00:00
let mut buf = String::with_capacity(3);
let mut n = *self;
2021-03-08 22:35:37 +00:00
if n >= 10 {
if n >= 100 {
buf.push((b'0' + n / 100) as char);
n %= 100;
}
buf.push((b'0' + n / 10) as char);
n %= 10;
2021-03-08 22:35:37 +00:00
}
buf.push((b'0' + n) as char);
buf
}
}
#[doc(hidden)]
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "i8_to_string_specialization", since = "1.54.0")]
2021-03-04 07:04:21 +00:00
impl ToString for i8 {
#[inline]
fn to_string(&self) -> String {
2021-03-08 22:35:37 +00:00
let mut buf = String::with_capacity(4);
if self.is_negative() {
2021-03-08 22:35:37 +00:00
buf.push('-');
}
let mut n = self.unsigned_abs();
2021-03-04 07:04:21 +00:00
if n >= 10 {
if n >= 100 {
2021-03-08 22:35:37 +00:00
buf.push('1');
2021-03-04 07:04:21 +00:00
n -= 100;
}
2021-03-08 22:35:37 +00:00
buf.push((b'0' + n / 10) as char);
n %= 10;
2021-03-04 07:04:21 +00:00
}
2021-03-08 22:35:37 +00:00
buf.push((b'0' + n) as char);
buf
2021-03-04 07:04:21 +00:00
}
}
#[doc(hidden)]
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2016-03-22 19:29:56 -07:00
#[stable(feature = "str_to_string_specialization", since = "1.9.0")]
impl ToString for str {
#[inline]
fn to_string(&self) -> String {
String::from(self)
}
}
#[doc(hidden)]
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "cow_str_to_string_specialization", since = "1.17.0")]
2019-02-02 12:23:15 +01:00
impl ToString for Cow<'_, str> {
#[inline]
fn to_string(&self) -> String {
self[..].to_owned()
}
}
#[doc(hidden)]
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "string_to_string_specialization", since = "1.17.0")]
impl ToString for String {
#[inline]
fn to_string(&self) -> String {
self.to_owned()
}
}
#[doc(hidden)]
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "fmt_arguments_to_string_specialization", since = "1.71.0")]
impl ToString for fmt::Arguments<'_> {
#[inline]
fn to_string(&self) -> String {
crate::fmt::format(*self)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<str> for String {
#[inline]
fn as_ref(&self) -> &str {
self
}
}
2020-02-01 22:19:28 +01:00
#[stable(feature = "string_as_mut", since = "1.43.0")]
impl AsMut<str> for String {
#[inline]
fn as_mut(&mut self) -> &mut str {
self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<[u8]> for String {
#[inline]
fn as_ref(&self) -> &[u8] {
self.as_bytes()
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl From<&str> for String {
2021-05-26 08:24:06 +00:00
/// Converts a `&str` into a [`String`].
///
/// The result is allocated on the heap.
#[inline]
fn from(s: &str) -> String {
s.to_owned()
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2020-03-10 18:45:08 -07:00
#[stable(feature = "from_mut_str_for_string", since = "1.44.0")]
2020-03-02 21:17:58 -08:00
impl From<&mut str> for String {
2021-05-26 08:24:06 +00:00
/// Converts a `&mut str` into a [`String`].
///
/// The result is allocated on the heap.
2020-03-02 21:17:58 -08:00
#[inline]
fn from(s: &mut str) -> String {
s.to_owned()
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "from_ref_string", since = "1.35.0")]
impl From<&String> for String {
2021-05-26 08:24:06 +00:00
/// Converts a `&String` into a [`String`].
///
/// This clones `s` and returns the clone.
#[inline]
fn from(s: &String) -> String {
s.clone()
}
}
// note: test pulls in std, which causes errors here
2017-02-13 20:37:42 -05:00
#[cfg(not(test))]
#[stable(feature = "string_from_box", since = "1.18.0")]
2017-02-13 20:37:42 -05:00
impl From<Box<str>> for String {
2021-05-26 08:24:06 +00:00
/// Converts the given boxed `str` slice to a [`String`].
/// It is notable that the `str` slice is owned.
///
/// # Examples
///
/// ```
2018-11-11 20:11:25 +01:00
/// let s1: String = String::from("hello world");
/// let s2: Box<str> = s1.into_boxed_str();
/// let s3: String = String::from(s2);
///
/// assert_eq!("hello world", s3)
/// ```
2017-02-13 20:37:42 -05:00
fn from(s: Box<str>) -> String {
s.into_string()
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2017-06-13 00:08:37 +01:00
#[stable(feature = "box_from_str", since = "1.20.0")]
2017-05-20 15:40:53 -04:00
impl From<String> for Box<str> {
2021-05-26 08:24:06 +00:00
/// Converts the given [`String`] to a boxed `str` slice that is owned.
///
/// # Examples
///
/// ```
2018-11-11 20:11:25 +01:00
/// let s1: String = String::from("hello world");
/// let s2: Box<str> = Box::from(s1);
/// let s3: String = String::from(s2);
///
/// assert_eq!("hello world", s3)
/// ```
2017-05-20 15:40:53 -04:00
fn from(s: String) -> Box<str> {
s.into_boxed_str()
2017-02-13 20:37:42 -05:00
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "string_from_cow_str", since = "1.14.0")]
impl<'a> From<Cow<'a, str>> for String {
2021-05-26 08:24:06 +00:00
/// Converts a clone-on-write string to an owned
/// instance of [`String`].
///
/// This extracts the owned string,
/// clones the string if it is not already owned.
///
/// # Example
///
/// ```
/// # use std::borrow::Cow;
/// // If the string is not owned...
/// let cow: Cow<'_, str> = Cow::Borrowed("eggplant");
2021-05-26 08:24:06 +00:00
/// // It will allocate on the heap and copy the string.
/// let owned: String = String::from(cow);
/// assert_eq!(&owned[..], "eggplant");
/// ```
fn from(s: Cow<'a, str>) -> String {
s.into_owned()
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&'a str> for Cow<'a, str> {
2021-05-26 08:24:06 +00:00
/// Converts a string slice into a [`Borrowed`] variant.
/// No heap allocation is performed, and the string
/// is not copied.
///
/// # Example
///
/// ```
/// # use std::borrow::Cow;
/// assert_eq!(Cow::from("eggplant"), Cow::Borrowed("eggplant"));
/// ```
2021-05-26 08:24:06 +00:00
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`Borrowed`]: crate::borrow::Cow::Borrowed "borrow::Cow::Borrowed"
#[inline]
fn from(s: &'a str) -> Cow<'a, str> {
Cow::Borrowed(s)
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<String> for Cow<'a, str> {
2021-05-26 08:24:06 +00:00
/// Converts a [`String`] into an [`Owned`] variant.
/// No heap allocation is performed, and the string
/// is not copied.
///
/// # Example
///
/// ```
/// # use std::borrow::Cow;
/// let s = "eggplant".to_string();
/// let s2 = "eggplant".to_string();
/// assert_eq!(Cow::from(s), Cow::<'static, str>::Owned(s2));
/// ```
2021-05-26 08:24:06 +00:00
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`Owned`]: crate::borrow::Cow::Owned "borrow::Cow::Owned"
#[inline]
fn from(s: String) -> Cow<'a, str> {
Cow::Owned(s)
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
2018-05-09 07:23:02 +01:00
#[stable(feature = "cow_from_string_ref", since = "1.28.0")]
2018-04-22 22:57:52 +01:00
impl<'a> From<&'a String> for Cow<'a, str> {
2021-05-26 08:24:06 +00:00
/// Converts a [`String`] reference into a [`Borrowed`] variant.
/// No heap allocation is performed, and the string
/// is not copied.
///
/// # Example
///
/// ```
/// # use std::borrow::Cow;
/// let s = "eggplant".to_string();
/// assert_eq!(Cow::from(&s), Cow::Borrowed("eggplant"));
/// ```
2021-05-26 08:24:06 +00:00
///
Apply 16 commits (squashed) ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::fmt ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::{rc, sync} ---------- Fix spacing for links inside code blocks, and improve link tooltips in alloc::string ---------- Fix spacing for links inside code blocks in alloc::vec ---------- Fix spacing for links inside code blocks in core::option ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in core::result ---------- Fix spacing for links inside code blocks in core::{iter::{self, iterator}, stream::stream, poll} ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{fs, path} ---------- Fix spacing for links inside code blocks in std::{collections, time} ---------- Fix spacing for links inside code blocks in and make formatting of `&str`-like types consistent in std::ffi::{c_str, os_str} ---------- Fix spacing for links inside code blocks, and improve link tooltips in std::ffi ---------- Fix spacing for links inside code blocks, and improve a few link tooltips in std::{io::{self, buffered::{bufreader, bufwriter}, cursor, util}, net::{self, addr}} ---------- Fix typo in link to `into` for `OsString` docs ---------- Remove tooltips that will probably become redundant in the future ---------- Apply suggestions from code review Replacing `…std/primitive.reference.html` paths with just `reference` Co-authored-by: Joshua Nelson <github@jyn.dev> ---------- Also replace `…std/primitive.reference.html` paths with just `reference` in `core::pin`
2021-08-25 11:45:08 +02:00
/// [`Borrowed`]: crate::borrow::Cow::Borrowed "borrow::Cow::Borrowed"
2018-04-22 22:57:52 +01:00
#[inline]
fn from(s: &'a String) -> Cow<'a, str> {
Cow::Borrowed(s.as_str())
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
impl<'a> FromIterator<char> for Cow<'a, str> {
fn from_iter<I: IntoIterator<Item = char>>(it: I) -> Cow<'a, str> {
Cow::Owned(FromIterator::from_iter(it))
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
impl<'a, 'b> FromIterator<&'b str> for Cow<'a, str> {
fn from_iter<I: IntoIterator<Item = &'b str>>(it: I) -> Cow<'a, str> {
Cow::Owned(FromIterator::from_iter(it))
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
impl<'a> FromIterator<String> for Cow<'a, str> {
fn from_iter<I: IntoIterator<Item = String>>(it: I) -> Cow<'a, str> {
Cow::Owned(FromIterator::from_iter(it))
}
}
#[stable(feature = "from_string_for_vec_u8", since = "1.14.0")]
impl From<String> for Vec<u8> {
2021-05-26 08:24:06 +00:00
/// Converts the given [`String`] to a vector [`Vec`] that holds values of type [`u8`].
///
/// # Examples
///
/// ```
/// let s1 = String::from("hello world");
/// let v1 = Vec::from(s1);
///
/// for b in v1 {
/// println!("{b}");
/// }
/// ```
2016-12-20 09:54:00 +05:30
fn from(string: String) -> Vec<u8> {
string.into_bytes()
}
}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
std: Stabilize the std::fmt module This commit performs a final stabilization pass over the std::fmt module, marking all necessary APIs as stable. One of the more interesting aspects of this module is that it exposes a good deal of its runtime representation to the outside world in order for `format_args!` to be able to construct the format strings. Instead of hacking the compiler to assume that these items are stable, this commit instead lays out a story for the stabilization and evolution of these APIs. There are three primary details used by the `format_args!` macro: 1. `Arguments` - an opaque package of a "compiled format string". This structure is passed around and the `write` function is the source of truth for transforming a compiled format string into a string at runtime. This must be able to be constructed in stable code. 2. `Argument` - an opaque structure representing an argument to a format string. This is *almost* a trait object as it's just a pointer/function pair, but due to the function originating from one of many traits, it's not actually a trait object. Like `Arguments`, this must be constructed from stable code. 3. `fmt::rt` - this module contains the runtime type definitions primarily for the `rt::Argument` structure. Whenever an argument is formatted with nonstandard flags, a corresponding `rt::Argument` is generated describing how the argument is being formatted. This can be used to construct an `Arguments`. The primary interface to `std::fmt` is the `Arguments` structure, and as such this type name is stabilize as-is today. It is expected for libraries to pass around an `Arguments` structure to represent a pending formatted computation. The remaining portions are largely "cruft" which would rather not be stabilized, but due to the stability checks they must be. As a result, almost all pieces have been renamed to represent that they are "version 1" of the formatting representation. The theory is that at a later date if we change the representation of these types we can add new definitions called "version 2" and corresponding constructors for `Arguments`. One of the other remaining large questions about the fmt module were how the pending I/O reform would affect the signatures of methods in the module. Due to [RFC 526][rfc], however, the writers of fmt are now incompatible with the writers of io, so this question has largely been solved. As a result the interfaces are largely stabilized as-is today. [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md Specifically, the following changes were made: * The contents of `fmt::rt` were all moved under `fmt::rt::v1` * `fmt::rt` is stable * `fmt::rt::v1` is stable * `Error` is stable * `Writer` is stable * `Writer::write_str` is stable * `Writer::write_fmt` is stable * `Formatter` is stable * `Argument` has been renamed to `ArgumentV1` and is stable * `ArgumentV1::new` is stable * `ArgumentV1::from_uint` is stable * `Arguments::new_v1` is stable (renamed from `new`) * `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`) * All formatting traits are now stable, as well as the `fmt` method. * `fmt::write` is stable * `fmt::format` is stable * `Formatter::pad_integral` is stable * `Formatter::pad` is stable * `Formatter::write_str` is stable * `Formatter::write_fmt` is stable * Some assorted top level items which were only used by `format_args!` were removed in favor of static functions on `ArgumentV1` as well. * The formatting-flag-accessing methods remain unstable Within the contents of the `fmt::rt::v1` module, the following actions were taken: * Reexports of all enum variants were removed * All prefixes on enum variants were removed * A few miscellaneous enum variants were renamed * Otherwise all structs, fields, and variants were marked stable. In addition to these actions in the `std::fmt` module, many implementations of `Show` and `String` were stabilized as well. In some other modules: * `ToString` is now stable * `ToString::to_string` is now stable * `Vec` no longer implements `fmt::Writer` (this has moved to `String`) This is a breaking change due to all of the changes to the `fmt::rt` module, but this likely will not have much impact on existing programs. Closes #20661 [breaking-change]
2015-01-13 15:42:53 -08:00
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Write for String {
2015-01-10 11:07:14 +01:00
#[inline]
fn write_str(&mut self, s: &str) -> fmt::Result {
self.push_str(s);
Ok(())
}
#[inline]
fn write_char(&mut self, c: char) -> fmt::Result {
self.push(c);
Ok(())
}
}
/// A draining iterator for `String`.
///
/// This struct is created by the [`drain`] method on [`String`]. See its
/// documentation for more.
///
2020-07-18 10:14:00 -07:00
/// [`drain`]: String::drain
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a> {
/// Will be used as &'a mut String in the destructor
string: *mut String,
/// Start of part to remove
start: usize,
/// End of part to remove
end: usize,
/// Current remaining range to remove
iter: Chars<'a>,
}
#[stable(feature = "collection_debug", since = "1.17.0")]
2019-02-02 12:23:15 +01:00
impl fmt::Debug for Drain<'_> {
2019-02-02 12:48:12 +01:00
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Drain").field(&self.as_str()).finish()
}
}
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
2019-02-02 12:23:15 +01:00
unsafe impl Sync for Drain<'_> {}
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
2019-02-02 12:23:15 +01:00
unsafe impl Send for Drain<'_> {}
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
2019-02-02 12:23:15 +01:00
impl Drop for Drain<'_> {
fn drop(&mut self) {
unsafe {
// Use Vec::drain. "Reaffirm" the bounds checks to avoid
// panic code being inserted again.
let self_vec = (*self.string).as_mut_vec();
if self.start <= self.end && self.end <= self_vec.len() {
self_vec.drain(self.start..self.end);
}
}
}
}
impl<'a> Drain<'a> {
/// Returns the remaining (sub)string of this iterator as a slice.
///
/// # Examples
///
/// ```
/// let mut s = String::from("abc");
/// let mut drain = s.drain(..);
/// assert_eq!(drain.as_str(), "abc");
/// let _ = drain.next().unwrap();
/// assert_eq!(drain.as_str(), "bc");
/// ```
2021-10-11 13:57:38 -04:00
#[must_use]
2021-07-04 14:23:43 +09:00
#[stable(feature = "string_drain_as_str", since = "1.55.0")]
pub fn as_str(&self) -> &str {
self.iter.as_str()
}
}
2021-07-04 14:23:43 +09:00
#[stable(feature = "string_drain_as_str", since = "1.55.0")]
impl<'a> AsRef<str> for Drain<'a> {
fn as_ref(&self) -> &str {
self.as_str()
}
}
#[stable(feature = "string_drain_as_str", since = "1.55.0")]
impl<'a> AsRef<[u8]> for Drain<'a> {
fn as_ref(&self) -> &[u8] {
self.as_str().as_bytes()
}
}
2020-09-09 17:59:43 +02:00
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
2019-02-02 12:23:15 +01:00
impl Iterator for Drain<'_> {
type Item = char;
#[inline]
fn next(&mut self) -> Option<char> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
When possible without changing semantics, implement Iterator::last in terms of DoubleEndedIterator::next_back for types in liballoc and libcore. Provided that the iterator has finite length and does not trigger user-provided code, this is safe. What follows is a full list of the DoubleEndedIterators in liballoc/libcore and whether this optimization is safe, and if not, why not. src/liballoc/boxed.rs Box: Pass through to avoid defeating optimization of the underlying DoubleIterator implementation. This has no correctness impact. src/liballoc/collections/binary_heap.rs Iter: Pass through to avoid defeating optimizations on slice::Iter IntoIter: Not safe, changes Drop order Drain: Not safe, changes Drop order src/liballoc/collections/btree/map.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order Keys: Safe to call next_back, invokes no user defined code. Values: ditto ValuesMut: ditto Range: ditto RangeMut: ditto src/liballoc/collections/btree/set.rs Iter: Safe to call next_back, invokes no user defined code. IntoIter: Not safe, changes Drop order Range: Safe to call next_back, invokes no user defined code. src/liballoc/collections/linked_list.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order src/liballoc/collections/vec_deque.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order Drain: ditto src/liballoc/string.rs Drain: Safe because return type is a primitive (char) src/liballoc/vec.rs IntoIter: Not safe, changes Drop order Drain: ditto Splice: ditto src/libcore/ascii.rs EscapeDefault: Safe because return type is a primitive (u8) src/libcore/iter/adapters/chain.rs Chain: Not safe, invokes user defined code (Iterator impl) src/libcore/iter/adapters/flatten.rs FlatMap: Not safe, invokes user defined code (Iterator impl) Flatten: ditto FlattenCompat: ditto src/libcore/iter/adapters/mod.rs Rev: Not safe, invokes user defined code (Iterator impl) Copied: ditto Cloned: Not safe, invokes user defined code (Iterator impl and T::clone) Map: Not safe, invokes user defined code (Iterator impl + closure) Filter: ditto FilterMap: ditto Enumerate: Not safe, invokes user defined code (Iterator impl) Skip: ditto Fuse: ditto Inspect: ditto src/libcore/iter/adapters/zip.rs Zip: Not safe, invokes user defined code (Iterator impl) src/libcore/iter/range.rs ops::Range: Not safe, changes Drop order, but ALREADY HAS SPECIALIZATION ops::RangeInclusive: ditto src/libcore/iter/sources.rs Repeat: Not safe, calling last should iloop. Empty: No point, iterator is at most one item long. Once: ditto OnceWith: ditto src/libcore/option.rs Item: No point, iterator is at most one item long. Iter: ditto IterMut: ditto IntoIter: ditto src/libcore/result.rs Iter: No point, iterator is at most one item long IterMut: ditto IntoIter: ditto src/libcore/slice/mod.rs Split: Not safe, invokes user defined closure SplitMut: ditto RSplit: ditto RSplitMut: ditto Windows: Safe, already has specialization Chunks: ditto ChunksMut: ditto ChunksExact: ditto ChunksExactMut: ditto RChunks: ditto RChunksMut: ditto RChunksExact: ditto RChunksExactMut: ditto src/libcore/str/mod.rs Chars: Safe, already has specialization CharIndices: ditto Bytes: ditto Lines: Safe to call next_back, invokes no user defined code. LinesAny: Deprecated Everything that is generic over P: Pattern: Not safe because Pattern invokes user defined code. SplitWhitespace: Safe to call next_back, invokes no user defined code. SplitAsciiWhitespace: ditto
2019-07-02 13:45:29 -07:00
#[inline]
fn last(mut self) -> Option<char> {
self.next_back()
}
}
std: Stabilize APIs for the 1.6 release This commit is the standard API stabilization commit for the 1.6 release cycle. The list of issues and APIs below have all been through their cycle-long FCP and the libs team decisions are listed below Stabilized APIs * `Read::read_exact` * `ErrorKind::UnexpectedEof` (renamed from `UnexpectedEOF`) * libcore -- this was a bit of a nuanced stabilization, the crate itself is now marked as `#[stable]` and the methods appearing via traits for primitives like `char` and `str` are now also marked as stable. Note that the extension traits themeselves are marked as unstable as they're imported via the prelude. The `try!` macro was also moved from the standard library into libcore to have the same interface. Otherwise the functions all have copied stability from the standard library now. * The `#![no_std]` attribute * `fs::DirBuilder` * `fs::DirBuilder::new` * `fs::DirBuilder::recursive` * `fs::DirBuilder::create` * `os::unix::fs::DirBuilderExt` * `os::unix::fs::DirBuilderExt::mode` * `vec::Drain` * `vec::Vec::drain` * `string::Drain` * `string::String::drain` * `vec_deque::Drain` * `vec_deque::VecDeque::drain` * `collections::hash_map::Drain` * `collections::hash_map::HashMap::drain` * `collections::hash_set::Drain` * `collections::hash_set::HashSet::drain` * `collections::binary_heap::Drain` * `collections::binary_heap::BinaryHeap::drain` * `Vec::extend_from_slice` (renamed from `push_all`) * `Mutex::get_mut` * `Mutex::into_inner` * `RwLock::get_mut` * `RwLock::into_inner` * `Iterator::min_by_key` (renamed from `min_by`) * `Iterator::max_by_key` (renamed from `max_by`) Deprecated APIs * `ErrorKind::UnexpectedEOF` (renamed to `UnexpectedEof`) * `OsString::from_bytes` * `OsStr::to_cstring` * `OsStr::to_bytes` * `fs::walk_dir` and `fs::WalkDir` * `path::Components::peek` * `slice::bytes::MutableByteVector` * `slice::bytes::copy_memory` * `Vec::push_all` (renamed to `extend_from_slice`) * `Duration::span` * `IpAddr` * `SocketAddr::ip` * `Read::tee` * `io::Tee` * `Write::broadcast` * `io::Broadcast` * `Iterator::min_by` (renamed to `min_by_key`) * `Iterator::max_by` (renamed to `max_by_key`) * `net::lookup_addr` New APIs (still unstable) * `<[T]>::sort_by_key` (added to mirror `min_by_key`) Closes #27585 Closes #27704 Closes #27707 Closes #27710 Closes #27711 Closes #27727 Closes #27740 Closes #27744 Closes #27799 Closes #27801 cc #27801 (doesn't close as `Chars` is still unstable) Closes #28968
2015-12-02 17:31:49 -08:00
#[stable(feature = "drain", since = "1.6.0")]
2019-02-02 12:23:15 +01:00
impl DoubleEndedIterator for Drain<'_> {
#[inline]
fn next_back(&mut self) -> Option<char> {
self.iter.next_back()
}
}
#[stable(feature = "fused", since = "1.26.0")]
2019-02-02 12:23:15 +01:00
impl FusedIterator for Drain<'_> {}
alloc: Add unstable Cfg feature `no-global_oom_handling` For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-16 20:18:04 -04:00
#[cfg(not(no_global_oom_handling))]
#[stable(feature = "from_char_for_string", since = "1.46.0")]
impl From<char> for String {
2021-05-26 08:24:06 +00:00
/// Allocates an owned [`String`] from a single character.
///
/// # Example
/// ```rust
/// let c: char = 'a';
/// let s: String = String::from(c);
/// assert_eq!("a", &s[..]);
/// ```
#[inline]
fn from(c: char) -> Self {
c.to_string()
}
}