Skip to content

Commit e0eb2ee

Browse files
committed
rand_core: implement reborrow for UnwrapMut
1 parent 975f602 commit e0eb2ee

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

rand_core/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
## Unreleased
88
### API changes
99
- Relax `Sized` bound on impls of `TryRngCore`, `TryCryptoRng` and `UnwrapMut` (#1593)
10+
- Add `UnwrapMut::re` to reborrow the inner rng with a tighter lifetime (#1595)
1011

1112
## [0.9.1] - 2025-02-16
1213
### API changes

rand_core/src/lib.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,21 @@ impl<R: TryCryptoRng> CryptoRng for UnwrapErr<R> {}
321321
#[derive(Debug, Eq, PartialEq, Hash)]
322322
pub struct UnwrapMut<'r, R: TryRngCore + ?Sized>(pub &'r mut R);
323323

324+
impl<'r, R: TryRngCore + ?Sized> UnwrapMut<'r, R> {
325+
/// Reborrow with a new lifetime
326+
///
327+
/// Rust allows references like `&T` or `&mut T` to be "reborrowed" through
328+
/// coercion: essentially, the pointer is copied under a new, shorter, lifetime.
329+
/// Until rfcs#1403 lands, reborrows on user types require a method call.
330+
#[inline(always)]
331+
pub fn re<'b>(&'b mut self) -> UnwrapMut<'b, R>
332+
where
333+
'r: 'b,
334+
{
335+
UnwrapMut(self.0)
336+
}
337+
}
338+
324339
impl<R: TryRngCore + ?Sized> RngCore for UnwrapMut<'_, R> {
325340
#[inline]
326341
fn next_u32(&mut self) -> u32 {
@@ -726,4 +741,31 @@ mod test {
726741

727742
assert!(my_api(&mut SomeRng));
728743
}
744+
745+
#[test]
746+
fn reborrow_unwrap_mut() {
747+
struct FourRng;
748+
749+
impl TryRngCore for FourRng {
750+
type Error = core::convert::Infallible;
751+
fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
752+
Ok(4)
753+
}
754+
fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
755+
unimplemented!()
756+
}
757+
fn try_fill_bytes(&mut self, _: &mut [u8]) -> Result<(), Self::Error> {
758+
unimplemented!()
759+
}
760+
}
761+
762+
let mut rng = FourRng;
763+
let mut rng = rng.unwrap_mut();
764+
765+
assert_eq!(rng.next_u32(), 4);
766+
let mut rng2 = rng.re();
767+
assert_eq!(rng2.next_u32(), 4);
768+
drop(rng2);
769+
assert_eq!(rng.next_u32(), 4);
770+
}
729771
}

0 commit comments

Comments
 (0)