Fully test the alloc crate through alloctests

For the tests that make use of internal implementation details, we
include the module to test using #[path] in alloctests now.
This commit is contained in:
bjorn3 2025-02-06 12:46:33 +00:00
parent 701bedc323
commit ae5687e4b0
28 changed files with 232 additions and 311 deletions

View file

@ -12,15 +12,15 @@ index 7165c3e48af..968552ad435 100644
--- a/library/alloc/Cargo.toml --- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml
@@ -11,7 +11,7 @@ test = { path = "../test" } @@ -11,7 +11,7 @@ test = { path = "../test" }
edition = "2021" bench = false
[dependencies] [dependencies]
core = { path = "../core", public = true } core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] } -compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std', 'no-f16-f128'] } +compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std', 'no-f16-f128'] }
[dev-dependencies] [features]
rand = { version = "0.8.5", default-features = false, features = ["alloc"] } compiler-builtins-mem = ['compiler_builtins/mem']
-- --
2.34.1 2.34.1

View file

@ -30,8 +30,6 @@ version = "0.0.0"
dependencies = [ dependencies = [
"compiler_builtins", "compiler_builtins",
"core", "core",
"rand",
"rand_xorshift",
] ]
[[package]] [[package]]

View file

@ -10,14 +10,14 @@ autotests = false
autobenches = false autobenches = false
edition = "2021" edition = "2021"
[lib]
test = false
bench = false
[dependencies] [dependencies]
core = { path = "../core", public = true } core = { path = "../core", public = true }
compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] } compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] }
[dev-dependencies]
rand = { version = "0.9.0", default-features = false, features = ["alloc"] }
rand_xorshift = "0.4.0"
[features] [features]
compiler-builtins-mem = ['compiler_builtins/mem'] compiler-builtins-mem = ['compiler_builtins/mem']
compiler-builtins-c = ["compiler_builtins/c"] compiler-builtins-c = ["compiler_builtins/c"]

View file

@ -5,9 +5,7 @@
#[stable(feature = "alloc_module", since = "1.28.0")] #[stable(feature = "alloc_module", since = "1.28.0")]
#[doc(inline)] #[doc(inline)]
pub use core::alloc::*; pub use core::alloc::*;
#[cfg(not(test))]
use core::hint; use core::hint;
#[cfg(not(test))]
use core::ptr::{self, NonNull}; use core::ptr::{self, NonNull};
unsafe extern "Rust" { unsafe extern "Rust" {
@ -44,14 +42,10 @@ unsafe extern "Rust" {
/// accessed through the [free functions in `alloc`](self#functions). /// accessed through the [free functions in `alloc`](self#functions).
#[unstable(feature = "allocator_api", issue = "32838")] #[unstable(feature = "allocator_api", issue = "32838")]
#[derive(Copy, Clone, Default, Debug)] #[derive(Copy, Clone, Default, Debug)]
#[cfg(not(test))]
// the compiler needs to know when a Box uses the global allocator vs a custom one // the compiler needs to know when a Box uses the global allocator vs a custom one
#[lang = "global_alloc_ty"] #[lang = "global_alloc_ty"]
pub struct Global; pub struct Global;
#[cfg(test)]
pub use std::alloc::Global;
/// Allocates memory with the global allocator. /// Allocates memory with the global allocator.
/// ///
/// This function forwards calls to the [`GlobalAlloc::alloc`] method /// This function forwards calls to the [`GlobalAlloc::alloc`] method
@ -180,7 +174,6 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
} }
} }
#[cfg(not(test))]
impl Global { impl Global {
#[inline] #[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@ -246,7 +239,6 @@ impl Global {
} }
#[unstable(feature = "allocator_api", issue = "32838")] #[unstable(feature = "allocator_api", issue = "32838")]
#[cfg(not(test))]
unsafe impl Allocator for Global { unsafe impl Allocator for Global {
#[inline] #[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@ -346,7 +338,7 @@ unsafe impl Allocator for Global {
} }
/// The allocator for `Box`. /// The allocator for `Box`.
#[cfg(all(not(no_global_oom_handling), not(test)))] #[cfg(not(no_global_oom_handling))]
#[lang = "exchange_malloc"] #[lang = "exchange_malloc"]
#[inline] #[inline]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@ -395,7 +387,7 @@ unsafe extern "Rust" {
/// [no_std]: https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute /// [no_std]: https://doc.rust-lang.org/reference/names/preludes.html#the-no_std-attribute
#[stable(feature = "global_alloc", since = "1.28.0")] #[stable(feature = "global_alloc", since = "1.28.0")]
#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")] #[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
#[cfg(all(not(no_global_oom_handling), not(test)))] #[cfg(not(no_global_oom_handling))]
#[cold] #[cold]
#[optimize(size)] #[optimize(size)]
pub const fn handle_alloc_error(layout: Layout) -> ! { pub const fn handle_alloc_error(layout: Layout) -> ! {
@ -419,11 +411,7 @@ pub const fn handle_alloc_error(layout: Layout) -> ! {
ct_error(layout) ct_error(layout)
} }
// For alloc test `std::alloc::handle_alloc_error` can be used directly. #[cfg(not(no_global_oom_handling))]
#[cfg(all(not(no_global_oom_handling), test))]
pub use std::alloc::handle_alloc_error;
#[cfg(all(not(no_global_oom_handling), not(test)))]
#[doc(hidden)] #[doc(hidden)]
#[allow(unused_attributes)] #[allow(unused_attributes)]
#[unstable(feature = "alloc_internals", issue = "none")] #[unstable(feature = "alloc_internals", issue = "none")]

View file

@ -32,7 +32,7 @@ where
/// implementing the `Clone` trait. But `Clone` works only for going from `&T` /// implementing the `Clone` trait. But `Clone` works only for going from `&T`
/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data /// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
/// from any borrow of a given type. /// from any borrow of a given type.
#[cfg_attr(not(test), rustc_diagnostic_item = "ToOwned")] #[rustc_diagnostic_item = "ToOwned"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait ToOwned { pub trait ToOwned {
/// The resulting type after obtaining ownership. /// The resulting type after obtaining ownership.
@ -54,7 +54,7 @@ pub trait ToOwned {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "cloning is often expensive and is not expected to have side effects"] #[must_use = "cloning is often expensive and is not expected to have side effects"]
#[cfg_attr(not(test), rustc_diagnostic_item = "to_owned_method")] #[rustc_diagnostic_item = "to_owned_method"]
fn to_owned(&self) -> Self::Owned; fn to_owned(&self) -> Self::Owned;
/// Uses borrowed data to replace owned data, usually by cloning. /// Uses borrowed data to replace owned data, usually by cloning.
@ -175,7 +175,7 @@ where
/// } /// }
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "Cow")] #[rustc_diagnostic_item = "Cow"]
pub enum Cow<'a, B: ?Sized + 'a> pub enum Cow<'a, B: ?Sized + 'a>
where where
B: ToOwned, B: ToOwned,

View file

@ -12,13 +12,10 @@ use core::ops::{
Deref, DerefMut, DerefPure, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, Deref, DerefMut, DerefPure, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive,
RangeTo, RangeToInclusive, RangeTo, RangeToInclusive,
}; };
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
use core::str::FromStr; use core::str::FromStr;
use core::{fmt, hash}; use core::{fmt, hash};
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
use crate::borrow::{Cow, ToOwned}; use crate::borrow::{Cow, ToOwned};
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
use crate::boxed::Box; use crate::boxed::Box;
#[cfg(not(no_rc))] #[cfg(not(no_rc))]
use crate::rc::Rc; use crate::rc::Rc;
@ -181,7 +178,6 @@ impl Default for ByteString {
// Omitted due to inference failures // Omitted due to inference failures
// //
// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
// #[unstable(feature = "bstr", issue = "134915")] // #[unstable(feature = "bstr", issue = "134915")]
// impl<'a, const N: usize> From<&'a [u8; N]> for ByteString { // impl<'a, const N: usize> From<&'a [u8; N]> for ByteString {
// #[inline] // #[inline]
@ -190,7 +186,6 @@ impl Default for ByteString {
// } // }
// } // }
// //
// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
// #[unstable(feature = "bstr", issue = "134915")] // #[unstable(feature = "bstr", issue = "134915")]
// impl<const N: usize> From<[u8; N]> for ByteString { // impl<const N: usize> From<[u8; N]> for ByteString {
// #[inline] // #[inline]
@ -199,7 +194,6 @@ impl Default for ByteString {
// } // }
// } // }
// //
// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
// #[unstable(feature = "bstr", issue = "134915")] // #[unstable(feature = "bstr", issue = "134915")]
// impl<'a> From<&'a [u8]> for ByteString { // impl<'a> From<&'a [u8]> for ByteString {
// #[inline] // #[inline]
@ -226,7 +220,6 @@ impl From<ByteString> for Vec<u8> {
// Omitted due to inference failures // Omitted due to inference failures
// //
// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
// #[unstable(feature = "bstr", issue = "134915")] // #[unstable(feature = "bstr", issue = "134915")]
// impl<'a> From<&'a str> for ByteString { // impl<'a> From<&'a str> for ByteString {
// #[inline] // #[inline]
@ -243,7 +236,6 @@ impl From<ByteString> for Vec<u8> {
// } // }
// } // }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl<'a> From<&'a ByteStr> for ByteString { impl<'a> From<&'a ByteStr> for ByteString {
#[inline] #[inline]
@ -252,7 +244,6 @@ impl<'a> From<&'a ByteStr> for ByteString {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl<'a> From<ByteString> for Cow<'a, ByteStr> { impl<'a> From<ByteString> for Cow<'a, ByteStr> {
#[inline] #[inline]
@ -261,7 +252,6 @@ impl<'a> From<ByteString> for Cow<'a, ByteStr> {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl<'a> From<&'a ByteString> for Cow<'a, ByteStr> { impl<'a> From<&'a ByteString> for Cow<'a, ByteStr> {
#[inline] #[inline]
@ -330,7 +320,6 @@ impl FromIterator<ByteString> for ByteString {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl FromStr for ByteString { impl FromStr for ByteString {
type Err = core::convert::Infallible; type Err = core::convert::Infallible;
@ -488,7 +477,6 @@ impl PartialEq for ByteString {
macro_rules! impl_partial_eq_ord_cow { macro_rules! impl_partial_eq_ord_cow {
($lhs:ty, $rhs:ty) => { ($lhs:ty, $rhs:ty) => {
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[allow(unused_lifetimes)] #[allow(unused_lifetimes)]
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl<'a> PartialEq<$rhs> for $lhs { impl<'a> PartialEq<$rhs> for $lhs {
@ -499,7 +487,6 @@ macro_rules! impl_partial_eq_ord_cow {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[allow(unused_lifetimes)] #[allow(unused_lifetimes)]
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl<'a> PartialEq<$lhs> for $rhs { impl<'a> PartialEq<$lhs> for $rhs {
@ -510,7 +497,6 @@ macro_rules! impl_partial_eq_ord_cow {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[allow(unused_lifetimes)] #[allow(unused_lifetimes)]
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl<'a> PartialOrd<$rhs> for $lhs { impl<'a> PartialOrd<$rhs> for $lhs {
@ -521,7 +507,6 @@ macro_rules! impl_partial_eq_ord_cow {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[allow(unused_lifetimes)] #[allow(unused_lifetimes)]
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl<'a> PartialOrd<$lhs> for $rhs { impl<'a> PartialOrd<$lhs> for $rhs {
@ -572,7 +557,6 @@ impl PartialOrd for ByteString {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl ToOwned for ByteStr { impl ToOwned for ByteStr {
type Owned = ByteString; type Owned = ByteString;
@ -605,7 +589,6 @@ impl<'a> TryFrom<&'a ByteString> for &'a str {
// Additional impls for `ByteStr` that require types from `alloc`: // 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")] #[unstable(feature = "bstr", issue = "134915")]
impl Clone for Box<ByteStr> { impl Clone for Box<ByteStr> {
#[inline] #[inline]
@ -614,7 +597,6 @@ impl Clone for Box<ByteStr> {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> { impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> {
#[inline] #[inline]
@ -623,7 +605,6 @@ impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl From<Box<[u8]>> for Box<ByteStr> { impl From<Box<[u8]>> for Box<ByteStr> {
#[inline] #[inline]
@ -633,7 +614,6 @@ impl From<Box<[u8]>> for Box<ByteStr> {
} }
} }
#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
impl From<Box<ByteStr>> for Box<[u8]> { impl From<Box<ByteStr>> for Box<[u8]> {
#[inline] #[inline]

View file

@ -153,7 +153,9 @@ use core::{fmt, ptr};
use crate::alloc::Global; use crate::alloc::Global;
use crate::collections::TryReserveError; use crate::collections::TryReserveError;
use crate::slice; use crate::slice;
use crate::vec::{self, AsVecIntoIter, Vec}; #[cfg(not(test))]
use crate::vec::AsVecIntoIter;
use crate::vec::{self, Vec};
/// A priority queue implemented with a binary heap. /// A priority queue implemented with a binary heap.
/// ///
@ -1600,6 +1602,7 @@ unsafe impl<I, A: Allocator> InPlaceIterable for IntoIter<I, A> {
const MERGE_BY: Option<NonZero<usize>> = NonZero::new(1); const MERGE_BY: Option<NonZero<usize>> = NonZero::new(1);
} }
#[cfg(not(test))]
unsafe impl<I> AsVecIntoIter for IntoIter<I> { unsafe impl<I> AsVecIntoIter for IntoIter<I> {
type Item = I; type Item = I;

View file

@ -24,41 +24,54 @@ pub mod btree_map {
pub mod btree_set { pub mod btree_set {
//! An ordered set based on a B-Tree. //! An ordered set based on a B-Tree.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(test))]
pub use super::btree::set::*; pub use super::btree::set::*;
} }
#[cfg(not(test))]
use core::fmt::Display; use core::fmt::Display;
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] #[doc(no_inline)]
#[cfg(not(test))]
pub use binary_heap::BinaryHeap; pub use binary_heap::BinaryHeap;
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] #[doc(no_inline)]
#[cfg(not(test))]
pub use btree_map::BTreeMap; pub use btree_map::BTreeMap;
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] #[doc(no_inline)]
#[cfg(not(test))]
pub use btree_set::BTreeSet; pub use btree_set::BTreeSet;
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] #[doc(no_inline)]
#[cfg(not(test))]
pub use linked_list::LinkedList; pub use linked_list::LinkedList;
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)] #[doc(no_inline)]
#[cfg(not(test))]
pub use vec_deque::VecDeque; pub use vec_deque::VecDeque;
#[cfg(not(test))]
use crate::alloc::{Layout, LayoutError}; use crate::alloc::{Layout, LayoutError};
/// The error type for `try_reserve` methods. /// The error type for `try_reserve` methods.
#[derive(Clone, PartialEq, Eq, Debug)] #[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "try_reserve", since = "1.57.0")] #[stable(feature = "try_reserve", since = "1.57.0")]
#[cfg(not(test))]
pub struct TryReserveError { pub struct TryReserveError {
kind: TryReserveErrorKind, kind: TryReserveErrorKind,
} }
#[cfg(test)]
pub use realalloc::collections::TryReserveError;
#[cfg(not(test))]
impl TryReserveError { impl TryReserveError {
/// Details about the allocation that caused the error /// Details about the allocation that caused the error
#[inline] #[inline]
@ -80,6 +93,7 @@ impl TryReserveError {
reason = "Uncertain how much info should be exposed", reason = "Uncertain how much info should be exposed",
issue = "48043" issue = "48043"
)] )]
#[cfg(not(test))]
pub enum TryReserveErrorKind { pub enum TryReserveErrorKind {
/// Error due to the computed capacity exceeding the collection's maximum /// Error due to the computed capacity exceeding the collection's maximum
/// (usually `isize::MAX` bytes). /// (usually `isize::MAX` bytes).
@ -103,11 +117,15 @@ pub enum TryReserveErrorKind {
}, },
} }
#[cfg(test)]
pub use realalloc::collections::TryReserveErrorKind;
#[unstable( #[unstable(
feature = "try_reserve_kind", feature = "try_reserve_kind",
reason = "Uncertain how much info should be exposed", reason = "Uncertain how much info should be exposed",
issue = "48043" issue = "48043"
)] )]
#[cfg(not(test))]
impl From<TryReserveErrorKind> for TryReserveError { impl From<TryReserveErrorKind> for TryReserveError {
#[inline] #[inline]
fn from(kind: TryReserveErrorKind) -> Self { fn from(kind: TryReserveErrorKind) -> Self {
@ -116,6 +134,7 @@ impl From<TryReserveErrorKind> for TryReserveError {
} }
#[unstable(feature = "try_reserve_kind", reason = "new API", issue = "48043")] #[unstable(feature = "try_reserve_kind", reason = "new API", issue = "48043")]
#[cfg(not(test))]
impl From<LayoutError> for TryReserveErrorKind { impl From<LayoutError> for TryReserveErrorKind {
/// Always evaluates to [`TryReserveErrorKind::CapacityOverflow`]. /// Always evaluates to [`TryReserveErrorKind::CapacityOverflow`].
#[inline] #[inline]
@ -125,6 +144,7 @@ impl From<LayoutError> for TryReserveErrorKind {
} }
#[stable(feature = "try_reserve", since = "1.57.0")] #[stable(feature = "try_reserve", since = "1.57.0")]
#[cfg(not(test))]
impl Display for TryReserveError { impl Display for TryReserveError {
fn fmt( fn fmt(
&self, &self,
@ -152,4 +172,5 @@ trait SpecExtend<I: IntoIterator> {
} }
#[stable(feature = "try_reserve", since = "1.57.0")] #[stable(feature = "try_reserve", since = "1.57.0")]
#[cfg(not(test))]
impl core::error::Error for TryReserveError {} impl core::error::Error for TryReserveError {}

View file

@ -645,6 +645,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
/// initialized rather than only supporting `0..len`. Requires that /// initialized rather than only supporting `0..len`. Requires that
/// `initialized.start` ≤ `initialized.end` ≤ `capacity`. /// `initialized.start` ≤ `initialized.end` ≤ `capacity`.
#[inline] #[inline]
#[cfg(not(test))]
pub(crate) unsafe fn from_contiguous_raw_parts_in( pub(crate) unsafe fn from_contiguous_raw_parts_in(
ptr: *mut T, ptr: *mut T,
initialized: Range<usize>, initialized: Range<usize>,

View file

@ -3,6 +3,7 @@ use core::slice;
use super::VecDeque; use super::VecDeque;
use crate::alloc::Allocator; use crate::alloc::Allocator;
#[cfg(not(test))]
use crate::vec; use crate::vec;
// Specialization trait used for VecDeque::extend // Specialization trait used for VecDeque::extend
@ -78,6 +79,7 @@ where
} }
} }
#[cfg(not(test))]
impl<T, A: Allocator> SpecExtend<T, vec::IntoIter<T>> for VecDeque<T, A> { impl<T, A: Allocator> SpecExtend<T, vec::IntoIter<T>> for VecDeque<T, A> {
#[track_caller] #[track_caller]
fn spec_extend(&mut self, mut iterator: vec::IntoIter<T>) { fn spec_extend(&mut self, mut iterator: vec::IntoIter<T>) {

View file

@ -19,6 +19,7 @@ where
} }
} }
#[cfg(not(test))]
impl<T> SpecFromIter<T, crate::vec::IntoIter<T>> for VecDeque<T> { impl<T> SpecFromIter<T, crate::vec::IntoIter<T>> for VecDeque<T> {
#[inline] #[inline]
fn spec_from_iter(iterator: crate::vec::IntoIter<T>) -> Self { fn spec_from_iter(iterator: crate::vec::IntoIter<T>) -> Self {

View file

@ -10,7 +10,6 @@ use core::{fmt, mem, ops, ptr, slice};
use crate::borrow::{Cow, ToOwned}; use crate::borrow::{Cow, ToOwned};
use crate::boxed::Box; use crate::boxed::Box;
use crate::rc::Rc; use crate::rc::Rc;
use crate::slice::hack::into_vec;
use crate::string::String; use crate::string::String;
#[cfg(target_has_atomic = "ptr")] #[cfg(target_has_atomic = "ptr")]
use crate::sync::Arc; use crate::sync::Arc;
@ -103,7 +102,7 @@ use crate::vec::Vec;
/// of `CString` instances can lead to invalid memory accesses, memory leaks, /// of `CString` instances can lead to invalid memory accesses, memory leaks,
/// and other memory errors. /// and other memory errors.
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)] #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
#[cfg_attr(not(test), rustc_diagnostic_item = "cstring_type")] #[rustc_diagnostic_item = "cstring_type"]
#[stable(feature = "alloc_c_string", since = "1.64.0")] #[stable(feature = "alloc_c_string", since = "1.64.0")]
pub struct CString { pub struct CString {
// Invariant 1: the slice ends with a zero byte and has a length of at least one. // Invariant 1: the slice ends with a zero byte and has a length of at least one.
@ -491,7 +490,7 @@ impl CString {
#[must_use = "`self` will be dropped if the result is not used"] #[must_use = "`self` will be dropped if the result is not used"]
#[stable(feature = "cstring_into", since = "1.7.0")] #[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_bytes(self) -> Vec<u8> { pub fn into_bytes(self) -> Vec<u8> {
let mut vec = into_vec(self.into_inner()); let mut vec = self.into_inner().into_vec();
let _nul = vec.pop(); let _nul = vec.pop();
debug_assert_eq!(_nul, Some(0u8)); debug_assert_eq!(_nul, Some(0u8));
vec vec
@ -512,7 +511,7 @@ impl CString {
#[must_use = "`self` will be dropped if the result is not used"] #[must_use = "`self` will be dropped if the result is not used"]
#[stable(feature = "cstring_into", since = "1.7.0")] #[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_bytes_with_nul(self) -> Vec<u8> { pub fn into_bytes_with_nul(self) -> Vec<u8> {
into_vec(self.into_inner()) self.into_inner().into_vec()
} }
/// Returns the contents of this `CString` as a slice of bytes. /// Returns the contents of this `CString` as a slice of bytes.
@ -573,7 +572,7 @@ impl CString {
#[inline] #[inline]
#[must_use] #[must_use]
#[stable(feature = "as_c_str", since = "1.20.0")] #[stable(feature = "as_c_str", since = "1.20.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "cstring_as_c_str")] #[rustc_diagnostic_item = "cstring_as_c_str"]
pub fn as_c_str(&self) -> &CStr { pub fn as_c_str(&self) -> &CStr {
&*self &*self
} }
@ -755,7 +754,6 @@ impl<'a> From<Cow<'a, CStr>> for CString {
} }
} }
#[cfg(not(test))]
#[stable(feature = "box_from_c_str", since = "1.17.0")] #[stable(feature = "box_from_c_str", since = "1.17.0")]
impl From<&CStr> for Box<CStr> { impl From<&CStr> for Box<CStr> {
/// Converts a `&CStr` into a `Box<CStr>`, /// Converts a `&CStr` into a `Box<CStr>`,
@ -766,7 +764,6 @@ impl From<&CStr> for Box<CStr> {
} }
} }
#[cfg(not(test))]
#[stable(feature = "box_from_mut_slice", since = "1.84.0")] #[stable(feature = "box_from_mut_slice", since = "1.84.0")]
impl From<&mut CStr> for Box<CStr> { impl From<&mut CStr> for Box<CStr> {
/// Converts a `&mut CStr` into a `Box<CStr>`, /// Converts a `&mut CStr` into a `Box<CStr>`,
@ -845,7 +842,6 @@ impl TryFrom<CString> for String {
} }
} }
#[cfg(not(test))]
#[stable(feature = "more_box_slice_clone", since = "1.29.0")] #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
impl Clone for Box<CStr> { impl Clone for Box<CStr> {
#[inline] #[inline]
@ -971,7 +967,6 @@ impl Default for Rc<CStr> {
} }
} }
#[cfg(not(test))]
#[stable(feature = "default_box_extra", since = "1.17.0")] #[stable(feature = "default_box_extra", since = "1.17.0")]
impl Default for Box<CStr> { impl Default for Box<CStr> {
fn default() -> Box<CStr> { fn default() -> Box<CStr> {
@ -1080,7 +1075,7 @@ impl ToOwned for CStr {
} }
fn clone_into(&self, target: &mut CString) { fn clone_into(&self, target: &mut CString) {
let mut b = into_vec(mem::take(&mut target.inner)); let mut b = mem::take(&mut target.inner).into_vec();
self.to_bytes_with_nul().clone_into(&mut b); self.to_bytes_with_nul().clone_into(&mut b);
target.inner = b.into_boxed_slice(); target.inner = b.into_boxed_slice();
} }
@ -1113,7 +1108,6 @@ impl AsRef<CStr> for CString {
} }
} }
#[cfg(not(test))]
impl CStr { impl CStr {
/// Converts a `CStr` into a <code>[Cow]<[str]></code>. /// Converts a `CStr` into a <code>[Cow]<[str]></code>.
/// ///

View file

@ -92,7 +92,6 @@
// //
// Library features: // Library features:
// tidy-alphabetical-start // tidy-alphabetical-start
#![cfg_attr(test, feature(str_as_str))]
#![feature(alloc_layout_extra)] #![feature(alloc_layout_extra)]
#![feature(allocator_api)] #![feature(allocator_api)]
#![feature(array_chunks)] #![feature(array_chunks)]
@ -159,13 +158,11 @@
// //
// Language features: // Language features:
// tidy-alphabetical-start // tidy-alphabetical-start
#![cfg_attr(not(test), feature(coroutine_trait))]
#![cfg_attr(test, feature(panic_update_hook))]
#![cfg_attr(test, feature(test))]
#![feature(allocator_internals)] #![feature(allocator_internals)]
#![feature(allow_internal_unstable)] #![feature(allow_internal_unstable)]
#![feature(cfg_sanitize)] #![feature(cfg_sanitize)]
#![feature(const_precise_live_drops)] #![feature(const_precise_live_drops)]
#![feature(coroutine_trait)]
#![feature(decl_macro)] #![feature(decl_macro)]
#![feature(dropck_eyepatch)] #![feature(dropck_eyepatch)]
#![feature(fundamental)] #![feature(fundamental)]
@ -198,15 +195,6 @@
// from other crates, but since this can only appear for lang items, it doesn't seem worth fixing. // from other crates, but since this can only appear for lang items, it doesn't seem worth fixing.
#![feature(intra_doc_pointers)] #![feature(intra_doc_pointers)]
// Allow testing this library
#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;
#[cfg(test)]
mod testing;
// Module with internal macros used by other modules (needs to be included before other modules). // Module with internal macros used by other modules (needs to be included before other modules).
#[macro_use] #[macro_use]
mod macros; mod macros;
@ -214,7 +202,6 @@ mod macros;
mod raw_vec; mod raw_vec;
// Heaps provided for low-level allocation strategies // Heaps provided for low-level allocation strategies
pub mod alloc; pub mod alloc;
// Primitive types using the heaps above // Primitive types using the heaps above
@ -222,13 +209,8 @@ pub mod alloc;
// Need to conditionally define the mod from `boxed.rs` to avoid // Need to conditionally define the mod from `boxed.rs` to avoid
// duplicating the lang-items when building in test cfg; but also need // duplicating the lang-items when building in test cfg; but also need
// to allow code to have `use boxed::Box;` declarations. // to allow code to have `use boxed::Box;` declarations.
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
mod boxed {
pub(crate) use std::boxed::Box;
}
pub mod borrow; pub mod borrow;
pub mod boxed;
#[unstable(feature = "bstr", issue = "134915")] #[unstable(feature = "bstr", issue = "134915")]
pub mod bstr; pub mod bstr;
pub mod collections; pub mod collections;
@ -252,20 +234,3 @@ pub mod __export {
pub use core::format_args; pub use core::format_args;
pub use core::hint::must_use; pub use core::hint::must_use;
} }
#[cfg(test)]
#[allow(dead_code)] // Not used in all configurations
pub(crate) mod test_helpers {
/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
/// seed not being the same for every RNG invocation too.
pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
use std::hash::{BuildHasher, Hash, Hasher};
let mut hasher = std::hash::RandomState::new().build_hasher();
std::panic::Location::caller().hash(&mut hasher);
let hc64 = hasher.finish();
let seed_vec =
hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<crate::vec::Vec<u8>>();
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
rand::SeedableRng::from_seed(seed)
}
}

View file

@ -34,7 +34,7 @@
/// be mindful of side effects. /// be mindful of side effects.
/// ///
/// [`Vec`]: crate::vec::Vec /// [`Vec`]: crate::vec::Vec
#[cfg(all(not(no_global_oom_handling), not(test)))] #[cfg(not(no_global_oom_handling))]
#[macro_export] #[macro_export]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "vec_macro"] #[rustc_diagnostic_item = "vec_macro"]
@ -55,25 +55,6 @@ macro_rules! vec {
); );
} }
// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
// required for this macro definition, is not available. Instead use the
// `slice::into_vec` function which is only available with cfg(test)
// NB see the slice::hack module in slice.rs for more information
#[cfg(all(not(no_global_oom_handling), test))]
#[allow(unused_macro_rules)]
macro_rules! vec {
() => (
$crate::vec::Vec::new()
);
($elem:expr; $n:expr) => (
$crate::vec::from_elem($elem, $n)
);
($($x:expr),*) => (
$crate::slice::into_vec($crate::boxed::Box::new([$($x),*]))
);
($($x:expr,)*) => (vec![$($x),*])
}
/// Creates a `String` using interpolation of runtime expressions. /// Creates a `String` using interpolation of runtime expressions.
/// ///
/// The first argument `format!` receives is a format string. This must be a string /// The first argument `format!` receives is a format string. This must be a string
@ -120,7 +101,7 @@ macro_rules! vec {
#[macro_export] #[macro_export]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(hint_must_use, liballoc_internals)] #[allow_internal_unstable(hint_must_use, liballoc_internals)]
#[cfg_attr(not(test), rustc_diagnostic_item = "format_macro")] #[rustc_diagnostic_item = "format_macro"]
macro_rules! format { macro_rules! format {
($($arg:tt)*) => { ($($arg:tt)*) => {
$crate::__export::must_use({ $crate::__export::must_use({

View file

@ -1,4 +1,5 @@
#![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")] #![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")]
#![cfg_attr(test, allow(dead_code))]
use core::marker::PhantomData; use core::marker::PhantomData;
use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties}; use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties};

View file

@ -262,14 +262,11 @@ use core::ptr::{self, NonNull, drop_in_place};
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
use core::slice::from_raw_parts_mut; use core::slice::from_raw_parts_mut;
use core::{borrow, fmt, hint}; use core::{borrow, fmt, hint};
#[cfg(test)]
use std::boxed::Box;
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
use crate::alloc::handle_alloc_error; use crate::alloc::handle_alloc_error;
use crate::alloc::{AllocError, Allocator, Global, Layout}; use crate::alloc::{AllocError, Allocator, Global, Layout};
use crate::borrow::{Cow, ToOwned}; use crate::borrow::{Cow, ToOwned};
#[cfg(not(test))]
use crate::boxed::Box; use crate::boxed::Box;
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
use crate::string::String; use crate::string::String;
@ -306,7 +303,7 @@ fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout {
/// ///
/// [get_mut]: Rc::get_mut /// [get_mut]: Rc::get_mut
#[doc(search_unbox)] #[doc(search_unbox)]
#[cfg_attr(not(test), rustc_diagnostic_item = "Rc")] #[rustc_diagnostic_item = "Rc"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_insignificant_dtor] #[rustc_insignificant_dtor]
pub struct Rc< pub struct Rc<
@ -2981,7 +2978,7 @@ impl<T, I: iter::TrustedLen<Item = T>> ToRcSlice<T> for I {
/// ///
/// [`upgrade`]: Weak::upgrade /// [`upgrade`]: Weak::upgrade
#[stable(feature = "rc_weak", since = "1.4.0")] #[stable(feature = "rc_weak", since = "1.4.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "RcWeak")] #[rustc_diagnostic_item = "RcWeak"]
pub struct Weak< pub struct Weak<
T: ?Sized, T: ?Sized,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,

View file

@ -8,9 +8,6 @@
//! A few functions are provided to create a slice from a value reference //! A few functions are provided to create a slice from a value reference
//! or from a raw pointer. //! or from a raw pointer.
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]
// Many of the usings in this module are only used in the test configuration.
// It's cleaner to just turn off the unused_imports warning than to fix them.
#![cfg_attr(test, allow(unused_imports, dead_code))]
use core::borrow::{Borrow, BorrowMut}; use core::borrow::{Borrow, BorrowMut};
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
@ -63,16 +60,6 @@ pub use core::slice::{range, try_range};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Basic slice extension methods // Basic slice extension methods
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// HACK(japaric) needed for the implementation of `vec!` macro during testing
// N.B., see the `hack` module in this file for more details.
#[cfg(test)]
pub use hack::into_vec;
// HACK(japaric) needed for the implementation of `Vec::clone` during testing
// N.B., see the `hack` module in this file for more details.
#[cfg(test)]
pub use hack::to_vec;
use crate::alloc::Allocator; use crate::alloc::Allocator;
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
use crate::alloc::Global; use crate::alloc::Global;
@ -81,98 +68,6 @@ use crate::borrow::ToOwned;
use crate::boxed::Box; use crate::boxed::Box;
use crate::vec::Vec; use crate::vec::Vec;
// HACK(japaric): With cfg(test) `impl [T]` is not available, these three
// functions are actually methods that are in `impl [T]` but not in
// `core::slice::SliceExt` - we need to supply these functions for the
// `test_permutations` test
#[allow(unreachable_pub)] // cfg(test) pub above
pub(crate) mod hack {
use core::alloc::Allocator;
use crate::boxed::Box;
use crate::vec::Vec;
// We shouldn't add inline attribute to this since this is used in
// `vec!` macro mostly and causes perf regression. See #71204 for
// discussion and perf results.
#[allow(missing_docs)]
pub fn into_vec<T, A: Allocator>(b: Box<[T], A>) -> Vec<T, A> {
unsafe {
let len = b.len();
let (b, alloc) = Box::into_raw_with_allocator(b);
Vec::from_raw_parts_in(b as *mut T, len, len, alloc)
}
}
#[cfg(not(no_global_oom_handling))]
#[allow(missing_docs)]
#[inline]
pub fn to_vec<T: ConvertVec, A: Allocator>(s: &[T], alloc: A) -> Vec<T, A> {
T::to_vec(s, alloc)
}
#[cfg(not(no_global_oom_handling))]
pub trait ConvertVec {
fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A>
where
Self: Sized;
}
#[cfg(not(no_global_oom_handling))]
impl<T: Clone> ConvertVec for T {
#[inline]
default fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
struct DropGuard<'a, T, A: Allocator> {
vec: &'a mut Vec<T, A>,
num_init: usize,
}
impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> {
#[inline]
fn drop(&mut self) {
// SAFETY:
// items were marked initialized in the loop below
unsafe {
self.vec.set_len(self.num_init);
}
}
}
let mut vec = Vec::with_capacity_in(s.len(), alloc);
let mut guard = DropGuard { vec: &mut vec, num_init: 0 };
let slots = guard.vec.spare_capacity_mut();
// .take(slots.len()) is necessary for LLVM to remove bounds checks
// and has better codegen than zip.
for (i, b) in s.iter().enumerate().take(slots.len()) {
guard.num_init = i;
slots[i].write(b.clone());
}
core::mem::forget(guard);
// SAFETY:
// the vec was allocated and initialized above to at least this length.
unsafe {
vec.set_len(s.len());
}
vec
}
}
#[cfg(not(no_global_oom_handling))]
impl<T: Copy> ConvertVec for T {
#[inline]
fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
let mut v = Vec::with_capacity_in(s.len(), alloc);
// SAFETY:
// allocated above with the capacity of `s`, and initialize to `s.len()` in
// ptr::copy_to_non_overlapping below.
unsafe {
s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len());
v.set_len(s.len());
}
v
}
}
}
#[cfg(not(test))]
impl<T> [T] { impl<T> [T] {
/// Sorts the slice, preserving initial order of equal elements. /// Sorts the slice, preserving initial order of equal elements.
/// ///
@ -501,8 +396,64 @@ impl<T> [T] {
where where
T: Clone, T: Clone,
{ {
// N.B., see the `hack` module in this file for more details. return T::to_vec(self, alloc);
hack::to_vec(self, alloc)
trait ConvertVec {
fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A>
where
Self: Sized;
}
impl<T: Clone> ConvertVec for T {
#[inline]
default fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
struct DropGuard<'a, T, A: Allocator> {
vec: &'a mut Vec<T, A>,
num_init: usize,
}
impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> {
#[inline]
fn drop(&mut self) {
// SAFETY:
// items were marked initialized in the loop below
unsafe {
self.vec.set_len(self.num_init);
}
}
}
let mut vec = Vec::with_capacity_in(s.len(), alloc);
let mut guard = DropGuard { vec: &mut vec, num_init: 0 };
let slots = guard.vec.spare_capacity_mut();
// .take(slots.len()) is necessary for LLVM to remove bounds checks
// and has better codegen than zip.
for (i, b) in s.iter().enumerate().take(slots.len()) {
guard.num_init = i;
slots[i].write(b.clone());
}
core::mem::forget(guard);
// SAFETY:
// the vec was allocated and initialized above to at least this length.
unsafe {
vec.set_len(s.len());
}
vec
}
}
impl<T: Copy> ConvertVec for T {
#[inline]
fn to_vec<A: Allocator>(s: &[Self], alloc: A) -> Vec<Self, A> {
let mut v = Vec::with_capacity_in(s.len(), alloc);
// SAFETY:
// allocated above with the capacity of `s`, and initialize to `s.len()` in
// ptr::copy_to_non_overlapping below.
unsafe {
s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), s.len());
v.set_len(s.len());
}
v
}
}
} }
/// Converts `self` into a vector without clones or allocation. /// Converts `self` into a vector without clones or allocation.
@ -522,10 +473,13 @@ impl<T> [T] {
#[rustc_allow_incoherent_impl] #[rustc_allow_incoherent_impl]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline] #[inline]
#[cfg_attr(not(test), rustc_diagnostic_item = "slice_into_vec")] #[rustc_diagnostic_item = "slice_into_vec"]
pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> { pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
// N.B., see the `hack` module in this file for more details. unsafe {
hack::into_vec(self) let len = self.len();
let (b, alloc) = Box::into_raw_with_allocator(self);
Vec::from_raw_parts_in(b as *mut T, len, len, alloc)
}
} }
/// Creates a vector by copying a slice `n` times. /// Creates a vector by copying a slice `n` times.
@ -666,7 +620,6 @@ impl<T> [T] {
} }
} }
#[cfg(not(test))]
impl [u8] { impl [u8] {
/// Returns a vector containing a copy of this slice where each byte /// Returns a vector containing a copy of this slice where each byte
/// is mapped to its ASCII upper case equivalent. /// is mapped to its ASCII upper case equivalent.
@ -883,16 +836,11 @@ impl<T: Copy, A: Allocator> SpecCloneIntoVec<T, A> for [T] {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone> ToOwned for [T] { impl<T: Clone> ToOwned for [T] {
type Owned = Vec<T>; type Owned = Vec<T>;
#[cfg(not(test))]
fn to_owned(&self) -> Vec<T> { fn to_owned(&self) -> Vec<T> {
self.to_vec() self.to_vec()
} }
#[cfg(test)]
fn to_owned(&self) -> Vec<T> {
hack::to_vec(self, Global)
}
fn clone_into(&self, target: &mut Vec<T>) { fn clone_into(&self, target: &mut Vec<T>) {
SpecCloneIntoVec::clone_into(self, target); SpecCloneIntoVec::clone_into(self, target);
} }

View file

@ -219,7 +219,6 @@ impl ToOwned for str {
} }
/// Methods for string slices. /// Methods for string slices.
#[cfg(not(test))]
impl str { impl str {
/// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating. /// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
/// ///
@ -631,7 +630,6 @@ pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
#[unstable(feature = "str_internals", issue = "none")] #[unstable(feature = "str_internals", issue = "none")]
#[doc(hidden)] #[doc(hidden)]
#[inline] #[inline]
#[cfg(not(test))]
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
pub fn convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> (String, &str) { pub fn convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> (String, &str) {
// Process the input in chunks of 16 bytes to enable auto-vectorization. // Process the input in chunks of 16 bytes to enable auto-vectorization.
@ -704,7 +702,6 @@ pub fn convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> (String, &str) {
} }
} }
#[inline] #[inline]
#[cfg(not(test))]
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[allow(dead_code)] #[allow(dead_code)]
/// Faster implementation of string replacement for ASCII to ASCII cases. /// Faster implementation of string replacement for ASCII to ASCII cases.

View file

@ -356,7 +356,7 @@ use crate::vec::{self, Vec};
/// [`as_str()`]: String::as_str /// [`as_str()`]: String::as_str
#[derive(PartialEq, PartialOrd, Eq, Ord)] #[derive(PartialEq, PartialOrd, Eq, Ord)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), lang = "String")] #[lang = "String"]
pub struct String { pub struct String {
vec: Vec<u8>, vec: Vec<u8>,
} }
@ -438,7 +438,7 @@ impl String {
/// ``` /// ```
#[inline] #[inline]
#[rustc_const_stable(feature = "const_string_new", since = "1.39.0")] #[rustc_const_stable(feature = "const_string_new", since = "1.39.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "string_new")] #[rustc_diagnostic_item = "string_new"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[must_use] #[must_use]
pub const fn new() -> String { pub const fn new() -> String {
@ -501,17 +501,6 @@ impl String {
Ok(String { vec: Vec::try_with_capacity(capacity)? }) Ok(String { vec: Vec::try_with_capacity(capacity)? })
} }
// 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
#[inline]
#[cfg(test)]
#[allow(missing_docs)]
pub fn from_str(_: &str) -> String {
panic!("not available with cfg(test)");
}
/// Converts a vector of bytes to a `String`. /// Converts a vector of bytes to a `String`.
/// ///
/// A string ([`String`]) is made of bytes ([`u8`]), and a vector of bytes /// A string ([`String`]) is made of bytes ([`u8`]), and a vector of bytes
@ -570,7 +559,7 @@ impl String {
/// [`into_bytes`]: String::into_bytes /// [`into_bytes`]: String::into_bytes
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "string_from_utf8")] #[rustc_diagnostic_item = "string_from_utf8"]
pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> { pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
match str::from_utf8(&vec) { match str::from_utf8(&vec) {
Ok(..) => Ok(String { vec }), Ok(..) => Ok(String { vec }),
@ -1071,7 +1060,7 @@ impl String {
#[inline] #[inline]
#[must_use] #[must_use]
#[stable(feature = "string_as_str", since = "1.7.0")] #[stable(feature = "string_as_str", since = "1.7.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "string_as_str")] #[rustc_diagnostic_item = "string_as_str"]
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
pub const fn as_str(&self) -> &str { pub const fn as_str(&self) -> &str {
// SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
@ -1094,7 +1083,7 @@ impl String {
#[inline] #[inline]
#[must_use] #[must_use]
#[stable(feature = "string_as_str", since = "1.7.0")] #[stable(feature = "string_as_str", since = "1.7.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "string_as_mut_str")] #[rustc_diagnostic_item = "string_as_mut_str"]
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
pub const fn as_mut_str(&mut self) -> &mut str { pub const fn as_mut_str(&mut self) -> &mut str {
// SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
@ -1117,7 +1106,7 @@ impl String {
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_confusables("append", "push")] #[rustc_confusables("append", "push")]
#[cfg_attr(not(test), rustc_diagnostic_item = "string_push_str")] #[rustc_diagnostic_item = "string_push_str"]
pub fn push_str(&mut self, string: &str) { pub fn push_str(&mut self, string: &str) {
self.vec.extend_from_slice(string.as_bytes()) self.vec.extend_from_slice(string.as_bytes())
} }
@ -1755,7 +1744,7 @@ impl String {
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[inline] #[inline]
#[stable(feature = "insert_str", since = "1.16.0")] #[stable(feature = "insert_str", since = "1.16.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "string_insert_str")] #[rustc_diagnostic_item = "string_insert_str"]
pub fn insert_str(&mut self, idx: usize, string: &str) { pub fn insert_str(&mut self, idx: usize, string: &str) {
assert!(self.is_char_boundary(idx)); assert!(self.is_char_boundary(idx));
@ -2724,7 +2713,7 @@ impl FromStr for String {
/// implementation for free. /// implementation for free.
/// ///
/// [`Display`]: fmt::Display /// [`Display`]: fmt::Display
#[cfg_attr(not(test), rustc_diagnostic_item = "ToString")] #[rustc_diagnostic_item = "ToString"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait ToString { pub trait ToString {
/// Converts the given value to a `String`. /// Converts the given value to a `String`.
@ -2739,7 +2728,7 @@ pub trait ToString {
/// ``` /// ```
#[rustc_conversion_suggestion] #[rustc_conversion_suggestion]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "to_string_method")] #[rustc_diagnostic_item = "to_string_method"]
fn to_string(&self) -> String; fn to_string(&self) -> String;
} }
@ -2979,7 +2968,6 @@ impl From<&String> for String {
} }
// note: test pulls in std, which causes errors here // note: test pulls in std, which causes errors here
#[cfg(not(test))]
#[stable(feature = "string_from_box", since = "1.18.0")] #[stable(feature = "string_from_box", since = "1.18.0")]
impl From<Box<str>> for String { impl From<Box<str>> for String {
/// Converts the given boxed `str` slice to a [`String`]. /// Converts the given boxed `str` slice to a [`String`].

View file

@ -234,7 +234,7 @@ macro_rules! acquire {
/// ///
/// [rc_examples]: crate::rc#examples /// [rc_examples]: crate::rc#examples
#[doc(search_unbox)] #[doc(search_unbox)]
#[cfg_attr(not(test), rustc_diagnostic_item = "Arc")] #[rustc_diagnostic_item = "Arc"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_insignificant_dtor] #[rustc_insignificant_dtor]
pub struct Arc< pub struct Arc<
@ -311,7 +311,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
/// ///
/// [`upgrade`]: Weak::upgrade /// [`upgrade`]: Weak::upgrade
#[stable(feature = "arc_weak", since = "1.4.0")] #[stable(feature = "arc_weak", since = "1.4.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "ArcWeak")] #[rustc_diagnostic_item = "ArcWeak"]
pub struct Weak< pub struct Weak<
T: ?Sized, T: ?Sized,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,

View file

@ -472,14 +472,9 @@ where
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "vec_into_iter_clone", since = "1.8.0")] #[stable(feature = "vec_into_iter_clone", since = "1.8.0")]
impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> { impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {
#[cfg(not(test))]
fn clone(&self) -> Self { fn clone(&self) -> Self {
self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter() self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter()
} }
#[cfg(test)]
fn clone(&self) -> Self {
crate::slice::to_vec(self.as_slice(), self.alloc.deref().clone()).into_iter()
}
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]

View file

@ -404,7 +404,7 @@ mod spec_extend;
/// [owned slice]: Box /// [owned slice]: Box
/// [`into_boxed_slice`]: Vec::into_boxed_slice /// [`into_boxed_slice`]: Vec::into_boxed_slice
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "Vec")] #[rustc_diagnostic_item = "Vec"]
#[rustc_insignificant_dtor] #[rustc_insignificant_dtor]
pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> { pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
buf: RawVec<T, A>, buf: RawVec<T, A>,
@ -428,7 +428,7 @@ impl<T> Vec<T> {
/// ``` /// ```
#[inline] #[inline]
#[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")] #[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_new")] #[rustc_diagnostic_item = "vec_new"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[must_use] #[must_use]
pub const fn new() -> Self { pub const fn new() -> Self {
@ -489,7 +489,7 @@ impl<T> Vec<T> {
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[must_use] #[must_use]
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_with_capacity")] #[rustc_diagnostic_item = "vec_with_capacity"]
#[track_caller] #[track_caller]
pub fn with_capacity(capacity: usize) -> Self { pub fn with_capacity(capacity: usize) -> Self {
Self::with_capacity_in(capacity, Global) Self::with_capacity_in(capacity, Global)
@ -1279,7 +1279,7 @@ impl<T, A: Allocator> Vec<T, A> {
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[track_caller] #[track_caller]
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_reserve")] #[rustc_diagnostic_item = "vec_reserve"]
pub fn reserve(&mut self, additional: usize) { pub fn reserve(&mut self, additional: usize) {
self.buf.reserve(self.len, additional); self.buf.reserve(self.len, additional);
} }
@ -1568,7 +1568,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// ``` /// ```
#[inline] #[inline]
#[stable(feature = "vec_as_slice", since = "1.7.0")] #[stable(feature = "vec_as_slice", since = "1.7.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_slice")] #[rustc_diagnostic_item = "vec_as_slice"]
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
pub const fn as_slice(&self) -> &[T] { pub const fn as_slice(&self) -> &[T] {
// SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size // SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size
@ -1600,7 +1600,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// ``` /// ```
#[inline] #[inline]
#[stable(feature = "vec_as_slice", since = "1.7.0")] #[stable(feature = "vec_as_slice", since = "1.7.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_mut_slice")] #[rustc_diagnostic_item = "vec_as_mut_slice"]
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
pub const fn as_mut_slice(&mut self) -> &mut [T] { pub const fn as_mut_slice(&mut self) -> &mut [T] {
// SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of
@ -2511,7 +2511,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// Takes *O*(1) time. /// Takes *O*(1) time.
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_pop")] #[rustc_diagnostic_item = "vec_pop"]
pub fn pop(&mut self) -> Option<T> { pub fn pop(&mut self) -> Option<T> {
if self.len == 0 { if self.len == 0 {
None None
@ -2712,7 +2712,7 @@ impl<T, A: Allocator> Vec<T, A> {
/// assert!(!v.is_empty()); /// assert!(!v.is_empty());
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_is_empty")] #[rustc_diagnostic_item = "vec_is_empty"]
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
pub const fn is_empty(&self) -> bool { pub const fn is_empty(&self) -> bool {
self.len() == 0 self.len() == 0
@ -3193,7 +3193,7 @@ impl<T: PartialEq, A: Allocator> Vec<T, A> {
#[doc(hidden)] #[doc(hidden)]
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "vec_from_elem")] #[rustc_diagnostic_item = "vec_from_elem"]
#[track_caller] #[track_caller]
pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> { pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
<T as SpecFromElem>::from_elem(elem, n, Global) <T as SpecFromElem>::from_elem(elem, n, Global)
@ -3293,23 +3293,12 @@ unsafe impl<T, A: Allocator> ops::DerefPure for Vec<T, A> {}
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> { impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
#[cfg(not(test))]
#[track_caller] #[track_caller]
fn clone(&self) -> Self { fn clone(&self) -> Self {
let alloc = self.allocator().clone(); let alloc = self.allocator().clone();
<[T]>::to_vec_in(&**self, alloc) <[T]>::to_vec_in(&**self, alloc)
} }
// HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
// required for this method definition, is not available. Instead use the
// `slice::to_vec` function which is only available with cfg(test)
// NB see the slice::hack module in slice.rs for more information
#[cfg(test)]
fn clone(&self) -> Self {
let alloc = self.allocator().clone();
crate::slice::to_vec(&**self, alloc)
}
/// Overwrites the contents of `self` with a clone of the contents of `source`. /// Overwrites the contents of `self` with a clone of the contents of `source`.
/// ///
/// This method is preferred over simply assigning `source.clone()` to `self`, /// This method is preferred over simply assigning `source.clone()` to `self`,
@ -3854,15 +3843,10 @@ impl<T: Clone> From<&[T]> for Vec<T> {
/// ``` /// ```
/// assert_eq!(Vec::from(&[1, 2, 3][..]), vec![1, 2, 3]); /// assert_eq!(Vec::from(&[1, 2, 3][..]), vec![1, 2, 3]);
/// ``` /// ```
#[cfg(not(test))]
#[track_caller] #[track_caller]
fn from(s: &[T]) -> Vec<T> { fn from(s: &[T]) -> Vec<T> {
s.to_vec() s.to_vec()
} }
#[cfg(test)]
fn from(s: &[T]) -> Vec<T> {
crate::slice::to_vec(s, Global)
}
} }
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
@ -3875,15 +3859,10 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
/// ``` /// ```
/// assert_eq!(Vec::from(&mut [1, 2, 3][..]), vec![1, 2, 3]); /// assert_eq!(Vec::from(&mut [1, 2, 3][..]), vec![1, 2, 3]);
/// ``` /// ```
#[cfg(not(test))]
#[track_caller] #[track_caller]
fn from(s: &mut [T]) -> Vec<T> { fn from(s: &mut [T]) -> Vec<T> {
s.to_vec() s.to_vec()
} }
#[cfg(test)]
fn from(s: &mut [T]) -> Vec<T> {
crate::slice::to_vec(s, Global)
}
} }
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
@ -3928,16 +3907,10 @@ impl<T, const N: usize> From<[T; N]> for Vec<T> {
/// ``` /// ```
/// assert_eq!(Vec::from([1, 2, 3]), vec![1, 2, 3]); /// assert_eq!(Vec::from([1, 2, 3]), vec![1, 2, 3]);
/// ``` /// ```
#[cfg(not(test))]
#[track_caller] #[track_caller]
fn from(s: [T; N]) -> Vec<T> { fn from(s: [T; N]) -> Vec<T> {
<[T]>::into_vec(Box::new(s)) <[T]>::into_vec(Box::new(s))
} }
#[cfg(test)]
fn from(s: [T; N]) -> Vec<T> {
crate::slice::into_vec(Box::new(s))
}
} }
#[stable(feature = "vec_from_cow_slice", since = "1.14.0")] #[stable(feature = "vec_from_cow_slice", since = "1.14.0")]
@ -3966,7 +3939,6 @@ where
} }
// note: test pulls in std, which causes errors here // note: test pulls in std, which causes errors here
#[cfg(not(test))]
#[stable(feature = "vec_from_box", since = "1.18.0")] #[stable(feature = "vec_from_box", since = "1.18.0")]
impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> { impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> {
/// Converts a boxed slice into a vector by transferring ownership of /// Converts a boxed slice into a vector by transferring ownership of
@ -3985,7 +3957,6 @@ impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> {
// note: test pulls in std, which causes errors here // note: test pulls in std, which causes errors here
#[cfg(not(no_global_oom_handling))] #[cfg(not(no_global_oom_handling))]
#[cfg(not(test))]
#[stable(feature = "box_from_vec", since = "1.20.0")] #[stable(feature = "box_from_vec", since = "1.20.0")]
impl<T, A: Allocator> From<Vec<T, A>> for Box<[T], A> { impl<T, A: Allocator> From<Vec<T, A>> for Box<[T], A> {
/// Converts a vector into a boxed slice. /// Converts a vector into a boxed slice.

View file

@ -10,8 +10,9 @@ edition = "2021"
[lib] [lib]
path = "lib.rs" path = "lib.rs"
test = false test = true
bench = false bench = true
doc = false
[dev-dependencies] [dev-dependencies]
rand = { version = "0.9.0", default-features = false, features = ["alloc"] } rand = { version = "0.9.0", default-features = false, features = ["alloc"] }

View file

@ -1 +1,90 @@
// Intentionally left empty. #![cfg(test)]
#![allow(unused_attributes)]
#![unstable(feature = "alloctests", issue = "none")]
#![no_std]
// Lints:
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(deprecated_in_future)]
#![warn(missing_debug_implementations)]
#![allow(explicit_outlives_requirements)]
#![allow(internal_features)]
#![allow(rustdoc::redundant_explicit_links)]
#![warn(rustdoc::unescaped_backticks)]
#![deny(ffi_unwind_calls)]
//
// Library features:
// tidy-alphabetical-start
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
#![feature(array_into_iter_constructors)]
#![feature(assert_matches)]
#![feature(core_intrinsics)]
#![feature(exact_size_is_empty)]
#![feature(extend_one)]
#![feature(extend_one_unchecked)]
#![feature(hasher_prefixfree_extras)]
#![feature(inplace_iteration)]
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(ptr_internals)]
#![feature(sized_type_properties)]
#![feature(slice_iter_mut_as_mut_slice)]
#![feature(slice_ptr_get)]
#![feature(slice_range)]
#![feature(std_internals)]
#![feature(temporary_niche_types)]
#![feature(trusted_fused)]
#![feature(trusted_len)]
#![feature(trusted_random_access)]
#![feature(try_reserve_kind)]
#![feature(try_trait_v2)]
// tidy-alphabetical-end
//
// Language features:
// tidy-alphabetical-start
#![feature(cfg_sanitize)]
#![feature(dropck_eyepatch)]
#![feature(lang_items)]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(optimize_attribute)]
#![feature(rustc_allow_const_fn_unstable)]
#![feature(rustc_attrs)]
#![feature(staged_api)]
#![feature(test)]
#![rustc_preserve_ub_checks]
// tidy-alphabetical-end
// Allow testing this library
extern crate alloc as realalloc;
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;
mod testing;
use realalloc::*;
#[path = "../alloc/src/collections/mod.rs"]
mod collections;
#[path = "../alloc/src/raw_vec/mod.rs"]
mod raw_vec;
#[allow(dead_code)] // Not used in all configurations
pub(crate) mod test_helpers {
/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
/// seed not being the same for every RNG invocation too.
pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
use std::hash::{BuildHasher, Hash, Hasher};
let mut hasher = std::hash::RandomState::new().build_hasher();
std::panic::Location::caller().hash(&mut hasher);
let hc64 = hasher.finish();
let seed_vec =
hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<crate::vec::Vec<u8>>();
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
rand::SeedableRng::from_seed(seed)
}
}