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 crates now require
rustc version 1.36.0 or later.
This allowed us to remove some unsafe code and simplify the internal
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
getrandom only as a dependency:
- You may have to update the
getrandomfeatures you are using. The following features are now available:
"rdrand": Use the RDRAND instruction on
wasm32-unknown-unknown. This replaces the
wasm-bindgenfeatures, 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
customfeature to provide a panicking implementation.
- Windows XP and stdweb are, as of
getrandomversion 0.2.1, no longer supported. If you require support for either of these platforms you may add a dependency on
getrandom = "=0.2.0"to pin this version.
- Hermit, L4Re and UEFI are no longer officially supported. You can use the
rdrandfeature 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
Serde has been re-added as an optional dependency (use the
flag), supporting many types (where appropriate).
deliberately excluded since these types are not portable.
ThreadRng no longer implements
Copy. This was necessary to fix a possible
use-after-free in its thread-local destructor. Any code relying on
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. Thus, replace
gen_range(a, b) with
gen_range(a..b). We suggest using the following regular
expression to search-replace in all files:
- or with
gen_range($1..$2)(if your tool does not support backreferences)
Most IDEs support search-replace-across-files or similar; alternatively an external tool such as Regexxer may be used.
This change has a couple of other implications:
- inclusive ranges are now supported, e.g.
- it may be necessary to explicitly dereference some parameters
- SIMD types are no longer supported (
Uniformtypes may still be used directly)
AsByteSliceMut trait was replaced with the
Fill trait. This should
only affect code implementing
AsByteSliceMut on user-defined types, since the
Rng::try_fill retain support for previously-supported types.
Fill supports some additional slice types which could not be supported with
[bool], [char], [f32], [f64].
The entire [
rand::rngs::adapter] module is now restricted to the
While this is technically a breaking change, it should only affect
ReseedingRng, which is unlikely to exist in the wild.
StdRng has switched from the 20-round ChaCha20 to ChaCha12 for improved
performance. This is a reduction in complexity but the 12-round variant is still
considered secure: see rand#932. This is a value-breaking change for
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 and improves performance. It is a value-breaking change.
Several smaller changes occurred to rand distributions:
Uniformdistribution now additionally supports the
chartype, so for example
rng.gen_range('a'..='f')is now supported.
Alphanumericdistribution 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
char. For example, with Rand 0.7 you could write:
With Rand 0.8, this is equivalent to the following:
let chars: String = iter::repeat(()) .map(|()| rng.sample(Alphanumeric)) .take(7) .collect();
let chars: String = iter::repeat(()) .map(|()| rng.sample(Alphanumeric)) .map(char::from) .take(7) .collect();
- The alternative implementation of
WeightedIndexemploying the alias method was moved from
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 v0.4, more changes occurred (since v0.2):
rand_distr::WeightedAliasIndexwas added (moved from the
Hypergeometricdistributions are now supported.
- A different algorithm is used for the
Betadistribution, improving both performance and accuracy. This is a value-breaking change.
LogNormaldistributions now support a
from_mean_cvconstructor method and
rand_distr::Dirichletnow uses boxed slices internally instead of
Vec. Therefore, the weights are taken as a slice instead of a
Vecas input. For example, the following
can be replaced with the following
Dirichlet::new(vec![1.0, 2.0, 3.0]).unwrap();
Dirichlet::new(&[1.0, 2.0, 3.0]).unwrap();
rand_distr::Poissondoes no longer support sampling
u64values directly. Old code may have to be updated to perform the conversion from
- The custom
rand_distrwas replaced with
num_traits::Float. Any implementations of
Floatfor user-defined types have to be migrated. Thanks to the math functions from
Additonally, there were some minor improvements:
- The treatment of rounding errors and NaN was improved for the
rand_distr::Expdistribution now supports the
lambda = 0parametrization.
There have been value-breaking
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.
StdRng is now gated behind a new feature flag,
std_rng. This is enabled by
nightly feature no longer implies the
simd_support feature. If you were
relying on this for SIMD support, you will have to use