@@ -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.
291291pub 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 ) ]
322322pub 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