From 2ceb3b6c0093e4333b07b370eec5c93e8572cece Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 1 Sep 2020 00:24:34 +0200 Subject: [PATCH 01/14] Updating guide for Rand 0.8 --- src/update-0.8.md | 100 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/update-0.8.md diff --git a/src/update-0.8.md b/src/update-0.8.md new file mode 100644 index 0000000..5304cde --- /dev/null +++ b/src/update-0.8.md @@ -0,0 +1,100 @@ +# Updating to 0.8 + +## Dependencies + +Rand crates now require `rustc` version 1.36.0 or later. +This allowed us to remove some unsafe code and simplify the internal `cfg` logic. + +## Core features + +[`Rng::gen_range`] now takes a `Range` instead of two numbers. +This requires replacing `gen_range(a, b)` with `gen_range(a..b)` in code written +for `rand 0.7`. If `a` or `b` were a reference, explicit dereferencing may now be +required. Additionally, inclusive ranges are now supported: `gen_range(a, b + +1)` can be replaced with `gen_range(a..=b)`. + +The `AsByteSliceMut` trait was replaced with the [`Fill`] trait. This should +only affect code implementing `AsByteSliceMut` on user-defined types, so they +are supported by [`Rng::fill`] and [`Rng::try_fill`]. Now, the [`Fill`] trait +has to be implemented instead: Rather than providing a mutable byte slice, the +user-defined type must be filled with random data. + +The entire [`rand::rngs::adapter`] module is now restricted to the `std` feature. +While this is technically a breaking change, it should only affect `no_std` code +using [`ReseedingRng`], which is unlikely to exist in the wild. + +## PRNGs + +These have seen only small changes, but noteworthy is: + +- [`StdRng`] and [`ThreadRng`] now use the ChaCha12 instead of the ChaCha20 + algorithm. This improves performance and is a value-breaking change for + [`StdRng`]. +- [`StdRng`], [`SmallRng`], and [`StepRng`] now implement `PartialEq` and `Eq`. + +## Distributions + +The most widely used distributions ([`Standard`] and [`Uniform`]), were not +significantly changed. Only the following distributions suffered breaking +changes: + +- The [`Alphanumeric`] distribution now samples bytes instead of chars. This + more closely reflects the internally used type, but old code likely has to + be adapted to perform the conversion from `u8` to `char`. +- The alternative implementation of [`WeightedIndex`] employing the alias method + was moved from `rand` to [`rand_distr::WeightedAliasIndex`]. Old code has to + be adapted accordingly. +- [`rand_distr::WeightedAliasIndex`] and [`rand_distr::Dirchlet`] now use boxed + slices instead of `Vec`. Existing code may have to be updated to reflect + this change. +- [`rand_distr::Poisson`] does no longer support sampling `u64` values directly. + Old code may have to perform the conversion from `f64` explicitly. +- The custom `Float` trait in `rand_distr` was replaced with + `num_traits::Float`. Any implementations of `Float` for user-defined types + have to be migrated. Thanks to the math functions from `num_traits::Float`, + `rand_distr` now supports `no_std`. + +Additonally, there were some minor improvements: + +- The treatment of rounding errors and NaN was improved for the + [`WeightedIndex`] distribution. +- The [`UniformInt`] and [`WeightedIndex`] distributions now support serialization + via the `serde1` feature. +- The [`rand_distr::Exp`] distribution now supports the `lambda = 0` parametrization. + +We also added several distributions: + +- [`rand_distr::WeightedAliasIndex`] (moved from the `rand` crate) +- [`rand_distr::InverseGaussian`] +- [`rand_distr::NormalInverseGaussian`] + +## Sequences + +Weighted sampling without replacement is now supported, see +[`rand::seq::index::sample_weighted`] and +[`SliceRandom::choose_multiple_weighted`]. + + +[`Fill`]: ../rand/rand/trait.Fill.html +[`Rng::gen_range`]: ../rand/rand/trait.Rng.html#method.gen_range +[`Rng::fill`]: ../rand/rand/trait.Rng.html#method.fill +[`Rng::try_fill`]: ../rand/rand/trait.Rng.html#method.try_fill +[`SmallRng`]: ../rand/rand/rngs/struct.SmallRng.html +[`StdRng`]: ../rand/rand/rngs/struct.StdRng.html +[`StepRng`]: ../rand/rand/rngs/struct.StepRng.html +[`ThreadRng`]: ../rand/rand/rngs/struct.ThreadRng.html +[`ReseedingRng`]: ../rand/rand/rngs/adapter/struct.ReseedingRng.html +[`Standard`]: ../rand/rand/distributions/struct.Standard.html +[`Uniform`]: ../rand/rand/distributions/struct.Uniform.html +[`UniformInt`]: ../rand/rand/distributions/struct.UniformInt.html +[`Alphanumeric`]: ../rand/rand/distributions/struct.Alphanumeric.html +[`WeightedIndex`]: ../rand/rand/distributions/struct.WeightedIndex.html +[`rand::rngs::adapter`]: ../rand/rand/rngs/adapter/index.html +[`rand::seq::index::sample_weighted`]: ../rand/rand/seq/index/fn.sample_weighted.html +[`SliceRandom::choose_multiple_weighted`]: ../rand/rand/seq/trait.SliceRandom.html#method.choose_multiple_weighted +[`rand_distr::WeightedAliasIndex`]: ../rand/rand_distr/struct.WeightedAliasIndex.html +[`rand_distr::InverseGaussian`]: ../rand/rand_distr/struct.InverseGaussian.html +[`rand_distr::NormalInverseGaussian`]: ../rand/rand_distr/struct.NormalInverseGaussian.html +[`rand_distr::Dirichlet`]: ../rand/rand_distr/struct.Dirichlet.html +[`rand_distr::Poisson`]: ../rand/rand_distr/struct.Poisson.html +[`rand_distr::Exp`]: ../rand/rand_distr/struct.Exp.html From f667ea86657c9de363bbf27f4c89b3fc3656e444 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 1 Sep 2020 15:02:34 +0200 Subject: [PATCH 02/14] Suggest regex for updating to new `gen_range` syntax --- src/update-0.8.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/update-0.8.md b/src/update-0.8.md index 5304cde..765236b 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -7,11 +7,13 @@ This allowed us to remove some unsafe code and simplify the internal `cfg` logic ## Core features -[`Rng::gen_range`] now takes a `Range` instead of two numbers. -This requires replacing `gen_range(a, b)` with `gen_range(a..b)` in code written -for `rand 0.7`. If `a` or `b` were a reference, explicit dereferencing may now be -required. Additionally, inclusive ranges are now supported: `gen_range(a, b + -1)` can be replaced with `gen_range(a..=b)`. +[`Rng::gen_range`] now takes a `Range` instead of two numbers. This requires +replacing `gen_range(a, b)` with `gen_range(a..b)` in code written for `rand +0.7`. We suggest to replace the regular expression +`gen_range\(([^,]*),\s*([^)]*)\)` with `gen_range(\1..\2)`. Additionally, if `a` +or `b` were a reference, explicit dereferencing may now be required. Inclusive +ranges are now supported: `gen_range(a, b + 1)` can be replaced with +`gen_range(a..=b)`. The `AsByteSliceMut` trait was replaced with the [`Fill`] trait. This should only affect code implementing `AsByteSliceMut` on user-defined types, so they From a23f875968695da259bcdf9698b7cfa5929cff00 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 1 Sep 2020 15:08:53 +0200 Subject: [PATCH 03/14] Add example for new `Alphanumeric` behavior --- src/update-0.8.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/update-0.8.md b/src/update-0.8.md index 765236b..877ac75 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -42,7 +42,22 @@ changes: - The [`Alphanumeric`] distribution now samples bytes instead of chars. This more closely reflects the internally used type, but old code likely has to - be adapted to perform the conversion from `u8` to `char`. + be adapted to perform the conversion from `u8` to `char`. For example, with + Rand 0.7 you could write: + ``` + let chars: String = iter::repeat(()) + .map(|()| rng.sample(Alphanumeric)) + .take(7) + .collect(); + ``` + With Rand 0.8, this is equivalent to the following: + ``` + let chars: String = iter::repeat(()) + .map(|()| rng.sample(Alphanumeric)) + .map(char::from) + .take(7) + .collect(); + ``` - The alternative implementation of [`WeightedIndex`] employing the alias method was moved from `rand` to [`rand_distr::WeightedAliasIndex`]. Old code has to be adapted accordingly. From 912cb334f85b3afe7efee7261360ee6dfb81927e Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 1 Sep 2020 17:56:08 +0200 Subject: [PATCH 04/14] Add more examples and replace padding --- src/update-0.8.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/update-0.8.md b/src/update-0.8.md index 877ac75..df4c2f2 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -58,14 +58,23 @@ changes: .take(7) .collect(); ``` -- The alternative implementation of [`WeightedIndex`] employing the alias method - was moved from `rand` to [`rand_distr::WeightedAliasIndex`]. Old code has to - be adapted accordingly. -- [`rand_distr::WeightedAliasIndex`] and [`rand_distr::Dirchlet`] now use boxed - slices instead of `Vec`. Existing code may have to be updated to reflect - this change. +- The alternative implementation of [`WeightedIndex`] employing the alias + method was moved from `rand` to [`rand_distr::WeightedAliasIndex`]. The + alias method is faster for large sizes, but it suffers from a slow + initialization, making it less generally useful. +- [`rand_distr::Dirchlet`] now uses boxed slices internally instead of `Vec`. + Therefore, the weights are taken as a slice instead of a `Vec` as input. + For example, the following `rand_distr 0.2` code + ``` + Dirichlet::new(vec![1.0, 2.0, 3.0]).unwrap(); + ``` + can be replaced with the following `rand_distr 0.3` code: + ``` + Dirichlet::new(&[1.0, 2.0, 3.0]).unwrap(); + ``` - [`rand_distr::Poisson`] does no longer support sampling `u64` values directly. - Old code may have to perform the conversion from `f64` explicitly. + Old code may have to be updated to perform the conversion from `f64` + explicitly. - The custom `Float` trait in `rand_distr` was replaced with `num_traits::Float`. Any implementations of `Float` for user-defined types have to be migrated. Thanks to the math functions from `num_traits::Float`, From 064e162f22798db08a226cefaaca3be12a9f7e47 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 1 Sep 2020 17:59:40 +0200 Subject: [PATCH 05/14] Mention `rand_distr` versions --- src/update-0.8.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/update-0.8.md b/src/update-0.8.md index df4c2f2..c5af976 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -1,5 +1,8 @@ # Updating to 0.8 +In the following, instructions are provided for porting your code from +`rand 0.7` and `rand_distr 0.2` to `rand 0.8` and `rand_distr 0.3`. + ## Dependencies Rand crates now require `rustc` version 1.36.0 or later. From 8f769d39a60aaba001c8395f3314a6c03cd10763 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 1 Sep 2020 18:11:06 +0200 Subject: [PATCH 06/14] Use syntax from `regex` crate --- src/update-0.8.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/update-0.8.md b/src/update-0.8.md index c5af976..d99e0f1 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -13,7 +13,7 @@ This allowed us to remove some unsafe code and simplify the internal `cfg` logic [`Rng::gen_range`] now takes a `Range` instead of two numbers. This requires replacing `gen_range(a, b)` with `gen_range(a..b)` in code written for `rand 0.7`. We suggest to replace the regular expression -`gen_range\(([^,]*),\s*([^)]*)\)` with `gen_range(\1..\2)`. Additionally, if `a` +`gen_range\(([^,]*),\s*([^)]*)\)` with `gen_range($1..$2)`. Additionally, if `a` or `b` were a reference, explicit dereferencing may now be required. Inclusive ranges are now supported: `gen_range(a, b + 1)` can be replaced with `gen_range(a..=b)`. From 8fd08ee0873008bfc1adf41ddc73eabc1ef1c4ca Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Wed, 2 Sep 2020 19:27:06 +0200 Subject: [PATCH 07/14] Mention both possible regex syntaxes --- src/update-0.8.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/update-0.8.md b/src/update-0.8.md index d99e0f1..f62345e 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -13,10 +13,11 @@ This allowed us to remove some unsafe code and simplify the internal `cfg` logic [`Rng::gen_range`] now takes a `Range` instead of two numbers. This requires replacing `gen_range(a, b)` with `gen_range(a..b)` in code written for `rand 0.7`. We suggest to replace the regular expression -`gen_range\(([^,]*),\s*([^)]*)\)` with `gen_range($1..$2)`. Additionally, if `a` -or `b` were a reference, explicit dereferencing may now be required. Inclusive -ranges are now supported: `gen_range(a, b + 1)` can be replaced with -`gen_range(a..=b)`. +`gen_range\(([^,]*),\s*([^)]*)\)` with `gen_range(\1..\2)` (or +`gen_range($1..$2)` in some tools without support for backreferences). +Additionally, if `a` or `b` were a reference, explicit dereferencing may now be +required. Inclusive ranges are now supported: `gen_range(a, b + 1)` can be +replaced with `gen_range(a..=b)`. The `AsByteSliceMut` trait was replaced with the [`Fill`] trait. This should only affect code implementing `AsByteSliceMut` on user-defined types, so they From 662c2e44b61a975246c6da9df19345bd7408f9ab Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Wed, 2 Sep 2020 19:34:30 +0200 Subject: [PATCH 08/14] Mention that `ThreadRng` is no longer `Copy` --- src/update-0.8.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/update-0.8.md b/src/update-0.8.md index f62345e..f2db56e 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -10,6 +10,21 @@ This allowed us to remove some unsafe code and simplify the internal `cfg` logic ## Core features +`ThreadRng` no longer implements `Copy`. This was necessary to fix a possible +use-after-free in its thread-local destructor. Any code relying on `ThreadRng` +being copied must be updated to use a mutable reference instead. For example, +``` +let rng = thread_rng(); +let a: u32 = Standard.sample(rng); +let b: u32 = Standard.sample(rng); +``` +can be replaced with the following code: +``` +let mut rng = thread_rng(); +let a: u32 = Standard.sample(&mut rng); +let b: u32 = Standard.sample(&mut rng); +``` + [`Rng::gen_range`] now takes a `Range` instead of two numbers. This requires replacing `gen_range(a, b)` with `gen_range(a..b)` in code written for `rand 0.7`. We suggest to replace the regular expression From 5c9949a4a12e4c5e09e4189cbfd989449fd5ad3c Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 15 Sep 2020 16:04:30 +0200 Subject: [PATCH 09/14] Mention changes to `SmallRng` algorithm --- src/update-0.8.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/update-0.8.md b/src/update-0.8.md index f2db56e..7600c34 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -51,6 +51,10 @@ These have seen only small changes, but noteworthy is: - [`StdRng`] and [`ThreadRng`] now use the ChaCha12 instead of the ChaCha20 algorithm. This improves performance and is a value-breaking change for [`StdRng`]. +- [`SmallRng`] now uses the Xoshiro128++ and Xoshiro256++ algorithm on 32-bit + and 64-bit platforms respectively. This reduces correlations of random data + generated from similar seeds, improves performance and is a value-breaking + change. - [`StdRng`], [`SmallRng`], and [`StepRng`] now implement `PartialEq` and `Eq`. ## Distributions From f2c2f5bf380661f4dd77e7f1fb1b0378afa0685e Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 15 Sep 2020 16:28:27 +0200 Subject: [PATCH 10/14] Discuss breaking changes due to getrandom --- src/update-0.8.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/update-0.8.md b/src/update-0.8.md index 7600c34..95e06c4 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -8,6 +8,30 @@ In the following, instructions are provided for porting your code from Rand crates now require `rustc` version 1.36.0 or later. This allowed us to remove some unsafe code and simplify the internal `cfg` logic. +The dependency on `getrandom` was bumped to version 0.2. While this does not +affect Rand's API, you may be affected by some of the breaking changes even if +you use `getrandom` only as a dependency: + +- You may have to update the `getrandom` features you are using. The + following features are now available: + - `"rdrand"`: Use the RDRAND instruction on `no_std` `x86/x86_64` + targets. + - `"js"`: Use JavaScript calls on `wasm32-unknown-unknown`. This + replaces the `stdweb` and `wasm-bindgen` features, which are + removed. + - `"custom"`: Allows you to specify a custom implementation. +- Unsupported targets no longer compile. If you require the previous behavior + (panicking at runtime instead of failing to compile), you can use the + `custom` feature to provide a panicking implementation. +- Hermit, L4Re and UEFI are no longer officially supported. You can use the + `rdrand` feature on these platforms. +- The minimum supported Linux kernel version is now 2.6.32. + +If you are using `getrandom`'s API directly, there are further breaking changes +that may affect you. See its +[changelog](https://github.com/rust-random/getrandom/blob/master/CHANGELOG.md#020---2020-09-10). + + ## Core features `ThreadRng` no longer implements `Copy`. This was necessary to fix a possible From 445e96aeaa7f060e86777e9bf38a8341d93925d5 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 22 Sep 2020 21:56:46 +0200 Subject: [PATCH 11/14] Mention split of `nightly` and `simd_support` feature --- src/update-0.8.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/update-0.8.md b/src/update-0.8.md index 95e06c4..754a06e 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -141,6 +141,10 @@ We also added several distributions: - [`rand_distr::InverseGaussian`] - [`rand_distr::NormalInverseGaussian`] +The `nightly` feature no longer implies the `simd_support` feature. If you were +relying on this for SIMD support, you will have to use `simd_support` feature +directly. + ## Sequences Weighted sampling without replacement is now supported, see From a2bb6cb616e7beeb77c22a74f20b9b54258c34bc Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Sun, 18 Oct 2020 15:07:20 +0200 Subject: [PATCH 12/14] Mention changes to `IteratorRandom` --- src/update-0.8.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/update-0.8.md b/src/update-0.8.md index 754a06e..9469876 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -151,6 +151,11 @@ Weighted sampling without replacement is now supported, see [`rand::seq::index::sample_weighted`] and [`SliceRandom::choose_multiple_weighted`]. +There have been value-breaking changes to [`IteratorRandom::choose`] improving +accuracy and performance. Furthermore, [`IteratorRandom::choose_stable`] was +added to provide an alternative that sacrifices performance for independence of +iterator size hints. + [`Fill`]: ../rand/rand/trait.Fill.html [`Rng::gen_range`]: ../rand/rand/trait.Rng.html#method.gen_range @@ -169,6 +174,8 @@ Weighted sampling without replacement is now supported, see [`rand::rngs::adapter`]: ../rand/rand/rngs/adapter/index.html [`rand::seq::index::sample_weighted`]: ../rand/rand/seq/index/fn.sample_weighted.html [`SliceRandom::choose_multiple_weighted`]: ../rand/rand/seq/trait.SliceRandom.html#method.choose_multiple_weighted +[`IteratorRandom::choose`]: ../rand/rand/seq/trait.IteratorRandom.html#method.choose +[`IteratorRandom::choose_stable`]: ../rand/rand/seq/trait.IteratorRandom.html#method.choose_stable [`rand_distr::WeightedAliasIndex`]: ../rand/rand_distr/struct.WeightedAliasIndex.html [`rand_distr::InverseGaussian`]: ../rand/rand_distr/struct.InverseGaussian.html [`rand_distr::NormalInverseGaussian`]: ../rand/rand_distr/struct.NormalInverseGaussian.html From 02e535462e00589a535692a7452329bc086a483a Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 20 Oct 2020 01:01:00 +0200 Subject: [PATCH 13/14] Add link to PR --- src/update-0.8.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/update-0.8.md b/src/update-0.8.md index 9469876..2ae1231 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -151,10 +151,11 @@ Weighted sampling without replacement is now supported, see [`rand::seq::index::sample_weighted`] and [`SliceRandom::choose_multiple_weighted`]. -There have been value-breaking changes to [`IteratorRandom::choose`] improving -accuracy and performance. Furthermore, [`IteratorRandom::choose_stable`] was -added to provide an alternative that sacrifices performance for independence of -iterator size hints. +There have been [value-breaking +changes](https://github.com/rust-random/rand/pull/1059) to +[`IteratorRandom::choose`], improving accuracy and performance. Furthermore, +[`IteratorRandom::choose_stable`] was added to provide an alternative that +sacrifices performance for independence of iterator size hints. [`Fill`]: ../rand/rand/trait.Fill.html From 5c83a3c297f8ea1ddf8365caaee323c2998d6428 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Tue, 15 Dec 2020 17:56:27 +0100 Subject: [PATCH 14/14] Fix typo --- src/update-0.8.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/update-0.8.md b/src/update-0.8.md index 2ae1231..3daa0b6 100644 --- a/src/update-0.8.md +++ b/src/update-0.8.md @@ -109,7 +109,7 @@ changes: method was moved from `rand` to [`rand_distr::WeightedAliasIndex`]. The alias method is faster for large sizes, but it suffers from a slow initialization, making it less generally useful. -- [`rand_distr::Dirchlet`] now uses boxed slices internally instead of `Vec`. +- [`rand_distr::Dirichlet`] now uses boxed slices internally instead of `Vec`. Therefore, the weights are taken as a slice instead of a `Vec` as input. For example, the following `rand_distr 0.2` code ```