diff options
author | David LeGare <legare@google.com> | 2022-03-03 23:21:58 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-03-03 23:21:58 +0000 |
commit | 237bc83fbfa14335404c620caa3c986e712348d9 (patch) | |
tree | 369e273affe8fedc061e4b74319fcf9b418aa961 | |
parent | 271eede053420cdcea5f348bb0eed9f41a0c006f (diff) | |
parent | 10d725b23a2aef9fabf6b46dbdc5f56903e57fe1 (diff) | |
download | rand-android-13.0.0_r18.tar.gz |
Update rand to 0.8.5 am: e63a633abe am: 413cb84e89 am: 10d725b23at_frc_odp_330442040t_frc_odp_330442000t_frc_ase_330444010android-13.0.0_r30android-13.0.0_r29android-13.0.0_r28android-13.0.0_r27android-13.0.0_r24android-13.0.0_r23android-13.0.0_r22android-13.0.0_r21android-13.0.0_r20android-13.0.0_r19android-13.0.0_r18android-13.0.0_r17android-13.0.0_r16aml_go_odp_330912000aml_go_ads_330915100aml_go_ads_330915000aml_go_ads_330913000android13-qpr1-s8-releaseandroid13-qpr1-s7-releaseandroid13-qpr1-s6-releaseandroid13-qpr1-s5-releaseandroid13-qpr1-s4-releaseandroid13-qpr1-s3-releaseandroid13-qpr1-s2-releaseandroid13-qpr1-s1-releaseandroid13-qpr1-releaseandroid13-mainline-go-adservices-releaseandroid13-frc-odp-releaseandroid13-dev
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/rand/+/2004097
Change-Id: Icb69e071839bde9938840b984557b692799fdc98
-rw-r--r-- | .cargo_vcs_info.json | 7 | ||||
-rw-r--r-- | Android.bp | 3 | ||||
-rw-r--r-- | CHANGELOG.md | 20 | ||||
-rw-r--r-- | Cargo.lock | 77 | ||||
-rw-r--r-- | Cargo.toml | 30 | ||||
-rw-r--r-- | Cargo.toml.orig | 35 | ||||
-rw-r--r-- | LICENSE-APACHE | 25 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | src/distributions/bernoulli.rs | 9 | ||||
-rw-r--r-- | src/distributions/distribution.rs | 6 | ||||
-rw-r--r-- | src/distributions/float.rs | 2 | ||||
-rw-r--r-- | src/distributions/integer.rs | 9 | ||||
-rw-r--r-- | src/distributions/mod.rs | 2 | ||||
-rw-r--r-- | src/distributions/other.rs | 18 | ||||
-rw-r--r-- | src/distributions/uniform.rs | 41 | ||||
-rw-r--r-- | src/distributions/utils.rs | 6 | ||||
-rw-r--r-- | src/distributions/weighted.rs | 1 | ||||
-rw-r--r-- | src/distributions/weighted_index.rs | 7 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/rng.rs | 9 | ||||
-rw-r--r-- | src/rngs/adapter/reseeding.rs | 26 | ||||
-rw-r--r-- | src/rngs/std.rs | 6 | ||||
-rw-r--r-- | src/rngs/thread.rs | 9 | ||||
-rw-r--r-- | src/seq/index.rs | 8 | ||||
-rw-r--r-- | src/seq/mod.rs | 13 |
26 files changed, 181 insertions, 207 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 7f98fc0..681c31d 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "8792268dfe57e49bb4518190bf4fe66176759a44" - } -} + "sha1": "937320cbfeebd4352a23086d9c6e68f067f74644" + }, + "path_in_vcs": "" +}
\ No newline at end of file @@ -43,7 +43,7 @@ rust_library { host_supported: true, crate_name: "rand", cargo_env_compat: true, - cargo_pkg_version: "0.8.4", + cargo_pkg_version: "0.8.5", srcs: ["src/lib.rs"], edition: "2018", features: [ @@ -52,7 +52,6 @@ rust_library { "getrandom", "libc", "rand_chacha", - "rand_hc", "small_rng", "std", "std_rng", diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c7387a..b0872af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,24 @@ A [separate changelog is kept for rand_core](rand_core/CHANGELOG.md). You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.html) useful. +## [0.8.5] - 2021-08-20 +### Fixes +- Fix build on non-32/64-bit architectures (#1144) +- Fix "min_const_gen" feature for `no_std` (#1173) +- Check `libc::pthread_atfork` return value with panic on error (#1178) +- More robust reseeding in case `ReseedingRng` is used from a fork handler (#1178) +- Fix nightly: remove unused `slice_partition_at_index` feature (#1215) +- Fix nightly + `simd_support`: update `packed_simd` (#1216) + +### Rngs +- `StdRng`: Switch from HC128 to ChaCha12 on emscripten (#1142). + We now use ChaCha12 on all platforms. + +### Documentation +- Added docs about rand's use of const generics (#1150) +- Better random chars example (#1157) + + ## [0.8.4] - 2021-06-15 ### Additions - Use const-generics to support arrays of all sizes (#1104) @@ -678,4 +696,4 @@ when updating from `rand 0.7.0` without also updating `rand_core`. ## [0.10-pre] - 2014-03-02 ### Added -- Seperate `rand` out of the standard library +- Separate `rand` out of the standard library @@ -1,28 +1,17 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "bincode" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "byteorder", "serde", ] [[package]] -name = "byteorder" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -30,20 +19,20 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "getrandom" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] [[package]] name = "libc" -version = "0.2.91" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libm" @@ -57,46 +46,46 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "packed_simd_2" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e64858a2d3733fdd61adfdd6da89aa202f7ff0e741d2fc7ed1e452ba9dc99d7" +checksum = "defdcfef86dcc44ad208f71d9ff4ce28df6537a4e0d6b0e8e845cb8ca10059a6" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", "libm", ] [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" dependencies = [ "proc-macro2", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" dependencies = [ "bincode", "libc", @@ -104,7 +93,6 @@ dependencies = [ "packed_simd_2", "rand_chacha", "rand_core", - "rand_hc", "rand_pcg", "serde", ] @@ -130,15 +118,6 @@ dependencies = [ ] [[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - -[[package]] name = "rand_pcg" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -149,18 +128,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.125" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", @@ -169,9 +148,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.67" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" +checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" dependencies = [ "proc-macro2", "quote", @@ -180,9 +159,9 @@ dependencies = [ [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "wasi" @@ -3,17 +3,16 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "rand" -version = "0.8.4" +version = "0.8.5" authors = ["The Rand Project Developers", "The Rust Project Developers"] include = ["src/", "LICENSE-*", "README.md", "CHANGELOG.md", "COPYRIGHT"] autobenches = true @@ -36,11 +35,16 @@ version = "0.4.4" optional = true [dependencies.packed_simd] -version = "0.3.5" +version = "0.3.7" features = ["into_bits"] optional = true package = "packed_simd_2" +[dependencies.rand_chacha] +version = "0.3.0" +optional = true +default-features = false + [dependencies.rand_core] version = "0.6.0" @@ -51,9 +55,6 @@ optional = true [dev-dependencies.bincode] version = "1.2.1" -[dev-dependencies.rand_hc] -version = "0.3.0" - [dev-dependencies.rand_pcg] version = "0.3.0" @@ -67,14 +68,7 @@ serde1 = ["serde", "rand_core/serde1"] simd_support = ["packed_simd"] small_rng = [] std = ["rand_core/std", "rand_chacha/std", "alloc", "getrandom", "libc"] -std_rng = ["rand_chacha", "rand_hc"] -[target."cfg(not(target_os = \"emscripten\"))".dependencies.rand_chacha] -version = "0.3.0" -optional = true -default-features = false -[target."cfg(target_os = \"emscripten\")".dependencies.rand_hc] -version = "0.3.0" -optional = true +std_rng = ["rand_chacha"] [target."cfg(unix)".dependencies.libc] version = "0.2.22" optional = true diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 5ce3123..98ba373 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "rand" -version = "0.8.4" +version = "0.8.5" authors = ["The Rand Project Developers", "The Rust Project Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -16,6 +16,15 @@ autobenches = true edition = "2018" include = ["src/", "LICENSE-*", "README.md", "CHANGELOG.md", "COPYRIGHT"] +[package.metadata.docs.rs] +# To build locally: +# RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --all-features --no-deps --open +all-features = true +rustdoc-args = ["--cfg", "doc_cfg"] + +[package.metadata.playground] +features = ["small_rng", "serde1"] + [features] # Meta-features: default = ["std", "std_rng"] @@ -36,7 +45,7 @@ getrandom = ["rand_core/getrandom"] simd_support = ["packed_simd"] # Option (enabled by default): enable StdRng -std_rng = ["rand_chacha", "rand_hc"] +std_rng = ["rand_chacha"] # Option: enable SmallRng small_rng = [] @@ -50,7 +59,6 @@ members = [ "rand_core", "rand_distr", "rand_chacha", - "rand_hc", "rand_pcg", ] @@ -58,11 +66,12 @@ members = [ rand_core = { path = "rand_core", version = "0.6.0" } log = { version = "0.4.4", optional = true } serde = { version = "1.0.103", features = ["derive"], optional = true } +rand_chacha = { path = "rand_chacha", version = "0.3.0", default-features = false, optional = true } [dependencies.packed_simd] # NOTE: so far no version works reliably due to dependence on unstable features package = "packed_simd_2" -version = "0.3.5" +version = "0.3.7" optional = true features = ["into_bits"] @@ -70,25 +79,7 @@ features = ["into_bits"] # Used for fork protection (reseeding.rs) libc = { version = "0.2.22", optional = true, default-features = false } -# Emscripten does not support 128-bit integers, which are used by ChaCha code. -# We work around this by using a different RNG. -[target.'cfg(not(target_os = "emscripten"))'.dependencies] -rand_chacha = { path = "rand_chacha", version = "0.3.0", default-features = false, optional = true } -[target.'cfg(target_os = "emscripten")'.dependencies] -rand_hc = { path = "rand_hc", version = "0.3.0", optional = true } - [dev-dependencies] rand_pcg = { path = "rand_pcg", version = "0.3.0" } -# Only for benches: -rand_hc = { path = "rand_hc", version = "0.3.0" } # Only to test serde1 bincode = "1.2.1" - -[package.metadata.docs.rs] -# To build locally: -# RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --all-features --no-deps --open -all-features = true -rustdoc-args = ["--cfg", "doc_cfg"] - -[package.metadata.playground] -features = ["small_rng", "serde1"] diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 17d7468..494ad3b 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -174,28 +174,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/rand/rand-0.8.4.crate" + value: "https://static.crates.io/crates/rand/rand-0.8.5.crate" } - version: "0.8.4" + version: "0.8.5" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 6 - day: 21 + year: 2022 + month: 3 + day: 1 } } @@ -51,7 +51,7 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -rand = "0.8.0" +rand = "0.8.4" ``` To get started using Rand, see [The Book](https://rust-random.github.io/book). @@ -120,7 +120,7 @@ Rand is built with these features enabled by default: Optionally, the following dependencies can be enabled: -- `log` enables logging via the `log` crate` crate +- `log` enables logging via the `log` crate Additionally, these features configure Rand: @@ -128,6 +128,8 @@ Additionally, these features configure Rand: - `nightly` enables some optimizations requiring nightly Rust - `simd_support` (experimental) enables sampling of SIMD values (uniformly random SIMD integers and floats), requiring nightly Rust +- `min_const_gen` enables generating random arrays of + any size using min-const-generics, requiring Rust ≥ 1.51. Note that nightly features are not stable and therefore not all library and compiler versions will be compatible. This is especially true of Rand's @@ -143,7 +145,7 @@ unavailable. The WASM target `wasm32-unknown-unknown` is not *automatically* supported by `rand` or `getrandom`. To solve this, either use a different target such as -`wasm32-wasi` or add a direct dependancy on `getrandom` with the `js` feature +`wasm32-wasi` or add a direct dependency on `getrandom` with the `js` feature (if the target supports JavaScript). See [getrandom#WebAssembly support](https://docs.rs/getrandom/latest/getrandom/#webassembly-support). diff --git a/src/distributions/bernoulli.rs b/src/distributions/bernoulli.rs index d54d599..226db79 100644 --- a/src/distributions/bernoulli.rs +++ b/src/distributions/bernoulli.rs @@ -33,7 +33,7 @@ use serde::{Serialize, Deserialize}; /// This `Bernoulli` distribution uses 64 bits from the RNG (a `u64`), /// so only probabilities that are multiples of 2<sup>-64</sup> can be /// represented. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))] pub struct Bernoulli { /// Probability of success, relative to the maximal integer. @@ -49,7 +49,7 @@ pub struct Bernoulli { // `f64` only has 53 bits of precision, and the next largest value of `p` will // result in `2^64 - 2048`. // -// Also there is a 100% theoretical concern: if someone consistenly wants to +// Also there is a 100% theoretical concern: if someone consistently wants to // generate `true` using the Bernoulli distribution (i.e. by using a probability // of `1.0`), just using `u64::MAX` is not enough. On average it would return // false once every 2^64 iterations. Some people apparently care about this @@ -211,4 +211,9 @@ mod test { true, false, false, true, false, false, true, true, true, true ]); } + + #[test] + fn bernoulli_distributions_can_be_compared() { + assert_eq!(Bernoulli::new(1.0), Bernoulli::new(1.0)); + } } diff --git a/src/distributions/distribution.rs b/src/distributions/distribution.rs index e7f7677..c5cf6a6 100644 --- a/src/distributions/distribution.rs +++ b/src/distributions/distribution.rs @@ -209,7 +209,7 @@ pub trait DistString { #[cfg(test)] mod tests { - use crate::distributions::{Alphanumeric, Distribution, Standard, Uniform}; + use crate::distributions::{Distribution, Uniform}; use crate::Rng; #[test] @@ -231,7 +231,7 @@ mod tests { let mut rng = crate::test::rng(212); let val = dist.sample(&mut rng); - assert!(val >= 15 && val <= 20); + assert!((15..=20).contains(&val)); } #[test] @@ -258,7 +258,7 @@ mod tests { #[cfg(feature = "alloc")] fn test_dist_string() { use core::str; - use crate::distributions::DistString; + use crate::distributions::{Alphanumeric, DistString, Standard}; let mut rng = crate::test::rng(213); let s1 = Alphanumeric.sample_string(&mut rng, 20); diff --git a/src/distributions/float.rs b/src/distributions/float.rs index 733a403..ce5946f 100644 --- a/src/distributions/float.rs +++ b/src/distributions/float.rs @@ -78,7 +78,7 @@ pub struct Open01; pub trait IntoFloat { type F; - /// Helper method to combine the fraction and a contant exponent into a + /// Helper method to combine the fraction and a constant exponent into a /// float. /// /// Only the least significant bits of `self` may be set, 23 for `f32` and diff --git a/src/distributions/integer.rs b/src/distributions/integer.rs index 8a2ce4c..19ce715 100644 --- a/src/distributions/integer.rs +++ b/src/distributions/integer.rs @@ -14,8 +14,8 @@ use crate::Rng; use core::arch::x86::{__m128i, __m256i}; #[cfg(all(target_arch = "x86_64", feature = "simd_support"))] use core::arch::x86_64::{__m128i, __m256i}; -#[cfg(not(target_os = "emscripten"))] use core::num::NonZeroU128; -use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; +use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, + NonZeroU128}; #[cfg(feature = "simd_support")] use packed_simd::*; impl Distribution<u8> for Standard { @@ -46,7 +46,6 @@ impl Distribution<u64> for Standard { } } -#[cfg(not(target_os = "emscripten"))] impl Distribution<u128> for Standard { #[inline] fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> u128 { @@ -86,7 +85,6 @@ impl_int_from_uint! { i8, u8 } impl_int_from_uint! { i16, u16 } impl_int_from_uint! { i32, u32 } impl_int_from_uint! { i64, u64 } -#[cfg(not(target_os = "emscripten"))] impl_int_from_uint! { i128, u128 } impl_int_from_uint! { isize, usize } @@ -108,7 +106,6 @@ impl_nzint!(NonZeroU8, NonZeroU8::new); impl_nzint!(NonZeroU16, NonZeroU16::new); impl_nzint!(NonZeroU32, NonZeroU32::new); impl_nzint!(NonZeroU64, NonZeroU64::new); -#[cfg(not(target_os = "emscripten"))] impl_nzint!(NonZeroU128, NonZeroU128::new); impl_nzint!(NonZeroUsize, NonZeroUsize::new); @@ -173,7 +170,6 @@ mod tests { rng.sample::<i16, _>(Standard); rng.sample::<i32, _>(Standard); rng.sample::<i64, _>(Standard); - #[cfg(not(target_os = "emscripten"))] rng.sample::<i128, _>(Standard); rng.sample::<usize, _>(Standard); @@ -181,7 +177,6 @@ mod tests { rng.sample::<u16, _>(Standard); rng.sample::<u32, _>(Standard); rng.sample::<u64, _>(Standard); - #[cfg(not(target_os = "emscripten"))] rng.sample::<u128, _>(Standard); } diff --git a/src/distributions/mod.rs b/src/distributions/mod.rs index e308668..05ca806 100644 --- a/src/distributions/mod.rs +++ b/src/distributions/mod.rs @@ -158,7 +158,7 @@ use crate::Rng; /// * Tuples (up to 12 elements): each element is generated sequentially. /// * Arrays (up to 32 elements): each element is generated sequentially; /// see also [`Rng::fill`] which supports arbitrary array length for integer -/// types and tends to be faster for `u32` and smaller types. +/// and float types and tends to be faster for `u32` and smaller types. /// When using `rustc` ≥ 1.51, enable the `min_const_gen` feature to support /// arrays larger than 32 elements. /// Note that [`Rng::fill`] and `Standard`'s array support are *not* equivalent: diff --git a/src/distributions/other.rs b/src/distributions/other.rs index 71fb267..03802a7 100644 --- a/src/distributions/other.rs +++ b/src/distributions/other.rs @@ -21,7 +21,7 @@ use crate::Rng; #[cfg(feature = "serde1")] use serde::{Serialize, Deserialize}; #[cfg(feature = "min_const_gen")] -use std::mem::{self, MaybeUninit}; +use core::mem::{self, MaybeUninit}; // ----- Sampling distributions ----- @@ -32,19 +32,22 @@ use std::mem::{self, MaybeUninit}; /// # Example /// /// ``` -/// use std::iter; /// use rand::{Rng, thread_rng}; /// use rand::distributions::Alphanumeric; /// /// let mut rng = thread_rng(); -/// let chars: String = iter::repeat(()) -/// .map(|()| rng.sample(Alphanumeric)) -/// .map(char::from) -/// .take(7) -/// .collect(); +/// let chars: String = (0..7).map(|_| rng.sample(Alphanumeric) as char).collect(); /// println!("Random chars: {}", chars); /// ``` /// +/// The [`DistString`] trait provides an easier method of generating +/// a random `String`, and offers more efficient allocation: +/// ``` +/// use rand::distributions::{Alphanumeric, DistString}; +/// let string = Alphanumeric.sample_string(&mut rand::thread_rng(), 16); +/// println!("Random string: {}", string); +/// ``` +/// /// # Passwords /// /// Users sometimes ask whether it is safe to use a string of random characters @@ -187,6 +190,7 @@ tuple_impl! {A, B, C, D, E, F, G, H, I, J, K} tuple_impl! {A, B, C, D, E, F, G, H, I, J, K, L} #[cfg(feature = "min_const_gen")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "min_const_gen")))] impl<T, const N: usize> Distribution<[T; N]> for Standard where Standard: Distribution<T> { diff --git a/src/distributions/uniform.rs b/src/distributions/uniform.rs index fb89837..261357b 100644 --- a/src/distributions/uniform.rs +++ b/src/distributions/uniform.rs @@ -80,7 +80,10 @@ //! where B1: SampleBorrow<Self::X> + Sized, //! B2: SampleBorrow<Self::X> + Sized //! { -//! UniformSampler::new(low, high) +//! UniformMyF32(UniformFloat::<f32>::new_inclusive( +//! low.borrow().0, +//! high.borrow().0, +//! )) //! } //! fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X { //! MyF32(self.0.sample(rng)) @@ -103,8 +106,7 @@ //! [`UniformDuration`]: crate::distributions::uniform::UniformDuration //! [`SampleBorrow::borrow`]: crate::distributions::uniform::SampleBorrow::borrow -#[cfg(not(feature = "std"))] use core::time::Duration; -#[cfg(feature = "std")] use std::time::Duration; +use core::time::Duration; use core::ops::{Range, RangeInclusive}; use crate::distributions::float::IntoFloat; @@ -158,7 +160,7 @@ use serde::{Serialize, Deserialize}; /// println!("{}", sum); /// ``` /// -/// For a single sample, [`Rng::gen_range`] may be prefered: +/// For a single sample, [`Rng::gen_range`] may be preferred: /// /// ``` /// use rand::Rng; @@ -170,8 +172,10 @@ use serde::{Serialize, Deserialize}; /// [`new`]: Uniform::new /// [`new_inclusive`]: Uniform::new_inclusive /// [`Rng::gen_range`]: Rng::gen_range -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde1", serde(bound(serialize = "X::Sampler: Serialize")))] +#[cfg_attr(feature = "serde1", serde(bound(deserialize = "X::Sampler: Deserialize<'de>")))] pub struct Uniform<X: SampleUniform>(X::Sampler); impl<X: SampleUniform> Uniform<X> { @@ -414,7 +418,7 @@ impl<T: SampleUniform + PartialOrd> SampleRange<T> for RangeInclusive<T> { /// An alternative to using a modulus is widening multiply: After a widening /// multiply by `range`, the result is in the high word. Then comparing the low /// word against `zone` makes sure our distribution is uniform. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))] pub struct UniformInt<X> { low: X, @@ -556,7 +560,6 @@ uniform_int_impl! { i8, u8, u32 } uniform_int_impl! { i16, u16, u32 } uniform_int_impl! { i32, u32, u32 } uniform_int_impl! { i64, u64, u64 } -#[cfg(not(target_os = "emscripten"))] uniform_int_impl! { i128, u128, u128 } uniform_int_impl! { isize, usize, usize } uniform_int_impl! { u8, u8, u32 } @@ -564,7 +567,6 @@ uniform_int_impl! { u16, u16, u32 } uniform_int_impl! { u32, u32, u32 } uniform_int_impl! { u64, u64, u64 } uniform_int_impl! { usize, usize, usize } -#[cfg(not(target_os = "emscripten"))] uniform_int_impl! { u128, u128, u128 } #[cfg(feature = "simd_support")] @@ -804,7 +806,7 @@ impl UniformSampler for UniformChar { /// [`new`]: UniformSampler::new /// [`new_inclusive`]: UniformSampler::new_inclusive /// [`Standard`]: crate::distributions::Standard -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))] pub struct UniformFloat<X> { low: X, @@ -1153,7 +1155,7 @@ mod tests { #[test] #[cfg(feature = "serde1")] fn test_serialization_uniform_duration() { - let distr = UniformDuration::new(std::time::Duration::from_secs(10), std::time::Duration::from_secs(60)); + let distr = UniformDuration::new(Duration::from_secs(10), Duration::from_secs(60)); let de_distr: UniformDuration = bincode::deserialize(&bincode::serialize(&distr).unwrap()).unwrap(); assert_eq!( distr.offset, de_distr.offset @@ -1224,7 +1226,7 @@ mod tests { #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_integers() { - #[cfg(not(target_os = "emscripten"))] use core::{i128, u128}; + use core::{i128, u128}; use core::{i16, i32, i64, i8, isize}; use core::{u16, u32, u64, u8, usize}; @@ -1292,9 +1294,7 @@ mod tests { );)* }}; } - t!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize); - #[cfg(not(target_os = "emscripten"))] - t!(i128, u128); + t!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, i128, u128); #[cfg(feature = "simd_support")] { @@ -1430,7 +1430,7 @@ mod tests { #[test] #[should_panic] fn test_float_overflow() { - Uniform::from(::core::f64::MIN..::core::f64::MAX); + let _ = Uniform::from(::core::f64::MIN..::core::f64::MAX); } #[test] @@ -1505,9 +1505,6 @@ mod tests { #[test] #[cfg_attr(miri, ignore)] // Miri is too slow fn test_durations() { - #[cfg(not(feature = "std"))] use core::time::Duration; - #[cfg(feature = "std")] use std::time::Duration; - let mut rng = crate::test::rng(253); let v = &[ @@ -1650,4 +1647,12 @@ mod tests { ], ); } + + #[test] + fn uniform_distributions_can_be_compared() { + assert_eq!(Uniform::new(1.0, 2.0), Uniform::new(1.0, 2.0)); + + // To cover UniformInt + assert_eq!(Uniform::new(1 as u32, 2 as u32), Uniform::new(1 as u32, 2 as u32)); + } } diff --git a/src/distributions/utils.rs b/src/distributions/utils.rs index b11f602..89da5fd 100644 --- a/src/distributions/utils.rs +++ b/src/distributions/utils.rs @@ -56,7 +56,6 @@ macro_rules! wmul_impl { wmul_impl! { u8, u16, 8 } wmul_impl! { u16, u32, 16 } wmul_impl! { u32, u64, 32 } -#[cfg(not(target_os = "emscripten"))] wmul_impl! { u64, u128, 64 } // This code is a translation of the __mulddi3 function in LLVM's @@ -120,9 +119,6 @@ macro_rules! wmul_impl_large { )+ }; } -#[cfg(target_os = "emscripten")] -wmul_impl_large! { u64, 32 } -#[cfg(not(target_os = "emscripten"))] wmul_impl_large! { u128, 64 } macro_rules! wmul_impl_usize { @@ -138,6 +134,8 @@ macro_rules! wmul_impl_usize { } }; } +#[cfg(target_pointer_width = "16")] +wmul_impl_usize! { u16 } #[cfg(target_pointer_width = "32")] wmul_impl_usize! { u32 } #[cfg(target_pointer_width = "64")] diff --git a/src/distributions/weighted.rs b/src/distributions/weighted.rs index 6dd9273..846b9df 100644 --- a/src/distributions/weighted.rs +++ b/src/distributions/weighted.rs @@ -43,6 +43,5 @@ pub mod alias_method { impl_weight!(f64, f32,); impl_weight!(u8, u16, u32, u64, usize,); impl_weight!(i8, i16, i32, i64, isize,); - #[cfg(not(target_os = "emscripten"))] impl_weight!(u128, i128,); } diff --git a/src/distributions/weighted_index.rs b/src/distributions/weighted_index.rs index 32da37f..8252b17 100644 --- a/src/distributions/weighted_index.rs +++ b/src/distributions/weighted_index.rs @@ -75,7 +75,7 @@ use serde::{Serialize, Deserialize}; /// /// [`Uniform<X>`]: crate::distributions::Uniform /// [`RngCore`]: crate::RngCore -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))] #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))] pub struct WeightedIndex<X: SampleUniform + PartialOrd> { @@ -418,6 +418,11 @@ mod test { 2, 2, 1, 3, 2, 1, 3, 3, 2, 1, ]); } + + #[test] + fn weighted_index_distributions_can_be_compared() { + assert_eq!(WeightedIndex::new(&[1, 2]), WeightedIndex::new(&[1, 2])); + } } /// Error type returned from `WeightedIndex::new`. @@ -50,7 +50,6 @@ #![doc(test(attr(allow(unused_variables), deny(warnings))))] #![no_std] #![cfg_attr(feature = "simd_support", feature(stdsimd))] -#![cfg_attr(feature = "nightly", feature(slice_partition_at_index))] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![allow( clippy::float_cmp, @@ -389,13 +389,10 @@ macro_rules! impl_fill { } } -impl_fill!(u16, u32, u64, usize,); -#[cfg(not(target_os = "emscripten"))] -impl_fill!(u128); -impl_fill!(i8, i16, i32, i64, isize,); -#[cfg(not(target_os = "emscripten"))] -impl_fill!(i128); +impl_fill!(u16, u32, u64, usize, u128,); +impl_fill!(i8, i16, i32, i64, isize, i128,); +#[cfg_attr(doc_cfg, doc(cfg(feature = "min_const_gen")))] #[cfg(feature = "min_const_gen")] impl<T, const N: usize> Fill for [T; N] where [T]: Fill diff --git a/src/rngs/adapter/reseeding.rs b/src/rngs/adapter/reseeding.rs index 70b0b82..ae3fcbb 100644 --- a/src/rngs/adapter/reseeding.rs +++ b/src/rngs/adapter/reseeding.rs @@ -22,10 +22,10 @@ use rand_core::{CryptoRng, Error, RngCore, SeedableRng}; /// /// - On a manual call to [`reseed()`]. /// - After `clone()`, the clone will be reseeded on first use. -/// - After a process is forked, the RNG in the child process is reseeded within -/// the next few generated values, depending on the block size of the -/// underlying PRNG. For ChaCha and Hc128 this is a maximum of -/// 15 `u32` values before reseeding. +/// - When a process is forked on UNIX, the RNGs in both the parent and child +/// processes will be reseeded just before the next call to +/// [`BlockRngCore::generate`], i.e. "soon". For ChaCha and Hc128 this is a +/// maximum of fifteen `u32` values before reseeding. /// - After the PRNG has generated a configurable number of random bytes. /// /// # When should reseeding after a fixed number of generated bytes be used? @@ -43,6 +43,12 @@ use rand_core::{CryptoRng, Error, RngCore, SeedableRng}; /// Use [`ReseedingRng::new`] with a `threshold` of `0` to disable reseeding /// after a fixed number of generated bytes. /// +/// # Limitations +/// +/// It is recommended that a `ReseedingRng` (including `ThreadRng`) not be used +/// from a fork handler. +/// Use `OsRng` or `getrandom`, or defer your use of the RNG until later. +/// /// # Error handling /// /// Although unlikely, reseeding the wrapped PRNG can fail. `ReseedingRng` will @@ -310,8 +316,16 @@ mod fork { pub fn register_fork_handler() { static REGISTER: Once = Once::new(); - REGISTER.call_once(|| unsafe { - libc::pthread_atfork(None, None, Some(fork_handler)); + REGISTER.call_once(|| { + // Bump the counter before and after forking (see #1169): + let ret = unsafe { libc::pthread_atfork( + Some(fork_handler), + Some(fork_handler), + Some(fork_handler), + ) }; + if ret != 0 { + panic!("libc::pthread_atfork failed with code {}", ret); + } }); } } diff --git a/src/rngs/std.rs b/src/rngs/std.rs index 80f8433..cdae8fa 100644 --- a/src/rngs/std.rs +++ b/src/rngs/std.rs @@ -10,13 +10,9 @@ use crate::{CryptoRng, Error, RngCore, SeedableRng}; -#[cfg(all(any(test, feature = "std"), not(target_os = "emscripten")))] pub(crate) use rand_chacha::ChaCha12Core as Core; -#[cfg(all(any(test, feature = "std"), target_os = "emscripten"))] -pub(crate) use rand_hc::Hc128Core as Core; -#[cfg(not(target_os = "emscripten"))] use rand_chacha::ChaCha12Rng as Rng; -#[cfg(target_os = "emscripten")] use rand_hc::Hc128Rng as Rng; +use rand_chacha::ChaCha12Rng as Rng; /// The standard RNG. The PRNG algorithm in `StdRng` is chosen to be efficient /// on the current platform, to be statistically strong and unpredictable diff --git a/src/rngs/thread.rs b/src/rngs/thread.rs index 552851f..baebb1d 100644 --- a/src/rngs/thread.rs +++ b/src/rngs/thread.rs @@ -33,15 +33,16 @@ use crate::{CryptoRng, Error, RngCore, SeedableRng}; // Number of generated bytes after which to reseed `ThreadRng`. -// According to benchmarks, reseeding has a noticable impact with thresholds +// According to benchmarks, reseeding has a noticeable impact with thresholds // of 32 kB and less. We choose 64 kB to avoid significant overhead. const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64; /// A reference to the thread-local generator /// /// An instance can be obtained via [`thread_rng`] or via `ThreadRng::default()`. -/// This handle is safe to use everywhere (including thread-local destructors) -/// but cannot be passed between threads (is not `Send` or `Sync`). +/// This handle is safe to use everywhere (including thread-local destructors), +/// though it is recommended not to use inside a fork handler. +/// The handle cannot be passed between threads (is not `Send` or `Sync`). /// /// `ThreadRng` uses the same PRNG as [`StdRng`] for security and performance /// and is automatically seeded from [`OsRng`]. @@ -59,7 +60,7 @@ const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64; #[cfg_attr(doc_cfg, doc(cfg(all(feature = "std", feature = "std_rng"))))] #[derive(Clone, Debug)] pub struct ThreadRng { - // Rc is explictly !Send and !Sync + // Rc is explicitly !Send and !Sync rng: Rc<UnsafeCell<ReseedingRng<Core, OsRng>>>, } diff --git a/src/seq/index.rs b/src/seq/index.rs index ae36c32..b38e464 100644 --- a/src/seq/index.rs +++ b/src/seq/index.rs @@ -16,11 +16,11 @@ use alloc::collections::BTreeSet; #[cfg(feature = "std")] use std::collections::HashSet; -#[cfg(feature = "alloc")] -use crate::distributions::{uniform::SampleUniform, Distribution, Uniform}; #[cfg(feature = "std")] use crate::distributions::WeightedError; -use crate::Rng; + +#[cfg(feature = "alloc")] +use crate::{Rng, distributions::{uniform::SampleUniform, Distribution, Uniform}}; #[cfg(feature = "serde1")] use serde::{Serialize, Deserialize}; @@ -380,7 +380,7 @@ where #[cfg(not(feature = "nightly"))] { - use std::collections::BinaryHeap; + use alloc::collections::BinaryHeap; // Partially sort the array such that the `amount` elements with the largest // keys are first using a binary max heap. diff --git a/src/seq/mod.rs b/src/seq/mod.rs index 9eeb777..069e9e6 100644 --- a/src/seq/mod.rs +++ b/src/seq/mod.rs @@ -1252,11 +1252,10 @@ mod test { // Case 2: All of the weights are 0 let choices = [('a', 0), ('b', 0), ('c', 0)]; - let result = choices + + assert_eq!(choices .choose_multiple_weighted(&mut rng, 2, |item| item.1) - .unwrap() - .collect::<Vec<_>>(); - assert_eq!(result.len(), 2); + .unwrap().count(), 2); // Case 3: Negative weights let choices = [('a', -1), ('b', 1), ('c', 1)]; @@ -1269,11 +1268,9 @@ mod test { // Case 4: Empty list let choices = []; - let result = choices + assert_eq!(choices .choose_multiple_weighted(&mut rng, 0, |_: &()| 0) - .unwrap() - .collect::<Vec<_>>(); - assert_eq!(result.len(), 0); + .unwrap().count(), 0); // Case 5: NaN weights let choices = [('a', core::f64::NAN), ('b', 1.0), ('c', 1.0)]; |