about summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/bstr.rs702
-rw-r--r--library/alloc/src/collections/btree/set.rs8
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs46
-rw-r--r--library/alloc/src/lib.rs4
-rw-r--r--library/alloc/src/vec/mod.rs26
5 files changed, 768 insertions, 18 deletions
diff --git a/library/alloc/src/bstr.rs b/library/alloc/src/bstr.rs
new file mode 100644
index 00000000000..61e61019b50
--- /dev/null
+++ b/library/alloc/src/bstr.rs
@@ -0,0 +1,702 @@
+//! The `ByteStr` and `ByteString` types and trait implementations.
+
+// This could be more fine-grained.
+#![cfg(not(no_global_oom_handling))]
+
+use core::borrow::{Borrow, BorrowMut};
+#[unstable(feature = "bstr", issue = "134915")]
+pub use core::bstr::ByteStr;
+use core::bstr::{impl_partial_eq, impl_partial_eq_n, impl_partial_eq_ord};
+use core::cmp::Ordering;
+use core::ops::{
+    Deref, DerefMut, DerefPure, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive,
+    RangeTo, RangeToInclusive,
+};
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+use core::str::FromStr;
+use core::{fmt, hash};
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+use crate::borrow::{Cow, ToOwned};
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+use crate::boxed::Box;
+#[cfg(not(no_rc))]
+use crate::rc::Rc;
+use crate::string::String;
+#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
+use crate::sync::Arc;
+use crate::vec::Vec;
+
+/// A wrapper for `Vec<u8>` representing a human-readable string that's conventionally, but not
+/// always, UTF-8.
+///
+/// Unlike `String`, this type permits non-UTF-8 contents, making it suitable for user input,
+/// non-native filenames (as `Path` only supports native filenames), and other applications that
+/// need to round-trip whatever data the user provides.
+///
+/// A `ByteString` owns its contents and can grow and shrink, like a `Vec` or `String`. For a
+/// borrowed byte string, see [`ByteStr`](../../std/bstr/struct.ByteStr.html).
+///
+/// `ByteString` implements `Deref` to `&Vec<u8>`, so all methods available on `&Vec<u8>` are
+/// available on `ByteString`. Similarly, `ByteString` implements `DerefMut` to `&mut Vec<u8>`,
+/// so you can modify a `ByteString` using any method available on `&mut Vec<u8>`.
+///
+/// The `Debug` and `Display` implementations for `ByteString` are the same as those for `ByteStr`,
+/// showing invalid UTF-8 as hex escapes or the Unicode replacement character, respectively.
+#[unstable(feature = "bstr", issue = "134915")]
+#[repr(transparent)]
+#[derive(Clone)]
+#[doc(alias = "BString")]
+pub struct ByteString(pub Vec<u8>);
+
+impl ByteString {
+    #[inline]
+    pub(crate) fn as_bytes(&self) -> &[u8] {
+        &self.0
+    }
+
+    #[inline]
+    pub(crate) fn as_bytestr(&self) -> &ByteStr {
+        ByteStr::new(&self.0)
+    }
+
+    #[inline]
+    pub(crate) fn as_mut_bytestr(&mut self) -> &mut ByteStr {
+        ByteStr::from_bytes_mut(&mut self.0)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Deref for ByteString {
+    type Target = Vec<u8>;
+
+    #[inline]
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl DerefMut for ByteString {
+    #[inline]
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.0
+    }
+}
+
+#[unstable(feature = "deref_pure_trait", issue = "87121")]
+unsafe impl DerefPure for ByteString {}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl fmt::Debug for ByteString {
+    #[inline]
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(self.as_bytestr(), f)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl fmt::Display for ByteString {
+    #[inline]
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(self.as_bytestr(), f)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl AsRef<[u8]> for ByteString {
+    #[inline]
+    fn as_ref(&self) -> &[u8] {
+        &self.0
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl AsRef<ByteStr> for ByteString {
+    #[inline]
+    fn as_ref(&self) -> &ByteStr {
+        self.as_bytestr()
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl AsMut<[u8]> for ByteString {
+    #[inline]
+    fn as_mut(&mut self) -> &mut [u8] {
+        &mut self.0
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl AsMut<ByteStr> for ByteString {
+    #[inline]
+    fn as_mut(&mut self) -> &mut ByteStr {
+        self.as_mut_bytestr()
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Borrow<[u8]> for ByteString {
+    #[inline]
+    fn borrow(&self) -> &[u8] {
+        &self.0
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Borrow<ByteStr> for ByteString {
+    #[inline]
+    fn borrow(&self) -> &ByteStr {
+        self.as_bytestr()
+    }
+}
+
+// `impl Borrow<ByteStr> for Vec<u8>` omitted to avoid inference failures
+// `impl Borrow<ByteStr> for String` omitted to avoid inference failures
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl BorrowMut<[u8]> for ByteString {
+    #[inline]
+    fn borrow_mut(&mut self) -> &mut [u8] {
+        &mut self.0
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl BorrowMut<ByteStr> for ByteString {
+    #[inline]
+    fn borrow_mut(&mut self) -> &mut ByteStr {
+        self.as_mut_bytestr()
+    }
+}
+
+// `impl BorrowMut<ByteStr> for Vec<u8>` omitted to avoid inference failures
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Default for ByteString {
+    fn default() -> Self {
+        ByteString(Vec::new())
+    }
+}
+
+// Omitted due to inference failures
+//
+// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+// #[unstable(feature = "bstr", issue = "134915")]
+// impl<'a, const N: usize> From<&'a [u8; N]> for ByteString {
+//     #[inline]
+//     fn from(s: &'a [u8; N]) -> Self {
+//         ByteString(s.as_slice().to_vec())
+//     }
+// }
+//
+// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+// #[unstable(feature = "bstr", issue = "134915")]
+// impl<const N: usize> From<[u8; N]> for ByteString {
+//     #[inline]
+//     fn from(s: [u8; N]) -> Self {
+//         ByteString(s.as_slice().to_vec())
+//     }
+// }
+//
+// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+// #[unstable(feature = "bstr", issue = "134915")]
+// impl<'a> From<&'a [u8]> for ByteString {
+//     #[inline]
+//     fn from(s: &'a [u8]) -> Self {
+//         ByteString(s.to_vec())
+//     }
+// }
+//
+// #[unstable(feature = "bstr", issue = "134915")]
+// impl From<Vec<u8>> for ByteString {
+//     #[inline]
+//     fn from(s: Vec<u8>) -> Self {
+//         ByteString(s)
+//     }
+// }
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl From<ByteString> for Vec<u8> {
+    #[inline]
+    fn from(s: ByteString) -> Self {
+        s.0
+    }
+}
+
+// Omitted due to inference failures
+//
+// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+// #[unstable(feature = "bstr", issue = "134915")]
+// impl<'a> From<&'a str> for ByteString {
+//     #[inline]
+//     fn from(s: &'a str) -> Self {
+//         ByteString(s.as_bytes().to_vec())
+//     }
+// }
+//
+// #[unstable(feature = "bstr", issue = "134915")]
+// impl From<String> for ByteString {
+//     #[inline]
+//     fn from(s: String) -> Self {
+//         ByteString(s.into_bytes())
+//     }
+// }
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+#[unstable(feature = "bstr", issue = "134915")]
+impl<'a> From<&'a ByteStr> for ByteString {
+    #[inline]
+    fn from(s: &'a ByteStr) -> Self {
+        ByteString(s.0.to_vec())
+    }
+}
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+#[unstable(feature = "bstr", issue = "134915")]
+impl<'a> From<ByteString> for Cow<'a, ByteStr> {
+    #[inline]
+    fn from(s: ByteString) -> Self {
+        Cow::Owned(s)
+    }
+}
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+#[unstable(feature = "bstr", issue = "134915")]
+impl<'a> From<&'a ByteString> for Cow<'a, ByteStr> {
+    #[inline]
+    fn from(s: &'a ByteString) -> Self {
+        Cow::Borrowed(s.as_bytestr())
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl FromIterator<char> for ByteString {
+    #[inline]
+    fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
+        ByteString(iter.into_iter().collect::<String>().into_bytes())
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl FromIterator<u8> for ByteString {
+    #[inline]
+    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
+        ByteString(iter.into_iter().collect())
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl<'a> FromIterator<&'a str> for ByteString {
+    #[inline]
+    fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
+        ByteString(iter.into_iter().collect::<String>().into_bytes())
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl<'a> FromIterator<&'a [u8]> for ByteString {
+    #[inline]
+    fn from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> Self {
+        let mut buf = Vec::new();
+        for b in iter {
+            buf.extend_from_slice(b);
+        }
+        ByteString(buf)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl<'a> FromIterator<&'a ByteStr> for ByteString {
+    #[inline]
+    fn from_iter<T: IntoIterator<Item = &'a ByteStr>>(iter: T) -> Self {
+        let mut buf = Vec::new();
+        for b in iter {
+            buf.extend_from_slice(&b.0);
+        }
+        ByteString(buf)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl FromIterator<ByteString> for ByteString {
+    #[inline]
+    fn from_iter<T: IntoIterator<Item = ByteString>>(iter: T) -> Self {
+        let mut buf = Vec::new();
+        for mut b in iter {
+            buf.append(&mut b.0);
+        }
+        ByteString(buf)
+    }
+}
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+#[unstable(feature = "bstr", issue = "134915")]
+impl FromStr for ByteString {
+    type Err = core::convert::Infallible;
+
+    #[inline]
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Ok(ByteString(s.as_bytes().to_vec()))
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Index<usize> for ByteString {
+    type Output = u8;
+
+    #[inline]
+    fn index(&self, idx: usize) -> &u8 {
+        &self.0[idx]
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Index<RangeFull> for ByteString {
+    type Output = ByteStr;
+
+    #[inline]
+    fn index(&self, _: RangeFull) -> &ByteStr {
+        self.as_bytestr()
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Index<Range<usize>> for ByteString {
+    type Output = ByteStr;
+
+    #[inline]
+    fn index(&self, r: Range<usize>) -> &ByteStr {
+        ByteStr::from_bytes(&self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Index<RangeInclusive<usize>> for ByteString {
+    type Output = ByteStr;
+
+    #[inline]
+    fn index(&self, r: RangeInclusive<usize>) -> &ByteStr {
+        ByteStr::from_bytes(&self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Index<RangeFrom<usize>> for ByteString {
+    type Output = ByteStr;
+
+    #[inline]
+    fn index(&self, r: RangeFrom<usize>) -> &ByteStr {
+        ByteStr::from_bytes(&self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Index<RangeTo<usize>> for ByteString {
+    type Output = ByteStr;
+
+    #[inline]
+    fn index(&self, r: RangeTo<usize>) -> &ByteStr {
+        ByteStr::from_bytes(&self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Index<RangeToInclusive<usize>> for ByteString {
+    type Output = ByteStr;
+
+    #[inline]
+    fn index(&self, r: RangeToInclusive<usize>) -> &ByteStr {
+        ByteStr::from_bytes(&self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl IndexMut<usize> for ByteString {
+    #[inline]
+    fn index_mut(&mut self, idx: usize) -> &mut u8 {
+        &mut self.0[idx]
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl IndexMut<RangeFull> for ByteString {
+    #[inline]
+    fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr {
+        self.as_mut_bytestr()
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl IndexMut<Range<usize>> for ByteString {
+    #[inline]
+    fn index_mut(&mut self, r: Range<usize>) -> &mut ByteStr {
+        ByteStr::from_bytes_mut(&mut self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl IndexMut<RangeInclusive<usize>> for ByteString {
+    #[inline]
+    fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut ByteStr {
+        ByteStr::from_bytes_mut(&mut self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl IndexMut<RangeFrom<usize>> for ByteString {
+    #[inline]
+    fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut ByteStr {
+        ByteStr::from_bytes_mut(&mut self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl IndexMut<RangeTo<usize>> for ByteString {
+    #[inline]
+    fn index_mut(&mut self, r: RangeTo<usize>) -> &mut ByteStr {
+        ByteStr::from_bytes_mut(&mut self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl IndexMut<RangeToInclusive<usize>> for ByteString {
+    #[inline]
+    fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut ByteStr {
+        ByteStr::from_bytes_mut(&mut self.0[r])
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl hash::Hash for ByteString {
+    #[inline]
+    fn hash<H: hash::Hasher>(&self, state: &mut H) {
+        self.0.hash(state);
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Eq for ByteString {}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl PartialEq for ByteString {
+    #[inline]
+    fn eq(&self, other: &ByteString) -> bool {
+        self.0 == other.0
+    }
+}
+
+macro_rules! impl_partial_eq_ord_cow {
+    ($lhs:ty, $rhs:ty) => {
+        #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+        #[allow(unused_lifetimes)]
+        #[unstable(feature = "bstr", issue = "134915")]
+        impl<'a> PartialEq<$rhs> for $lhs {
+            #[inline]
+            fn eq(&self, other: &$rhs) -> bool {
+                let other: &[u8] = (&**other).as_ref();
+                PartialEq::eq(self.as_bytes(), other)
+            }
+        }
+
+        #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+        #[allow(unused_lifetimes)]
+        #[unstable(feature = "bstr", issue = "134915")]
+        impl<'a> PartialEq<$lhs> for $rhs {
+            #[inline]
+            fn eq(&self, other: &$lhs) -> bool {
+                let this: &[u8] = (&**self).as_ref();
+                PartialEq::eq(this, other.as_bytes())
+            }
+        }
+
+        #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+        #[allow(unused_lifetimes)]
+        #[unstable(feature = "bstr", issue = "134915")]
+        impl<'a> PartialOrd<$rhs> for $lhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
+                let other: &[u8] = (&**other).as_ref();
+                PartialOrd::partial_cmp(self.as_bytes(), other)
+            }
+        }
+
+        #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+        #[allow(unused_lifetimes)]
+        #[unstable(feature = "bstr", issue = "134915")]
+        impl<'a> PartialOrd<$lhs> for $rhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
+                let this: &[u8] = (&**self).as_ref();
+                PartialOrd::partial_cmp(this, other.as_bytes())
+            }
+        }
+    };
+}
+
+// PartialOrd with `Vec<u8>` omitted to avoid inference failures
+impl_partial_eq!(ByteString, Vec<u8>);
+// PartialOrd with `[u8]` omitted to avoid inference failures
+impl_partial_eq!(ByteString, [u8]);
+// PartialOrd with `&[u8]` omitted to avoid inference failures
+impl_partial_eq!(ByteString, &[u8]);
+// PartialOrd with `String` omitted to avoid inference failures
+impl_partial_eq!(ByteString, String);
+// PartialOrd with `str` omitted to avoid inference failures
+impl_partial_eq!(ByteString, str);
+// PartialOrd with `&str` omitted to avoid inference failures
+impl_partial_eq!(ByteString, &str);
+impl_partial_eq_ord!(ByteString, ByteStr);
+impl_partial_eq_ord!(ByteString, &ByteStr);
+// PartialOrd with `[u8; N]` omitted to avoid inference failures
+impl_partial_eq_n!(ByteString, [u8; N]);
+// PartialOrd with `&[u8; N]` omitted to avoid inference failures
+impl_partial_eq_n!(ByteString, &[u8; N]);
+impl_partial_eq_ord_cow!(ByteString, Cow<'_, ByteStr>);
+impl_partial_eq_ord_cow!(ByteString, Cow<'_, str>);
+impl_partial_eq_ord_cow!(ByteString, Cow<'_, [u8]>);
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl Ord for ByteString {
+    #[inline]
+    fn cmp(&self, other: &ByteString) -> Ordering {
+        Ord::cmp(&self.0, &other.0)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl PartialOrd for ByteString {
+    #[inline]
+    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
+        PartialOrd::partial_cmp(&self.0, &other.0)
+    }
+}
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+#[unstable(feature = "bstr", issue = "134915")]
+impl ToOwned for ByteStr {
+    type Owned = ByteString;
+
+    #[inline]
+    fn to_owned(&self) -> ByteString {
+        ByteString(self.0.to_vec())
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl TryFrom<ByteString> for String {
+    type Error = crate::string::FromUtf8Error;
+
+    #[inline]
+    fn try_from(s: ByteString) -> Result<Self, Self::Error> {
+        String::from_utf8(s.0)
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl<'a> TryFrom<&'a ByteString> for &'a str {
+    type Error = crate::str::Utf8Error;
+
+    #[inline]
+    fn try_from(s: &'a ByteString) -> Result<Self, Self::Error> {
+        crate::str::from_utf8(s.0.as_slice())
+    }
+}
+
+// Additional impls for `ByteStr` that require types from `alloc`:
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+#[unstable(feature = "bstr", issue = "134915")]
+impl Clone for Box<ByteStr> {
+    #[inline]
+    fn clone(&self) -> Self {
+        Self::from(Box::<[u8]>::from(&self.0))
+    }
+}
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+#[unstable(feature = "bstr", issue = "134915")]
+impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> {
+    #[inline]
+    fn from(s: &'a ByteStr) -> Self {
+        Cow::Borrowed(s)
+    }
+}
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+#[unstable(feature = "bstr", issue = "134915")]
+impl From<Box<[u8]>> for Box<ByteStr> {
+    #[inline]
+    fn from(s: Box<[u8]>) -> Box<ByteStr> {
+        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
+        unsafe { Box::from_raw(Box::into_raw(s) as _) }
+    }
+}
+
+#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
+#[unstable(feature = "bstr", issue = "134915")]
+impl From<Box<ByteStr>> for Box<[u8]> {
+    #[inline]
+    fn from(s: Box<ByteStr>) -> Box<[u8]> {
+        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
+        unsafe { Box::from_raw(Box::into_raw(s) as _) }
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+#[cfg(not(no_rc))]
+impl From<Rc<[u8]>> for Rc<ByteStr> {
+    #[inline]
+    fn from(s: Rc<[u8]>) -> Rc<ByteStr> {
+        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
+        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+#[cfg(not(no_rc))]
+impl From<Rc<ByteStr>> for Rc<[u8]> {
+    #[inline]
+    fn from(s: Rc<ByteStr>) -> Rc<[u8]> {
+        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
+        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
+impl From<Arc<[u8]>> for Arc<ByteStr> {
+    #[inline]
+    fn from(s: Arc<[u8]>) -> Arc<ByteStr> {
+        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
+        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
+    }
+}
+
+#[unstable(feature = "bstr", issue = "134915")]
+#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
+impl From<Arc<ByteStr>> for Arc<[u8]> {
+    #[inline]
+    fn from(s: Arc<ByteStr>) -> Arc<[u8]> {
+        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
+        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
+    }
+}
+
+// PartialOrd with `Vec<u8>` omitted to avoid inference failures
+impl_partial_eq!(ByteStr, Vec<u8>);
+// PartialOrd with `String` omitted to avoid inference failures
+impl_partial_eq!(ByteStr, String);
+impl_partial_eq_ord_cow!(&'a ByteStr, Cow<'a, ByteStr>);
+impl_partial_eq_ord_cow!(&'a ByteStr, Cow<'a, str>);
+impl_partial_eq_ord_cow!(&'a ByteStr, Cow<'a, [u8]>);
+
+#[unstable(feature = "bstr", issue = "134915")]
+impl<'a> TryFrom<&'a ByteStr> for String {
+    type Error = core::str::Utf8Error;
+
+    #[inline]
+    fn try_from(s: &'a ByteStr) -> Result<Self, Self::Error> {
+        Ok(core::str::from_utf8(&s.0)?.into())
+    }
+}
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 9660023d694..041f80c1f2c 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1442,20 +1442,20 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
     ///
     /// let mut set = BTreeSet::from([1, 2, 3, 4]);
     ///
-    /// let mut cursor = unsafe { set.upper_bound_mut(Bound::Included(&3)) };
+    /// let mut cursor = set.upper_bound_mut(Bound::Included(&3));
     /// assert_eq!(cursor.peek_prev(), Some(&3));
     /// assert_eq!(cursor.peek_next(), Some(&4));
     ///
-    /// let mut cursor = unsafe { set.upper_bound_mut(Bound::Excluded(&3)) };
+    /// let mut cursor = set.upper_bound_mut(Bound::Excluded(&3));
     /// assert_eq!(cursor.peek_prev(), Some(&2));
     /// assert_eq!(cursor.peek_next(), Some(&3));
     ///
-    /// let mut cursor = unsafe { set.upper_bound_mut(Bound::Unbounded) };
+    /// let mut cursor = set.upper_bound_mut(Bound::Unbounded);
     /// assert_eq!(cursor.peek_prev(), Some(&4));
     /// assert_eq!(cursor.peek_next(), None);
     /// ```
     #[unstable(feature = "btree_cursors", issue = "107540")]
-    pub unsafe fn upper_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
+    pub fn upper_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
     where
         T: Borrow<Q> + Ord,
         Q: Ord,
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 0b6a55297e1..1c33f8f60d8 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -1735,6 +1735,52 @@ impl<T, A: Allocator> VecDeque<T, A> {
         }
     }
 
+    /// Removes and returns the first element from the deque if the predicate
+    /// returns `true`, or [`None`] if the predicate returns false or the deque
+    /// is empty (the predicate will not be called in that case).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(vec_deque_pop_if)]
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut deque: VecDeque<i32> = vec![0, 1, 2, 3, 4].into();
+    /// let pred = |x: &mut i32| *x % 2 == 0;
+    ///
+    /// assert_eq!(deque.pop_front_if(pred), Some(0));
+    /// assert_eq!(deque, [1, 2, 3, 4]);
+    /// assert_eq!(deque.pop_front_if(pred), None);
+    /// ```
+    #[unstable(feature = "vec_deque_pop_if", issue = "135889")]
+    pub fn pop_front_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
+        let first = self.front_mut()?;
+        if predicate(first) { self.pop_front() } else { None }
+    }
+
+    /// Removes and returns the last element from the deque if the predicate
+    /// returns `true`, or [`None`] if the predicate returns false or the deque
+    /// is empty (the predicate will not be called in that case).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(vec_deque_pop_if)]
+    /// use std::collections::VecDeque;
+    ///
+    /// let mut deque: VecDeque<i32> = vec![0, 1, 2, 3, 4].into();
+    /// let pred = |x: &mut i32| *x % 2 == 0;
+    ///
+    /// assert_eq!(deque.pop_back_if(pred), Some(4));
+    /// assert_eq!(deque, [0, 1, 2, 3]);
+    /// assert_eq!(deque.pop_back_if(pred), None);
+    /// ```
+    #[unstable(feature = "vec_deque_pop_if", issue = "135889")]
+    pub fn pop_back_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
+        let first = self.back_mut()?;
+        if predicate(first) { self.pop_back() } else { None }
+    }
+
     /// Prepends an element to the deque.
     ///
     /// # Examples
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index b4f08debc93..28e4217e303 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -102,6 +102,8 @@
 #![feature(async_fn_traits)]
 #![feature(async_iterator)]
 #![feature(box_uninit_write)]
+#![feature(bstr)]
+#![feature(bstr_internals)]
 #![feature(clone_to_uninit)]
 #![feature(coerce_unsized)]
 #![feature(const_eval_select)]
@@ -228,6 +230,8 @@ mod boxed {
     pub use std::boxed::Box;
 }
 pub mod borrow;
+#[unstable(feature = "bstr", issue = "134915")]
+pub mod bstr;
 pub mod collections;
 #[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))]
 pub mod ffi;
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index cd2afd7a473..54673ceb1da 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2511,9 +2511,9 @@ impl<T, A: Allocator> Vec<T, A> {
         }
     }
 
-    /// Removes and returns the last element in a vector if the predicate
+    /// Removes and returns the last element from a vector if the predicate
     /// returns `true`, or [`None`] if the predicate returns false or the vector
-    /// is empty.
+    /// is empty (the predicate will not be called in that case).
     ///
     /// # Examples
     ///
@@ -2528,12 +2528,9 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert_eq!(vec.pop_if(pred), None);
     /// ```
     #[unstable(feature = "vec_pop_if", issue = "122741")]
-    pub fn pop_if<F>(&mut self, f: F) -> Option<T>
-    where
-        F: FnOnce(&mut T) -> bool,
-    {
+    pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
         let last = self.last_mut()?;
-        if f(last) { self.pop() } else { None }
+        if predicate(last) { self.pop() } else { None }
     }
 
     /// Moves all the elements of `other` into `self`, leaving `other` empty.
@@ -2574,9 +2571,11 @@ impl<T, A: Allocator> Vec<T, A> {
         self.len += count;
     }
 
-    /// Removes the specified range from the vector in bulk, returning all
-    /// removed elements as an iterator. If the iterator is dropped before
-    /// being fully consumed, it drops the remaining removed elements.
+    /// Removes the subslice indicated by the given range from the vector,
+    /// returning a double-ended iterator over the removed subslice.
+    ///
+    /// If the iterator is dropped before being fully consumed,
+    /// it drops the remaining removed elements.
     ///
     /// The returned iterator keeps a mutable borrow on the vector to optimize
     /// its implementation.
@@ -3016,10 +3015,9 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
     /// Iterates over the slice `other`, clones each element, and then appends
     /// it to this `Vec`. The `other` slice is traversed in-order.
     ///
-    /// Note that this function is same as [`extend`] except that it is
-    /// specialized to work with slices instead. If and when Rust gets
-    /// specialization this function will likely be deprecated (but still
-    /// available).
+    /// Note that this function is the same as [`extend`],
+    /// except that it also works with slice elements that are Clone but not Copy.
+    /// If Rust gets specialization this function may be deprecated.
     ///
     /// # Examples
     ///