diff --git a/CHANGELOG.md b/CHANGELOG.md index 96d9c3eb9a..4499433951 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update. - Bump the MSRV to 1.61.0 - Rename `Rng::gen` to `Rng::random` to avoid conflict with the new `gen` keyword in Rust 2024 (#1435) - Move all benchmarks to new `benches` crate (#1439) +- Annotate panicking methods with `#[track_caller]` (#1442) ## [0.9.0-alpha.1] - 2024-03-18 - Add the `Slice::num_choices` method to the Slice distribution (#1402) diff --git a/rand_core/src/lib.rs b/rand_core/src/lib.rs index 70424e6c9c..6617ea1c80 100644 --- a/rand_core/src/lib.rs +++ b/rand_core/src/lib.rs @@ -385,6 +385,7 @@ pub trait SeedableRng: Sized { /// [`getrandom`]: https://docs.rs/getrandom #[cfg(feature = "getrandom")] #[cfg_attr(doc_cfg, doc(cfg(feature = "getrandom")))] + #[track_caller] fn from_entropy() -> Self { let mut seed = Self::Seed::default(); if let Err(err) = getrandom::getrandom(seed.as_mut()) { diff --git a/src/rng.rs b/src/rng.rs index d9927197cc..6c9d4b7eab 100644 --- a/src/rng.rs +++ b/src/rng.rs @@ -9,11 +9,11 @@ //! [`Rng`] trait -use rand_core::{Error, RngCore}; use crate::distributions::uniform::{SampleRange, SampleUniform}; use crate::distributions::{self, Distribution, Standard}; use core::num::Wrapping; use core::{mem, slice}; +use rand_core::{Error, RngCore}; /// An automatically-implemented extension trait on [`RngCore`] providing high-level /// generic methods for sampling values and other convenience methods. @@ -124,10 +124,11 @@ pub trait Rng: RngCore { /// ``` /// /// [`Uniform`]: distributions::uniform::Uniform + #[track_caller] fn gen_range(&mut self, range: R) -> T where T: SampleUniform, - R: SampleRange + R: SampleRange, { assert!(!range.is_empty(), "cannot sample empty range"); range.sample_single(self).unwrap() @@ -236,8 +237,9 @@ pub trait Rng: RngCore { /// /// [`fill_bytes`]: RngCore::fill_bytes /// [`try_fill`]: Rng::try_fill + #[track_caller] fn fill(&mut self, dest: &mut T) { - dest.try_fill(self).unwrap_or_else(|_| panic!("Rng::fill failed")) + dest.try_fill(self).expect("Rng::fill failed") } /// Fill any type implementing [`Fill`] with random data @@ -288,9 +290,12 @@ pub trait Rng: RngCore { /// /// [`Bernoulli`]: distributions::Bernoulli #[inline] + #[track_caller] fn gen_bool(&mut self, p: f64) -> bool { - let d = distributions::Bernoulli::new(p).unwrap(); - self.sample(d) + match distributions::Bernoulli::new(p) { + Ok(d) => self.sample(d), + Err(_) => panic!("p={:?} is outside range [0.0, 1.0]", p), + } } /// Return a bool with a probability of `numerator/denominator` of being @@ -317,9 +322,15 @@ pub trait Rng: RngCore { /// /// [`Bernoulli`]: distributions::Bernoulli #[inline] + #[track_caller] fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool { - let d = distributions::Bernoulli::from_ratio(numerator, denominator).unwrap(); - self.sample(d) + match distributions::Bernoulli::from_ratio(numerator, denominator) { + Ok(d) => self.sample(d), + Err(_) => panic!( + "p={}/{} is outside range [0.0, 1.0]", + numerator, denominator + ), + } } /// Alias for [`Rng::random`]. @@ -432,8 +443,8 @@ where [T]: Fill #[cfg(test)] mod test { use super::*; - use crate::test::rng; use crate::rngs::mock::StepRng; + use crate::test::rng; #[cfg(feature = "alloc")] use alloc::boxed::Box; #[test]