From 79f1b0ffdbc8605c99ce8348d40ee073a2a7bd0f Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Mon, 12 Aug 2024 12:16:08 +0100 Subject: [PATCH] Document known issues: #1378, #1312, #1476. --- CHANGELOG.md | 1 + rand_distr/src/binomial.rs | 13 +++++++++++++ rand_distr/src/poisson.rs | 15 +++++++++++++++ src/distr/weighted_index.rs | 2 ++ src/seq/slice.rs | 6 ++++++ 5 files changed, 37 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 205cf4c14b..fca9d4807f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update. - Fix portability of `rand::distributions::Slice` (#1469) - Rename `rand::distributions` to `rand::distr` (#1470) - The `serde1` feature has been renamed `serde` (#1477) +- Mark `WeightError`, `PoissonError`, `BinomialError` as `#[non_exhaustive]` (#1480). ## [0.9.0-alpha.1] - 2024-03-18 - Add the `Slice::num_choices` method to the Slice distribution (#1402) diff --git a/rand_distr/src/binomial.rs b/rand_distr/src/binomial.rs index fa061b0333..885d8b21c3 100644 --- a/rand_distr/src/binomial.rs +++ b/rand_distr/src/binomial.rs @@ -26,6 +26,10 @@ use rand::Rng; /// /// `f(k) = n!/(k! (n-k)!) p^k (1-p)^(n-k)` for `k >= 0`. /// +/// # Known issues +/// +/// See documentation of [`Binomial::new`]. +/// /// # Plot /// /// The following plot of the binomial distribution illustrates the @@ -54,6 +58,8 @@ pub struct Binomial { /// Error type returned from [`Binomial::new`]. #[derive(Clone, Copy, Debug, PartialEq, Eq)] +// Marked non_exhaustive to allow a new error code in the solution to #1378. +#[non_exhaustive] pub enum Error { /// `p < 0` or `nan`. ProbabilityTooSmall, @@ -76,6 +82,13 @@ impl std::error::Error for Error {} impl Binomial { /// Construct a new `Binomial` with the given shape parameters `n` (number /// of trials) and `p` (probability of success). + /// + /// # Known issues + /// + /// Although this method should return an [`Error`] on invalid parameters, + /// some (extreme) parameter combinations are known to return a [`Binomial`] + /// object which panics when [sampled](Distribution::sample). + /// See [#1378](https://github.com/rust-random/rand/issues/1378). pub fn new(n: u64, p: f64) -> Result { if !(p >= 0.0) { return Err(Error::ProbabilityTooSmall); diff --git a/rand_distr/src/poisson.rs b/rand_distr/src/poisson.rs index fd631a256f..09eae374db 100644 --- a/rand_distr/src/poisson.rs +++ b/rand_distr/src/poisson.rs @@ -23,6 +23,10 @@ use rand::Rng; /// This distribution has density function: /// `f(k) = λ^k * exp(-λ) / k!` for `k >= 0`. /// +/// # Known issues +/// +/// See documentation of [`Poisson::new`]. +/// /// # Plot /// /// The following plot shows the Poisson distribution with various values of `λ`. @@ -56,6 +60,8 @@ where /// Error type returned from [`Poisson::new`]. #[derive(Clone, Copy, Debug, PartialEq, Eq)] +// Marked non_exhaustive to allow a new error code in the solution to #1312. +#[non_exhaustive] pub enum Error { /// `lambda <= 0` ShapeTooSmall, @@ -82,6 +88,15 @@ where { /// Construct a new `Poisson` with the given shape parameter /// `lambda`. + /// + /// # Known issues + /// + /// Although this method should return an [`Error`] on invalid parameters, + /// some (extreme) values of `lambda` are known to return a [`Poisson`] + /// object which hangs when [sampled](Distribution::sample). + /// Large (less extreme) values of `lambda` may result in successful + /// sampling but with reduced precision. + /// See [#1312](https://github.com/rust-random/rand/issues/1312). pub fn new(lambda: F) -> Result, Error> { if !lambda.is_finite() { return Err(Error::NonFinite); diff --git a/src/distr/weighted_index.rs b/src/distr/weighted_index.rs index e7c2669f9f..0d8eb7d170 100644 --- a/src/distr/weighted_index.rs +++ b/src/distr/weighted_index.rs @@ -704,6 +704,8 @@ mod test { /// Errors returned by [`WeightedIndex::new`], [`WeightedIndex::update_weights`] and other weighted distributions #[derive(Debug, Clone, Copy, PartialEq, Eq)] +// Marked non_exhaustive to allow a new error code in the solution to #1476. +#[non_exhaustive] pub enum WeightError { /// The input weight sequence is empty, too long, or wrongly ordered InvalidInput, diff --git a/src/seq/slice.rs b/src/seq/slice.rs index 7c86f00a73..75f304c922 100644 --- a/src/seq/slice.rs +++ b/src/seq/slice.rs @@ -189,6 +189,12 @@ pub trait IndexedRandom: Index { /// if the "nightly" feature is enabled, or `O(length)` space and /// `O(length + amount * log length)` time otherwise. /// + /// # Known issues + /// + /// The algorithm currently used to implement this method loses accuracy + /// when small values are used for weights. + /// See [#1476](https://github.com/rust-random/rand/issues/1476). + /// /// # Example /// /// ```