Skip to content

Commit 22e6883

Browse files
committed
Auto merge of #104658 - thomcc:rand-update-and-usable-no_std, r=Mark-Simulacrum
Update `rand` in the stdlib tests, and remove the `getrandom` feature from it. The main goal is actually removing `getrandom`, so that eventually we can allow running the stdlib test suite on tier3 targets which don't have `getrandom` support. Currently those targets can only run the subset of stdlib tests that exist in uitests, and (generally speaking), we prefer not to test libstd functionality in uitests, which came up recently in rust-lang/rust#104095 and rust-lang/rust#104185. Additionally, the fact that we can't update `rand`/`getrandom` means we're stuck with the old set of tier3 targets, so can't test new ones. ~~Anyway, I haven't checked that this actually does allow use on tier3 targets (I think it does not, as some work is needed in stdlib submodules) but it moves us slightly closer to this, and seems to allow at least finally updating our `rand` dep, which definitely improves the status quo.~~ Checked and works now. For the most part, our tests and benchmarks are fine using hard-coded seeds. A couple tests seem to fail with this (stuff manipulating the environment expecting no collisions, for example), or become pointless (all inputs to a function become equivalent). In these cases I've done a (gross) dance (ab)using `RandomState` and `Location::caller()` for some extra "entropy". Trying to share that code seems *way* more painful than it's worth given that the duplication is a 7-line function, even if the lines are quite gross. (Keeping in mind that sharing it would require adding `rand` as a non-dev dep to std, and exposing a type from it publicly, all of which sounds truly awful, even if done behind a perma-unstable feature). See also some previous attempts: - rust-lang/rust#86963 (in particular rust-lang/rust#86963 (comment) which explains why this is non-trivial) - rust-lang/rust#89131 - rust-lang/rust#96626 (comment) (I tried in that PR at the same time, but settled for just removing the usage of `thread_rng()` from the benchmarks, since that was the main goal). - rust-lang/rust#104185 - Probably more. It's very tempting of a thing to "just update". r? `@Mark-Simulacrum`
2 parents b055008 + f0685e3 commit 22e6883

File tree

20 files changed

+474
-388
lines changed

20 files changed

+474
-388
lines changed

alloc/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ core = { path = "../core" }
1313
compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
1414

1515
[dev-dependencies]
16-
rand = "0.7"
17-
rand_xorshift = "0.2"
16+
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
17+
rand_xorshift = "0.3.0"
1818

1919
[[test]]
2020
name = "collectionstests"

alloc/benches/slice.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{mem, ptr};
22

3-
use rand::distributions::{Alphanumeric, Standard};
3+
use rand::distributions::{Alphanumeric, DistString, Standard};
44
use rand::Rng;
55
use test::{black_box, Bencher};
66

@@ -218,7 +218,7 @@ fn gen_strings(len: usize) -> Vec<String> {
218218
let mut v = vec![];
219219
for _ in 0..len {
220220
let n = rng.gen::<usize>() % 20 + 1;
221-
v.push((&mut rng).sample_iter(&Alphanumeric).take(n).collect());
221+
v.push(Alphanumeric.sample_string(&mut rng, n));
222222
}
223223
v
224224
}

alloc/src/collections/binary_heap/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ fn test_retain() {
465465
#[test]
466466
#[cfg(not(target_os = "emscripten"))]
467467
fn panic_safe() {
468-
use rand::{seq::SliceRandom, thread_rng};
468+
use rand::seq::SliceRandom;
469469
use std::cmp;
470470
use std::panic::{self, AssertUnwindSafe};
471471
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -490,7 +490,7 @@ fn panic_safe() {
490490
self.0.partial_cmp(&other.0)
491491
}
492492
}
493-
let mut rng = thread_rng();
493+
let mut rng = crate::test_helpers::test_rng();
494494
const DATASZ: usize = 32;
495495
// Miri is too slow
496496
let ntest = if cfg!(miri) { 1 } else { 10 };

alloc/src/collections/linked_list/tests.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::vec::Vec;
55
use std::panic::{catch_unwind, AssertUnwindSafe};
66
use std::thread;
77

8-
use rand::{thread_rng, RngCore};
8+
use rand::RngCore;
99

1010
#[test]
1111
fn test_basic() {
@@ -481,12 +481,12 @@ fn test_split_off_2() {
481481
}
482482
}
483483

484-
fn fuzz_test(sz: i32) {
484+
fn fuzz_test(sz: i32, rng: &mut impl RngCore) {
485485
let mut m: LinkedList<_> = LinkedList::new();
486486
let mut v = vec![];
487487
for i in 0..sz {
488488
check_links(&m);
489-
let r: u8 = thread_rng().next_u32() as u8;
489+
let r: u8 = rng.next_u32() as u8;
490490
match r % 6 {
491491
0 => {
492492
m.pop_back();
@@ -521,11 +521,12 @@ fn fuzz_test(sz: i32) {
521521

522522
#[test]
523523
fn test_fuzz() {
524+
let mut rng = crate::test_helpers::test_rng();
524525
for _ in 0..25 {
525-
fuzz_test(3);
526-
fuzz_test(16);
526+
fuzz_test(3, &mut rng);
527+
fuzz_test(16, &mut rng);
527528
#[cfg(not(miri))] // Miri is too slow
528-
fuzz_test(189);
529+
fuzz_test(189, &mut rng);
529530
}
530531
}
531532

alloc/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@
192192
#![feature(unsized_fn_params)]
193193
#![feature(c_unwind)]
194194
#![feature(with_negative_coherence)]
195+
#![cfg_attr(test, feature(panic_update_hook))]
195196
//
196197
// Rustdoc features:
197198
#![feature(doc_cfg)]
@@ -255,3 +256,20 @@ pub mod vec;
255256
pub mod __export {
256257
pub use core::format_args;
257258
}
259+
260+
#[cfg(test)]
261+
#[allow(dead_code)] // Not used in all configurations
262+
pub(crate) mod test_helpers {
263+
/// Copied from `std::test_helpers::test_rng`, since these tests rely on the
264+
/// seed not being the same for every RNG invocation too.
265+
pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
266+
use std::hash::{BuildHasher, Hash, Hasher};
267+
let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
268+
std::panic::Location::caller().hash(&mut hasher);
269+
let hc64 = hasher.finish();
270+
let seed_vec =
271+
hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<crate::vec::Vec<u8>>();
272+
let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
273+
rand::SeedableRng::from_seed(seed)
274+
}
275+
}

alloc/src/slice.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ use crate::borrow::ToOwned;
2828
use crate::boxed::Box;
2929
use crate::vec::Vec;
3030

31+
#[cfg(test)]
32+
mod tests;
33+
3134
#[unstable(feature = "slice_range", issue = "76393")]
3235
pub use core::slice::range;
3336
#[unstable(feature = "array_chunks", issue = "74985")]

0 commit comments

Comments
 (0)