Skip to content

Commit

Permalink
ThreadRng::rng should be unsafe
Browse files Browse the repository at this point in the history
This method must be used correctly to avoid undefined behavior. Making
it `unsafe` communicates this more clearly. Note that this is a private,
internal method that was and is being used soundly.
  • Loading branch information
vks committed Sep 2, 2020
1 parent 050c1af commit e1c43ca
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -16,7 +16,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
- Implement weighted sampling without replacement (#976, #1013)

### Changes
- `ThreadRng` is no longer `Copy` to enable safe usage within thread-local destructors (see #968)
- `ThreadRng` is no longer `Copy` to enable safe usage within thread-local destructors (#968, #1035)
- `gen_range(a, b)` was replaced with `gen_range(a..b)`, and `gen_range(a..=b)`
is supported (#744, #1003). Note that `a` and `b` can no longer be references or SIMD types.
- Replace `AsByteSliceMut` with `Fill` (#940)
Expand Down
18 changes: 12 additions & 6 deletions src/rngs/thread.rs
Expand Up @@ -96,29 +96,35 @@ impl Default for ThreadRng {
}

impl ThreadRng {
/// Return a mutable reference to the internal RNG.
///
/// # Safety
///
/// The caller must make sure to stop using the returned reference before
/// anyone else calls this method.
#[inline(always)]
fn rng(&mut self) -> &mut ReseedingRng<Core, OsRng> {
unsafe { &mut *self.rng.get() }
unsafe fn rng(&mut self) -> &mut ReseedingRng<Core, OsRng> {
&mut *self.rng.get()
}
}

impl RngCore for ThreadRng {
#[inline(always)]
fn next_u32(&mut self) -> u32 {
self.rng().next_u32()
unsafe { self.rng().next_u32() }
}

#[inline(always)]
fn next_u64(&mut self) -> u64 {
self.rng().next_u64()
unsafe { self.rng().next_u64() }
}

fn fill_bytes(&mut self, dest: &mut [u8]) {
self.rng().fill_bytes(dest)
unsafe { self.rng().fill_bytes(dest) }
}

fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
self.rng().try_fill_bytes(dest)
unsafe { self.rng().try_fill_bytes(dest) }
}
}

Expand Down

0 comments on commit e1c43ca

Please sign in to comment.