Merge de37698fd5f61cd95cc35437f22e602244f25bd9 on remote branch

Change-Id: I03f7ae41bbab7a24717ebb8311f318a6beb3a082
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
diff --git a/Android.bp b/Android.bp
index 5cd98d7..5f32482 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,7 +43,7 @@
     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 @@
         "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 @@
 
 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 @@
 
 ## [0.10-pre] - 2014-03-02
 ### Added
-- Seperate `rand` out of the standard library
+- Separate `rand` out of the standard library
diff --git a/Cargo.lock b/Cargo.lock
index d9cea07..631e46a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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 @@
 
 [[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 @@
 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 @@
  "packed_simd_2",
  "rand_chacha",
  "rand_core",
- "rand_hc",
  "rand_pcg",
  "serde",
 ]
@@ -130,15 +118,6 @@
 ]
 
 [[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 @@
 
 [[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 @@
 
 [[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 @@
 
 [[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"
diff --git a/Cargo.toml b/Cargo.toml
index b109e37..3f38081 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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 @@
 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 @@
 [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 @@
 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 @@
 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 @@
 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 @@
     "rand_core",
     "rand_distr",
     "rand_chacha",
-    "rand_hc",
     "rand_pcg",
 ]
 
@@ -58,11 +66,12 @@
 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 @@
 # 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 @@
    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.
diff --git a/METADATA b/METADATA
index 5d320d8..2449ce5 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   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
   }
 }
diff --git a/README.md b/README.md
index 355e53b..44c2e4d 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@
 
 ```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 @@
 
 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 @@
 -   `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 @@
 
 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 @@
 /// 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 @@
 // `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 @@
             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 @@
 
 #[cfg(test)]
 mod tests {
-    use crate::distributions::{Alphanumeric, Distribution, Standard, Uniform};
+    use crate::distributions::{Distribution, Uniform};
     use crate::Rng;
 
     #[test]
@@ -231,7 +231,7 @@
 
         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 @@
     #[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 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 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 @@
     }
 }
 
-#[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! { 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!(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 @@
         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 @@
         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 @@
 /// *   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 @@
 #[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 @@
 /// # 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, 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 @@
 /// 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 @@
 /// [`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 @@
 /// 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! { 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! { 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 @@
 /// [`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 @@
     #[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 @@
     #[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 @@
                 );)*
             }};
         }
-        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 @@
     #[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 @@
     #[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 @@
             ],
         );
     }
+
+    #[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 @@
 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 @@
         )+
     };
 }
-#[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 @@
         }
     };
 }
+#[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 @@
     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 @@
 ///
 /// [`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 @@
             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`.
diff --git a/src/lib.rs b/src/lib.rs
index 6f8665a..6d84718 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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,
diff --git a/src/rng.rs b/src/rng.rs
index 07643c5..79a9fbf 100644
--- a/src/rng.rs
+++ b/src/rng.rs
@@ -389,13 +389,10 @@
     }
 }
 
-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 @@
 ///
 /// - 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 [`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 @@
 
     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 @@
 
 
 // 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 @@
 #[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 @@
 
     #[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 @@
 
         // 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 @@
 
         // 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)];