mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Update rand in the stdlib tests, and remove the getrandom feature from it
This commit is contained in:
parent
659e169d37
commit
a4bf36e87b
125
Cargo.lock
125
Cargo.lock
@ -30,7 +30,7 @@ version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
|
||||
dependencies = [
|
||||
"getrandom 0.2.8",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
@ -50,7 +50,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"core",
|
||||
"rand 0.7.3",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
@ -947,7 +947,7 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
name = "core"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rand 0.7.3",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
]
|
||||
|
||||
@ -1051,7 +1051,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
@ -1310,7 +1310,7 @@ version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a3d382e8464107391c8706b4c14b087808ecb909f6c15c34114bc42e53a9e4c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.8",
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1347,7 +1347,7 @@ dependencies = [
|
||||
"hkdf",
|
||||
"pem-rfc7468",
|
||||
"pkcs8",
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
"sec1",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
@ -1478,7 +1478,7 @@ version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
|
||||
dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
@ -1745,17 +1745,6 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.8"
|
||||
@ -1765,7 +1754,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasi",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
@ -1836,7 +1825,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7"
|
||||
dependencies = [
|
||||
"ff",
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
@ -2111,7 +2100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe"
|
||||
dependencies = [
|
||||
"bitmaps",
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
"rand_xoshiro",
|
||||
"sized-chunks",
|
||||
"typenum",
|
||||
@ -2656,14 +2645,14 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"env_logger 0.9.0",
|
||||
"getrandom 0.2.8",
|
||||
"getrandom",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"libffi",
|
||||
"libloading",
|
||||
"log",
|
||||
"measureme",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"regex",
|
||||
"rustc-workspace-hack",
|
||||
"rustc_version",
|
||||
@ -2966,10 +2955,10 @@ checksum = "ed20c4c21d893414f42e0cbfebe8a8036b5ae9b0264611fb6504e395eda6ceec"
|
||||
dependencies = [
|
||||
"ct-codecs",
|
||||
"ed25519-compact",
|
||||
"getrandom 0.2.8",
|
||||
"getrandom",
|
||||
"orion",
|
||||
"p384",
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -3089,7 +3078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3294,19 +3283,6 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@ -3314,18 +3290,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.0",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.5.1",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3335,16 +3301,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3353,25 +3310,16 @@ version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8"
|
||||
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3380,7 +3328,7 @@ version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
|
||||
dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3422,7 +3370,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||
dependencies = [
|
||||
"getrandom 0.2.8",
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
@ -3636,10 +3584,10 @@ version = "1.0.0"
|
||||
dependencies = [
|
||||
"bstr 0.2.17",
|
||||
"clap 3.2.20",
|
||||
"getrandom 0.2.8",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"regex",
|
||||
"serde_json",
|
||||
"syn",
|
||||
@ -3652,7 +3600,7 @@ name = "rustc_abi"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rand_xoshiro",
|
||||
"rustc_data_structures",
|
||||
"rustc_index",
|
||||
@ -4156,7 +4104,7 @@ dependencies = [
|
||||
name = "rustc_incremental"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
@ -5179,7 +5127,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5339,11 +5287,12 @@ dependencies = [
|
||||
"panic_abort",
|
||||
"panic_unwind",
|
||||
"profiler_builtins",
|
||||
"rand 0.7.3",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"rustc-demangle",
|
||||
"std_detect",
|
||||
"unwind",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5815,7 +5764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
@ -6098,7 +6047,7 @@ version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
dependencies = [
|
||||
"getrandom 0.2.8",
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6139,12 +6088,6 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
@ -13,8 +13,8 @@ core = { path = "../core" }
|
||||
compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7"
|
||||
rand_xorshift = "0.2"
|
||||
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
|
||||
rand_xorshift = "0.3.0"
|
||||
|
||||
[[test]]
|
||||
name = "collectionstests"
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::{mem, ptr};
|
||||
|
||||
use rand::distributions::{Alphanumeric, Standard};
|
||||
use rand::distributions::{Alphanumeric, DistString, Standard};
|
||||
use rand::Rng;
|
||||
use test::{black_box, Bencher};
|
||||
|
||||
@ -218,7 +218,7 @@ fn gen_strings(len: usize) -> Vec<String> {
|
||||
let mut v = vec![];
|
||||
for _ in 0..len {
|
||||
let n = rng.gen::<usize>() % 20 + 1;
|
||||
v.push((&mut rng).sample_iter(&Alphanumeric).take(n).collect());
|
||||
v.push(Alphanumeric.sample_string(&mut rng, n));
|
||||
}
|
||||
v
|
||||
}
|
||||
|
@ -465,7 +465,7 @@ fn test_retain() {
|
||||
#[test]
|
||||
#[cfg(not(target_os = "emscripten"))]
|
||||
fn panic_safe() {
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use rand::seq::SliceRandom;
|
||||
use std::cmp;
|
||||
use std::panic::{self, AssertUnwindSafe};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
@ -490,7 +490,7 @@ fn panic_safe() {
|
||||
self.0.partial_cmp(&other.0)
|
||||
}
|
||||
}
|
||||
let mut rng = thread_rng();
|
||||
let mut rng = crate::test_helpers::test_rng();
|
||||
const DATASZ: usize = 32;
|
||||
// Miri is too slow
|
||||
let ntest = if cfg!(miri) { 1 } else { 10 };
|
||||
|
@ -5,7 +5,7 @@ use crate::vec::Vec;
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
use std::thread;
|
||||
|
||||
use rand::{thread_rng, RngCore};
|
||||
use rand::RngCore;
|
||||
|
||||
#[test]
|
||||
fn test_basic() {
|
||||
@ -481,12 +481,12 @@ fn test_split_off_2() {
|
||||
}
|
||||
}
|
||||
|
||||
fn fuzz_test(sz: i32) {
|
||||
fn fuzz_test(sz: i32, rng: &mut impl RngCore) {
|
||||
let mut m: LinkedList<_> = LinkedList::new();
|
||||
let mut v = vec![];
|
||||
for i in 0..sz {
|
||||
check_links(&m);
|
||||
let r: u8 = thread_rng().next_u32() as u8;
|
||||
let r: u8 = rng.next_u32() as u8;
|
||||
match r % 6 {
|
||||
0 => {
|
||||
m.pop_back();
|
||||
@ -521,11 +521,12 @@ fn fuzz_test(sz: i32) {
|
||||
|
||||
#[test]
|
||||
fn test_fuzz() {
|
||||
let mut rng = crate::test_helpers::test_rng();
|
||||
for _ in 0..25 {
|
||||
fuzz_test(3);
|
||||
fuzz_test(16);
|
||||
fuzz_test(3, &mut rng);
|
||||
fuzz_test(16, &mut rng);
|
||||
#[cfg(not(miri))] // Miri is too slow
|
||||
fuzz_test(189);
|
||||
fuzz_test(189, &mut rng);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,6 +192,7 @@
|
||||
#![feature(unsized_fn_params)]
|
||||
#![feature(c_unwind)]
|
||||
#![feature(with_negative_coherence)]
|
||||
#![cfg_attr(test, feature(panic_update_hook))]
|
||||
//
|
||||
// Rustdoc features:
|
||||
#![feature(doc_cfg)]
|
||||
@ -255,3 +256,20 @@ pub mod vec;
|
||||
pub mod __export {
|
||||
pub use core::format_args;
|
||||
}
|
||||
|
||||
#[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::collections::hash_map::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)
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ use crate::borrow::ToOwned;
|
||||
use crate::boxed::Box;
|
||||
use crate::vec::Vec;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[unstable(feature = "slice_range", issue = "76393")]
|
||||
pub use core::slice::range;
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
|
359
library/alloc/src/slice/tests.rs
Normal file
359
library/alloc/src/slice/tests.rs
Normal file
@ -0,0 +1,359 @@
|
||||
use crate::borrow::ToOwned;
|
||||
use crate::rc::Rc;
|
||||
use crate::string::ToString;
|
||||
use crate::test_helpers::test_rng;
|
||||
use crate::vec::Vec;
|
||||
|
||||
use core::cell::Cell;
|
||||
use core::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
use core::convert::identity;
|
||||
use core::fmt;
|
||||
use core::mem;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering::Relaxed};
|
||||
use rand::{distributions::Standard, prelude::*, Rng, RngCore};
|
||||
use std::panic;
|
||||
|
||||
macro_rules! do_test {
|
||||
($input:ident, $func:ident) => {
|
||||
let len = $input.len();
|
||||
|
||||
// Work out the total number of comparisons required to sort
|
||||
// this array...
|
||||
let mut count = 0usize;
|
||||
$input.to_owned().$func(|a, b| {
|
||||
count += 1;
|
||||
a.cmp(b)
|
||||
});
|
||||
|
||||
// ... and then panic on each and every single one.
|
||||
for panic_countdown in 0..count {
|
||||
// Refresh the counters.
|
||||
VERSIONS.store(0, Relaxed);
|
||||
for i in 0..len {
|
||||
DROP_COUNTS[i].store(0, Relaxed);
|
||||
}
|
||||
|
||||
let v = $input.to_owned();
|
||||
let _ = std::panic::catch_unwind(move || {
|
||||
let mut v = v;
|
||||
let mut panic_countdown = panic_countdown;
|
||||
v.$func(|a, b| {
|
||||
if panic_countdown == 0 {
|
||||
SILENCE_PANIC.with(|s| s.set(true));
|
||||
panic!();
|
||||
}
|
||||
panic_countdown -= 1;
|
||||
a.cmp(b)
|
||||
})
|
||||
});
|
||||
|
||||
// Check that the number of things dropped is exactly
|
||||
// what we expect (i.e., the contents of `v`).
|
||||
for (i, c) in DROP_COUNTS.iter().enumerate().take(len) {
|
||||
let count = c.load(Relaxed);
|
||||
assert!(count == 1, "found drop count == {} for i == {}, len == {}", count, i, len);
|
||||
}
|
||||
|
||||
// Check that the most recent versions of values were dropped.
|
||||
assert_eq!(VERSIONS.load(Relaxed), 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const MAX_LEN: usize = 80;
|
||||
|
||||
static DROP_COUNTS: [AtomicUsize; MAX_LEN] = [
|
||||
// FIXME(RFC 1109): AtomicUsize is not Copy.
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
];
|
||||
|
||||
static VERSIONS: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
#[derive(Clone, Eq)]
|
||||
struct DropCounter {
|
||||
x: u32,
|
||||
id: usize,
|
||||
version: Cell<usize>,
|
||||
}
|
||||
|
||||
impl PartialEq for DropCounter {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.partial_cmp(other) == Some(Ordering::Equal)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for DropCounter {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.version.set(self.version.get() + 1);
|
||||
other.version.set(other.version.get() + 1);
|
||||
VERSIONS.fetch_add(2, Relaxed);
|
||||
self.x.partial_cmp(&other.x)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for DropCounter {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DropCounter {
|
||||
fn drop(&mut self) {
|
||||
DROP_COUNTS[self.id].fetch_add(1, Relaxed);
|
||||
VERSIONS.fetch_sub(self.version.get(), Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
std::thread_local!(static SILENCE_PANIC: Cell<bool> = Cell::new(false));
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "emscripten", ignore)] // no threads
|
||||
fn panic_safe() {
|
||||
panic::update_hook(move |prev, info| {
|
||||
if !SILENCE_PANIC.with(|s| s.get()) {
|
||||
prev(info);
|
||||
}
|
||||
});
|
||||
|
||||
let mut rng = test_rng();
|
||||
|
||||
// Miri is too slow (but still need to `chain` to make the types match)
|
||||
let lens = if cfg!(miri) { (1..10).chain(0..0) } else { (1..20).chain(70..MAX_LEN) };
|
||||
let moduli: &[u32] = if cfg!(miri) { &[5] } else { &[5, 20, 50] };
|
||||
|
||||
for len in lens {
|
||||
for &modulus in moduli {
|
||||
for &has_runs in &[false, true] {
|
||||
let mut input = (0..len)
|
||||
.map(|id| DropCounter {
|
||||
x: rng.next_u32() % modulus,
|
||||
id: id,
|
||||
version: Cell::new(0),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if has_runs {
|
||||
for c in &mut input {
|
||||
c.x = c.id as u32;
|
||||
}
|
||||
|
||||
for _ in 0..5 {
|
||||
let a = rng.gen::<usize>() % len;
|
||||
let b = rng.gen::<usize>() % len;
|
||||
if a < b {
|
||||
input[a..b].reverse();
|
||||
} else {
|
||||
input.swap(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_test!(input, sort_by);
|
||||
do_test!(input, sort_unstable_by);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set default panic hook again.
|
||||
drop(panic::take_hook());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(miri, ignore)] // Miri is too slow
|
||||
fn test_sort() {
|
||||
let mut rng = test_rng();
|
||||
|
||||
for len in (2..25).chain(500..510) {
|
||||
for &modulus in &[5, 10, 100, 1000] {
|
||||
for _ in 0..10 {
|
||||
let orig: Vec<_> = (&mut rng)
|
||||
.sample_iter::<i32, _>(&Standard)
|
||||
.map(|x| x % modulus)
|
||||
.take(len)
|
||||
.collect();
|
||||
|
||||
// Sort in default order.
|
||||
let mut v = orig.clone();
|
||||
v.sort();
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
|
||||
// Sort in ascending order.
|
||||
let mut v = orig.clone();
|
||||
v.sort_by(|a, b| a.cmp(b));
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
|
||||
// Sort in descending order.
|
||||
let mut v = orig.clone();
|
||||
v.sort_by(|a, b| b.cmp(a));
|
||||
assert!(v.windows(2).all(|w| w[0] >= w[1]));
|
||||
|
||||
// Sort in lexicographic order.
|
||||
let mut v1 = orig.clone();
|
||||
let mut v2 = orig.clone();
|
||||
v1.sort_by_key(|x| x.to_string());
|
||||
v2.sort_by_cached_key(|x| x.to_string());
|
||||
assert!(v1.windows(2).all(|w| w[0].to_string() <= w[1].to_string()));
|
||||
assert!(v1 == v2);
|
||||
|
||||
// Sort with many pre-sorted runs.
|
||||
let mut v = orig.clone();
|
||||
v.sort();
|
||||
v.reverse();
|
||||
for _ in 0..5 {
|
||||
let a = rng.gen::<usize>() % len;
|
||||
let b = rng.gen::<usize>() % len;
|
||||
if a < b {
|
||||
v[a..b].reverse();
|
||||
} else {
|
||||
v.swap(a, b);
|
||||
}
|
||||
}
|
||||
v.sort();
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort using a completely random comparison function.
|
||||
// This will reorder the elements *somehow*, but won't panic.
|
||||
let mut v = [0; 500];
|
||||
for i in 0..v.len() {
|
||||
v[i] = i as i32;
|
||||
}
|
||||
v.sort_by(|_, _| *[Less, Equal, Greater].choose(&mut rng).unwrap());
|
||||
v.sort();
|
||||
for i in 0..v.len() {
|
||||
assert_eq!(v[i], i as i32);
|
||||
}
|
||||
|
||||
// Should not panic.
|
||||
[0i32; 0].sort();
|
||||
[(); 10].sort();
|
||||
[(); 100].sort();
|
||||
|
||||
let mut v = [0xDEADBEEFu64];
|
||||
v.sort();
|
||||
assert!(v == [0xDEADBEEF]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_stability() {
|
||||
// Miri is too slow
|
||||
let large_range = if cfg!(miri) { 0..0 } else { 500..510 };
|
||||
let rounds = if cfg!(miri) { 1 } else { 10 };
|
||||
|
||||
let mut rng = test_rng();
|
||||
for len in (2..25).chain(large_range) {
|
||||
for _ in 0..rounds {
|
||||
let mut counts = [0; 10];
|
||||
|
||||
// create a vector like [(6, 1), (5, 1), (6, 2), ...],
|
||||
// where the first item of each tuple is random, but
|
||||
// the second item represents which occurrence of that
|
||||
// number this element is, i.e., the second elements
|
||||
// will occur in sorted order.
|
||||
let orig: Vec<_> = (0..len)
|
||||
.map(|_| {
|
||||
let n = rng.gen::<usize>() % 10;
|
||||
counts[n] += 1;
|
||||
(n, counts[n])
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut v = orig.clone();
|
||||
// Only sort on the first element, so an unstable sort
|
||||
// may mix up the counts.
|
||||
v.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
|
||||
|
||||
// This comparison includes the count (the second item
|
||||
// of the tuple), so elements with equal first items
|
||||
// will need to be ordered with increasing
|
||||
// counts... i.e., exactly asserting that this sort is
|
||||
// stable.
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
|
||||
let mut v = orig.clone();
|
||||
v.sort_by_cached_key(|&(x, _)| x);
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +1,9 @@
|
||||
use std::cell::Cell;
|
||||
use std::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
use std::cmp::Ordering::{Equal, Greater, Less};
|
||||
use std::convert::identity;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::panic;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
|
||||
|
||||
use rand::distributions::Standard;
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::{thread_rng, Rng, RngCore};
|
||||
|
||||
fn square(n: usize) -> usize {
|
||||
n * n
|
||||
@ -388,123 +382,6 @@ fn test_reverse() {
|
||||
assert_eq!(v, (-50..51i16).rev().collect::<Vec<_>>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(miri, ignore)] // Miri is too slow
|
||||
fn test_sort() {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
for len in (2..25).chain(500..510) {
|
||||
for &modulus in &[5, 10, 100, 1000] {
|
||||
for _ in 0..10 {
|
||||
let orig: Vec<_> =
|
||||
rng.sample_iter::<i32, _>(&Standard).map(|x| x % modulus).take(len).collect();
|
||||
|
||||
// Sort in default order.
|
||||
let mut v = orig.clone();
|
||||
v.sort();
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
|
||||
// Sort in ascending order.
|
||||
let mut v = orig.clone();
|
||||
v.sort_by(|a, b| a.cmp(b));
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
|
||||
// Sort in descending order.
|
||||
let mut v = orig.clone();
|
||||
v.sort_by(|a, b| b.cmp(a));
|
||||
assert!(v.windows(2).all(|w| w[0] >= w[1]));
|
||||
|
||||
// Sort in lexicographic order.
|
||||
let mut v1 = orig.clone();
|
||||
let mut v2 = orig.clone();
|
||||
v1.sort_by_key(|x| x.to_string());
|
||||
v2.sort_by_cached_key(|x| x.to_string());
|
||||
assert!(v1.windows(2).all(|w| w[0].to_string() <= w[1].to_string()));
|
||||
assert!(v1 == v2);
|
||||
|
||||
// Sort with many pre-sorted runs.
|
||||
let mut v = orig.clone();
|
||||
v.sort();
|
||||
v.reverse();
|
||||
for _ in 0..5 {
|
||||
let a = rng.gen::<usize>() % len;
|
||||
let b = rng.gen::<usize>() % len;
|
||||
if a < b {
|
||||
v[a..b].reverse();
|
||||
} else {
|
||||
v.swap(a, b);
|
||||
}
|
||||
}
|
||||
v.sort();
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort using a completely random comparison function.
|
||||
// This will reorder the elements *somehow*, but won't panic.
|
||||
let mut v = [0; 500];
|
||||
for i in 0..v.len() {
|
||||
v[i] = i as i32;
|
||||
}
|
||||
v.sort_by(|_, _| *[Less, Equal, Greater].choose(&mut rng).unwrap());
|
||||
v.sort();
|
||||
for i in 0..v.len() {
|
||||
assert_eq!(v[i], i as i32);
|
||||
}
|
||||
|
||||
// Should not panic.
|
||||
[0i32; 0].sort();
|
||||
[(); 10].sort();
|
||||
[(); 100].sort();
|
||||
|
||||
let mut v = [0xDEADBEEFu64];
|
||||
v.sort();
|
||||
assert!(v == [0xDEADBEEF]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_stability() {
|
||||
// Miri is too slow
|
||||
let large_range = if cfg!(miri) { 0..0 } else { 500..510 };
|
||||
let rounds = if cfg!(miri) { 1 } else { 10 };
|
||||
|
||||
for len in (2..25).chain(large_range) {
|
||||
for _ in 0..rounds {
|
||||
let mut counts = [0; 10];
|
||||
|
||||
// create a vector like [(6, 1), (5, 1), (6, 2), ...],
|
||||
// where the first item of each tuple is random, but
|
||||
// the second item represents which occurrence of that
|
||||
// number this element is, i.e., the second elements
|
||||
// will occur in sorted order.
|
||||
let orig: Vec<_> = (0..len)
|
||||
.map(|_| {
|
||||
let n = thread_rng().gen::<usize>() % 10;
|
||||
counts[n] += 1;
|
||||
(n, counts[n])
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut v = orig.clone();
|
||||
// Only sort on the first element, so an unstable sort
|
||||
// may mix up the counts.
|
||||
v.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
|
||||
|
||||
// This comparison includes the count (the second item
|
||||
// of the tuple), so elements with equal first items
|
||||
// will need to be ordered with increasing
|
||||
// counts... i.e., exactly asserting that this sort is
|
||||
// stable.
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
|
||||
let mut v = orig.clone();
|
||||
v.sort_by_cached_key(|&(x, _)| x);
|
||||
assert!(v.windows(2).all(|w| w[0] <= w[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rotate_left() {
|
||||
let expected: Vec<_> = (0..13).collect();
|
||||
@ -1608,230 +1485,6 @@ fn test_copy_from_slice_dst_shorter() {
|
||||
dst.copy_from_slice(&src);
|
||||
}
|
||||
|
||||
const MAX_LEN: usize = 80;
|
||||
|
||||
static DROP_COUNTS: [AtomicUsize; MAX_LEN] = [
|
||||
// FIXME(RFC 1109): AtomicUsize is not Copy.
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
AtomicUsize::new(0),
|
||||
];
|
||||
|
||||
static VERSIONS: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
#[derive(Clone, Eq)]
|
||||
struct DropCounter {
|
||||
x: u32,
|
||||
id: usize,
|
||||
version: Cell<usize>,
|
||||
}
|
||||
|
||||
impl PartialEq for DropCounter {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.partial_cmp(other) == Some(Ordering::Equal)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for DropCounter {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.version.set(self.version.get() + 1);
|
||||
other.version.set(other.version.get() + 1);
|
||||
VERSIONS.fetch_add(2, Relaxed);
|
||||
self.x.partial_cmp(&other.x)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for DropCounter {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DropCounter {
|
||||
fn drop(&mut self) {
|
||||
DROP_COUNTS[self.id].fetch_add(1, Relaxed);
|
||||
VERSIONS.fetch_sub(self.version.get(), Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! test {
|
||||
($input:ident, $func:ident) => {
|
||||
let len = $input.len();
|
||||
|
||||
// Work out the total number of comparisons required to sort
|
||||
// this array...
|
||||
let mut count = 0usize;
|
||||
$input.to_owned().$func(|a, b| {
|
||||
count += 1;
|
||||
a.cmp(b)
|
||||
});
|
||||
|
||||
// ... and then panic on each and every single one.
|
||||
for panic_countdown in 0..count {
|
||||
// Refresh the counters.
|
||||
VERSIONS.store(0, Relaxed);
|
||||
for i in 0..len {
|
||||
DROP_COUNTS[i].store(0, Relaxed);
|
||||
}
|
||||
|
||||
let v = $input.to_owned();
|
||||
let _ = std::panic::catch_unwind(move || {
|
||||
let mut v = v;
|
||||
let mut panic_countdown = panic_countdown;
|
||||
v.$func(|a, b| {
|
||||
if panic_countdown == 0 {
|
||||
SILENCE_PANIC.with(|s| s.set(true));
|
||||
panic!();
|
||||
}
|
||||
panic_countdown -= 1;
|
||||
a.cmp(b)
|
||||
})
|
||||
});
|
||||
|
||||
// Check that the number of things dropped is exactly
|
||||
// what we expect (i.e., the contents of `v`).
|
||||
for (i, c) in DROP_COUNTS.iter().enumerate().take(len) {
|
||||
let count = c.load(Relaxed);
|
||||
assert!(count == 1, "found drop count == {} for i == {}, len == {}", count, i, len);
|
||||
}
|
||||
|
||||
// Check that the most recent versions of values were dropped.
|
||||
assert_eq!(VERSIONS.load(Relaxed), 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
thread_local!(static SILENCE_PANIC: Cell<bool> = Cell::new(false));
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "emscripten", ignore)] // no threads
|
||||
fn panic_safe() {
|
||||
panic::update_hook(move |prev, info| {
|
||||
if !SILENCE_PANIC.with(|s| s.get()) {
|
||||
prev(info);
|
||||
}
|
||||
});
|
||||
|
||||
let mut rng = thread_rng();
|
||||
|
||||
// Miri is too slow (but still need to `chain` to make the types match)
|
||||
let lens = if cfg!(miri) { (1..10).chain(0..0) } else { (1..20).chain(70..MAX_LEN) };
|
||||
let moduli: &[u32] = if cfg!(miri) { &[5] } else { &[5, 20, 50] };
|
||||
|
||||
for len in lens {
|
||||
for &modulus in moduli {
|
||||
for &has_runs in &[false, true] {
|
||||
let mut input = (0..len)
|
||||
.map(|id| DropCounter {
|
||||
x: rng.next_u32() % modulus,
|
||||
id: id,
|
||||
version: Cell::new(0),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if has_runs {
|
||||
for c in &mut input {
|
||||
c.x = c.id as u32;
|
||||
}
|
||||
|
||||
for _ in 0..5 {
|
||||
let a = rng.gen::<usize>() % len;
|
||||
let b = rng.gen::<usize>() % len;
|
||||
if a < b {
|
||||
input[a..b].reverse();
|
||||
} else {
|
||||
input.swap(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test!(input, sort_by);
|
||||
test!(input, sort_unstable_by);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set default panic hook again.
|
||||
drop(panic::take_hook());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn repeat_generic_slice() {
|
||||
assert_eq!([1, 2].repeat(2), vec![1, 2, 1, 2]);
|
||||
|
@ -24,8 +24,8 @@ path = "benches/lib.rs"
|
||||
test = true
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7"
|
||||
rand_xorshift = "0.2"
|
||||
rand = { version = "0.8.5", default-features = false }
|
||||
rand_xorshift = { version = "0.3.0", default-features = false }
|
||||
|
||||
[features]
|
||||
# Make panics and failed asserts immediately abort without formatting any message
|
||||
|
@ -21,7 +21,7 @@ macro_rules! int_log_bench {
|
||||
/* Exponentially distributed random numbers from the whole range of the type. */
|
||||
let numbers: Vec<$t> = (0..256)
|
||||
.map(|_| {
|
||||
let x = rng.gen::<$t>() >> rng.gen_range(0, <$t>::BITS);
|
||||
let x = rng.gen::<$t>() >> rng.gen_range(0..<$t>::BITS);
|
||||
if x != 0 { x } else { 1 }
|
||||
})
|
||||
.collect();
|
||||
@ -38,7 +38,7 @@ macro_rules! int_log_bench {
|
||||
/* Exponentially distributed random numbers from the range 0..256. */
|
||||
let numbers: Vec<$t> = (0..256)
|
||||
.map(|_| {
|
||||
let x = (rng.gen::<u8>() >> rng.gen_range(0, u8::BITS)) as $t;
|
||||
let x = (rng.gen::<u8>() >> rng.gen_range(0..u8::BITS)) as $t;
|
||||
if x != 0 { x } else { 1 }
|
||||
})
|
||||
.collect();
|
||||
|
@ -155,3 +155,16 @@ mod time;
|
||||
mod tuple;
|
||||
mod unicode;
|
||||
mod waker;
|
||||
|
||||
/// Copied from `std::test_helpers::test_rng`, see that function for rationale.
|
||||
#[track_caller]
|
||||
#[allow(dead_code)] // Not used in all configurations.
|
||||
pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
|
||||
use core::hash::{BuildHasher, Hash, Hasher};
|
||||
let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
|
||||
core::panic::Location::caller().hash(&mut hasher);
|
||||
let hc64 = hasher.finish();
|
||||
let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
|
||||
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
|
||||
rand::SeedableRng::from_seed(seed)
|
||||
}
|
||||
|
@ -9,8 +9,6 @@ use core::num::flt2dec::MAX_SIG_DIGITS;
|
||||
use core::num::flt2dec::{decode, DecodableFloat, Decoded, FullDecoded};
|
||||
|
||||
use rand::distributions::{Distribution, Uniform};
|
||||
use rand::rngs::StdRng;
|
||||
use rand::SeedableRng;
|
||||
|
||||
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
|
||||
match decode(v).1 {
|
||||
@ -92,7 +90,7 @@ where
|
||||
if cfg!(target_os = "emscripten") {
|
||||
return; // using rng pulls in i128 support, which doesn't work
|
||||
}
|
||||
let mut rng = StdRng::from_entropy();
|
||||
let mut rng = crate::test_rng();
|
||||
let f32_range = Uniform::new(0x0000_0001u32, 0x7f80_0000);
|
||||
iterate("f32_random_equivalence_test", k, n, f, g, |_| {
|
||||
let x = f32::from_bits(f32_range.sample(&mut rng));
|
||||
@ -108,7 +106,7 @@ where
|
||||
if cfg!(target_os = "emscripten") {
|
||||
return; // using rng pulls in i128 support, which doesn't work
|
||||
}
|
||||
let mut rng = StdRng::from_entropy();
|
||||
let mut rng = crate::test_rng();
|
||||
let f64_range = Uniform::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
|
||||
iterate("f64_random_equivalence_test", k, n, f, g, |_| {
|
||||
let x = f64::from_bits(f64_range.sample(&mut rng));
|
||||
|
@ -1805,7 +1805,7 @@ fn brute_force_rotate_test_1() {
|
||||
fn sort_unstable() {
|
||||
use core::cmp::Ordering::{Equal, Greater, Less};
|
||||
use core::slice::heapsort;
|
||||
use rand::{rngs::StdRng, seq::SliceRandom, Rng, SeedableRng};
|
||||
use rand::{seq::SliceRandom, Rng};
|
||||
|
||||
// Miri is too slow (but still need to `chain` to make the types match)
|
||||
let lens = if cfg!(miri) { (2..20).chain(0..0) } else { (2..25).chain(500..510) };
|
||||
@ -1813,7 +1813,7 @@ fn sort_unstable() {
|
||||
|
||||
let mut v = [0; 600];
|
||||
let mut tmp = [0; 600];
|
||||
let mut rng = StdRng::from_entropy();
|
||||
let mut rng = crate::test_rng();
|
||||
|
||||
for len in lens {
|
||||
let v = &mut v[0..len];
|
||||
@ -1879,11 +1879,10 @@ fn sort_unstable() {
|
||||
#[cfg_attr(miri, ignore)] // Miri is too slow
|
||||
fn select_nth_unstable() {
|
||||
use core::cmp::Ordering::{Equal, Greater, Less};
|
||||
use rand::rngs::StdRng;
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::{Rng, SeedableRng};
|
||||
use rand::Rng;
|
||||
|
||||
let mut rng = StdRng::from_entropy();
|
||||
let mut rng = crate::test_rng();
|
||||
|
||||
for len in (2..21).chain(500..501) {
|
||||
let mut orig = vec![0; len];
|
||||
|
@ -33,7 +33,8 @@ default-features = false
|
||||
features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive']
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.7"
|
||||
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
|
||||
rand_xorshift = "0.3.0"
|
||||
|
||||
[target.'cfg(any(all(target_family = "wasm", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies]
|
||||
dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] }
|
||||
|
@ -3,7 +3,8 @@ use super::HashMap;
|
||||
use super::RandomState;
|
||||
use crate::assert_matches::assert_matches;
|
||||
use crate::cell::RefCell;
|
||||
use rand::{thread_rng, Rng};
|
||||
use crate::test_helpers::test_rng;
|
||||
use rand::Rng;
|
||||
use realstd::collections::TryReserveErrorKind::*;
|
||||
|
||||
// https://github.com/rust-lang/rust/issues/62301
|
||||
@ -710,16 +711,16 @@ fn test_entry_take_doesnt_corrupt() {
|
||||
}
|
||||
|
||||
let mut m = HashMap::new();
|
||||
let mut rng = thread_rng();
|
||||
let mut rng = test_rng();
|
||||
|
||||
// Populate the map with some items.
|
||||
for _ in 0..50 {
|
||||
let x = rng.gen_range(-10, 10);
|
||||
let x = rng.gen_range(-10..10);
|
||||
m.insert(x, ());
|
||||
}
|
||||
|
||||
for _ in 0..1000 {
|
||||
let x = rng.gen_range(-10, 10);
|
||||
let x = rng.gen_range(-10..10);
|
||||
match m.entry(x) {
|
||||
Vacant(_) => {}
|
||||
Occupied(e) => {
|
||||
|
@ -10,7 +10,7 @@ use crate::sys_common::io::test::{tmpdir, TempDir};
|
||||
use crate::thread;
|
||||
use crate::time::{Duration, Instant};
|
||||
|
||||
use rand::{rngs::StdRng, RngCore, SeedableRng};
|
||||
use rand::RngCore;
|
||||
|
||||
#[cfg(unix)]
|
||||
use crate::os::unix::fs::symlink as symlink_dir;
|
||||
@ -1181,7 +1181,7 @@ fn _assert_send_sync() {
|
||||
#[test]
|
||||
fn binary_file() {
|
||||
let mut bytes = [0; 1024];
|
||||
StdRng::from_entropy().fill_bytes(&mut bytes);
|
||||
crate::test_helpers::test_rng().fill_bytes(&mut bytes);
|
||||
|
||||
let tmpdir = tmpdir();
|
||||
|
||||
@ -1194,7 +1194,7 @@ fn binary_file() {
|
||||
#[test]
|
||||
fn write_then_read() {
|
||||
let mut bytes = [0; 1024];
|
||||
StdRng::from_entropy().fill_bytes(&mut bytes);
|
||||
crate::test_helpers::test_rng().fill_bytes(&mut bytes);
|
||||
|
||||
let tmpdir = tmpdir();
|
||||
|
||||
|
@ -652,3 +652,30 @@ mod sealed {
|
||||
#[unstable(feature = "sealed", issue = "none")]
|
||||
pub trait Sealed {}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)] // Not used in all configurations.
|
||||
pub(crate) mod test_helpers {
|
||||
/// Test-only replacement for `rand::thread_rng()`, which is unusable for
|
||||
/// us, as we want to allow running stdlib tests on tier-3 targets which may
|
||||
/// not have `getrandom` support.
|
||||
///
|
||||
/// Does a bit of a song and dance to ensure that the seed is different on
|
||||
/// each call (as some tests sadly rely on this), but doesn't try that hard.
|
||||
///
|
||||
/// This is duplicated in the `core`, `alloc` test suites (as well as
|
||||
/// `std`'s integration tests), but figuring out a mechanism to share these
|
||||
/// seems far more painful than copy-pasting a 7 line function a couple
|
||||
/// times, given that even under a perma-unstable feature, I don't think we
|
||||
/// want to expose types from `rand` from `std`.
|
||||
#[track_caller]
|
||||
pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
|
||||
use core::hash::{BuildHasher, Hash, Hasher};
|
||||
let mut hasher = crate::collections::hash_map::RandomState::new().build_hasher();
|
||||
core::panic::Location::caller().hash(&mut hasher);
|
||||
let hc64 = hasher.finish();
|
||||
let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
|
||||
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
|
||||
rand::SeedableRng::from_seed(seed)
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
use crate::sync::mpsc::channel;
|
||||
use crate::sync::{Arc, RwLock, RwLockReadGuard, TryLockError};
|
||||
use crate::thread;
|
||||
use rand::{self, Rng};
|
||||
use rand::Rng;
|
||||
|
||||
#[derive(Eq, PartialEq, Debug)]
|
||||
struct NonCopy(i32);
|
||||
@ -28,7 +28,7 @@ fn frob() {
|
||||
let tx = tx.clone();
|
||||
let r = r.clone();
|
||||
thread::spawn(move || {
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut rng = crate::test_helpers::test_rng();
|
||||
for _ in 0..M {
|
||||
if rng.gen_bool(1.0 / (N as f64)) {
|
||||
drop(r.write().unwrap());
|
||||
|
@ -39,9 +39,10 @@ pub mod test {
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller] // for `test_rng`
|
||||
pub fn tmpdir() -> TempDir {
|
||||
let p = env::temp_dir();
|
||||
let mut r = rand::thread_rng();
|
||||
let mut r = crate::test_helpers::test_rng();
|
||||
let ret = p.join(&format!("rust-{}", r.next_u32()));
|
||||
fs::create_dir(&ret).unwrap();
|
||||
TempDir(ret)
|
||||
|
@ -1,12 +1,24 @@
|
||||
use std::env::*;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::{thread_rng, Rng};
|
||||
use rand::distributions::{Alphanumeric, DistString};
|
||||
|
||||
/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
|
||||
/// seed not being the same for every RNG invocation too.
|
||||
#[track_caller]
|
||||
pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
|
||||
use core::hash::{BuildHasher, Hash, Hasher};
|
||||
let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
|
||||
core::panic::Location::caller().hash(&mut hasher);
|
||||
let hc64 = hasher.finish();
|
||||
let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>();
|
||||
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
|
||||
rand::SeedableRng::from_seed(seed)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn make_rand_name() -> OsString {
|
||||
let rng = thread_rng();
|
||||
let n = format!("TEST{}", rng.sample_iter(&Alphanumeric).take(10).collect::<String>());
|
||||
let n = format!("TEST{}", Alphanumeric.sample_string(&mut test_rng(), 10));
|
||||
let n = OsString::from(n);
|
||||
assert!(var_os(&n).is_none());
|
||||
n
|
||||
|
@ -195,7 +195,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
"rand_xorshift",
|
||||
"rand_xoshiro",
|
||||
"redox_syscall",
|
||||
|
Loading…
Reference in New Issue
Block a user