Skip to content

Commit 775b05b

Browse files
authored
Relax Sized requirements for blanket impls (#1593)
Relaxes `Sized` bound on blanket impls for `TryRngCore`, `TryCryptoRng`, `UnwrapErr`, and `UnwrapMut`.
1 parent ec6d5c0 commit 775b05b

File tree

2 files changed

+95
-4
lines changed

2 files changed

+95
-4
lines changed

rand_core/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## Unreleased
8+
### API changes
9+
- Relax `Sized` bound on impls of `TryRngCore`, `TryCryptoRng` and `UnwrapMut` (#1593)
10+
711
## [0.9.1] - 2025-02-16
812
### API changes
913
- Add `TryRngCore::unwrap_mut`, providing an impl of `RngCore` over `&mut rng` (#1589)

rand_core/src/lib.rs

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ pub trait TryRngCore {
254254
// Note that, unfortunately, this blanket impl prevents us from implementing
255255
// `TryRngCore` for types which can be dereferenced to `TryRngCore`, i.e. `TryRngCore`
256256
// will not be automatically implemented for `&mut R`, `Box<R>`, etc.
257-
impl<R: RngCore> TryRngCore for R {
257+
impl<R: RngCore + ?Sized> TryRngCore for R {
258258
type Error = core::convert::Infallible;
259259

260260
#[inline]
@@ -290,7 +290,7 @@ impl<R: RngCore> TryRngCore for R {
290290
/// (like [`OsRng`]) or if the `default()` instance uses a strong, fresh seed.
291291
pub trait TryCryptoRng: TryRngCore {}
292292

293-
impl<R: CryptoRng> TryCryptoRng for R {}
293+
impl<R: CryptoRng + ?Sized> TryCryptoRng for R {}
294294

295295
/// Wrapper around [`TryRngCore`] implementation which implements [`RngCore`]
296296
/// by panicking on potential errors.
@@ -321,7 +321,7 @@ 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: TryRngCore> RngCore for UnwrapMut<'_, R> {
324+
impl<R: TryRngCore + ?Sized> RngCore for UnwrapMut<'_, R> {
325325
#[inline]
326326
fn next_u32(&mut self) -> u32 {
327327
self.0.try_next_u32().unwrap()
@@ -338,7 +338,7 @@ impl<R: TryRngCore> RngCore for UnwrapMut<'_, R> {
338338
}
339339
}
340340

341-
impl<R: TryCryptoRng> CryptoRng for UnwrapMut<'_, R> {}
341+
impl<R: TryCryptoRng + ?Sized> CryptoRng for UnwrapMut<'_, R> {}
342342

343343
/// A random number generator that can be explicitly seeded.
344344
///
@@ -639,4 +639,91 @@ mod test {
639639
// value-breakage test:
640640
assert_eq!(results[0], 5029875928683246316);
641641
}
642+
643+
// A stub RNG.
644+
struct SomeRng;
645+
646+
impl RngCore for SomeRng {
647+
fn next_u32(&mut self) -> u32 {
648+
unimplemented!()
649+
}
650+
fn next_u64(&mut self) -> u64 {
651+
unimplemented!()
652+
}
653+
fn fill_bytes(&mut self, _: &mut [u8]) {
654+
unimplemented!()
655+
}
656+
}
657+
658+
impl CryptoRng for SomeRng {}
659+
660+
#[test]
661+
fn dyn_rngcore_to_tryrngcore() {
662+
// Illustrates the need for `+ ?Sized` bound in `impl<R: RngCore> TryRngCore for R`.
663+
664+
// A method in another crate taking a fallible RNG
665+
fn third_party_api(_rng: &mut (impl TryRngCore + ?Sized)) -> bool {
666+
true
667+
}
668+
669+
// A method in our crate requiring an infallible RNG
670+
fn my_api(rng: &mut dyn RngCore) -> bool {
671+
// We want to call the method above
672+
third_party_api(rng)
673+
}
674+
675+
assert!(my_api(&mut SomeRng));
676+
}
677+
678+
#[test]
679+
fn dyn_cryptorng_to_trycryptorng() {
680+
// Illustrates the need for `+ ?Sized` bound in `impl<R: CryptoRng> TryCryptoRng for R`.
681+
682+
// A method in another crate taking a fallible RNG
683+
fn third_party_api(_rng: &mut (impl TryCryptoRng + ?Sized)) -> bool {
684+
true
685+
}
686+
687+
// A method in our crate requiring an infallible RNG
688+
fn my_api(rng: &mut dyn CryptoRng) -> bool {
689+
// We want to call the method above
690+
third_party_api(rng)
691+
}
692+
693+
assert!(my_api(&mut SomeRng));
694+
}
695+
696+
#[test]
697+
fn dyn_unwrap_mut_tryrngcore() {
698+
// Illustrates the need for `+ ?Sized` bound in
699+
// `impl<R: TryRngCore> RngCore for UnwrapMut<'_, R>`.
700+
701+
fn third_party_api(_rng: &mut impl RngCore) -> bool {
702+
true
703+
}
704+
705+
fn my_api(rng: &mut (impl TryRngCore + ?Sized)) -> bool {
706+
let mut infallible_rng = rng.unwrap_mut();
707+
third_party_api(&mut infallible_rng)
708+
}
709+
710+
assert!(my_api(&mut SomeRng));
711+
}
712+
713+
#[test]
714+
fn dyn_unwrap_mut_trycryptorng() {
715+
// Illustrates the need for `+ ?Sized` bound in
716+
// `impl<R: TryCryptoRng> CryptoRng for UnwrapMut<'_, R>`.
717+
718+
fn third_party_api(_rng: &mut impl CryptoRng) -> bool {
719+
true
720+
}
721+
722+
fn my_api(rng: &mut (impl TryCryptoRng + ?Sized)) -> bool {
723+
let mut infallible_rng = rng.unwrap_mut();
724+
third_party_api(&mut infallible_rng)
725+
}
726+
727+
assert!(my_api(&mut SomeRng));
728+
}
642729
}

0 commit comments

Comments
 (0)