@@ -95,8 +95,6 @@ macro_rules! rc_box {
9595
9696 // ~~~ $Rc<T> and Box<T> like inherent impls ~~~ //
9797
98- // downcast is pretty useless without CoerceUnsized
99-
10098 impl $RcBox<dyn Any + ' static > {
10199 doc_comment! {
102100 concat!( "Attempt to downcast the box to a concrete type.
@@ -122,7 +120,8 @@ print_if_string(my_number.try_into().unwrap());
122120```
123121
124122The unsizing as `" , stringify!( $Rc) , "` is required until
125- [DST coercions](https://github.com/rust-lang/rust/issues/27732) are stabilized." ) ,
123+ [DST coercions](https://github.com/rust-lang/rust/issues/27732) are stabilized. Alternatively,
124+ activate the `unsize` feature to convert the pointer via an explicit method call." ) ,
126125 #[ inline]
127126 pub fn downcast<T >( self ) -> Result <$RcBox<T >, Self >
128127 where T : Any ,
@@ -164,7 +163,8 @@ print_if_string(my_number.try_into().unwrap());
164163```
165164
166165The unsizing as `" , stringify!( $Rc) , "` is required until
167- [DST coercions](https://github.com/rust-lang/rust/issues/27732) are stabilized." ) ,
166+ [DST coercions](https://github.com/rust-lang/rust/issues/27732) are stabilized. Alternatively,
167+ activate the `unsize` feature to convert the pointer via an explicit method call." ) ,
168168 #[ inline]
169169 pub fn downcast<T >( self ) -> Result <$RcBox<T >, Self >
170170 where T : Any + Send
@@ -206,7 +206,8 @@ print_if_string(my_number.try_into().unwrap());
206206```
207207
208208The unsizing as `" , stringify!( $Rc) , "` is required until
209- [DST coercions](https://github.com/rust-lang/rust/issues/27732) are stabilized." ) ,
209+ [DST coercions](https://github.com/rust-lang/rust/issues/27732) are stabilized. Alternatively,
210+ activate the `unsize` feature to convert the pointer via an explicit method call." ) ,
210211 #[ inline]
211212 pub fn downcast<T >( self ) -> Result <$RcBox<T >, Self >
212213 where T : Any + Send + Sync
@@ -634,6 +635,51 @@ then the data will be pinned in memory and unable to be moved."),
634635
635636 #[ cfg( feature = "std" ) ]
636637 impl <T : ?Sized > UnwindSafe for $RcBox<T > where Box <T >: UnwindSafe { }
638+
639+ #[ cfg( feature = "unsize" ) ]
640+ doc_comment! {
641+ concat!( "Unsizes a pointer using the `unsize` crate.
642+
643+ # Usage
644+
645+ ```
646+ # use rc_box::*;
647+ use unsize::{Coercion, CoerceUnsize};
648+
649+ let unique = " , stringify!( $RcBox) , "::new(|| 42u32);
650+ let unique:" , stringify!( $RcBox) , r"<dyn Fn() -> u32> =
651+ unique.unsize(Coercion::<_, dyn Fn() -> u32>::to_fn());
652+
653+ let value = (*unique)();
654+ assert_eq!(value, 42);
655+ ```
656+
657+ Another common usage would be to create a `dyn Any`.
658+
659+ fn print_if_string(value: " , stringify!( $RcBox) , r#"<dyn Any>) {
660+ if let Ok(string) = value.downcast::<String>() {
661+ println!("String ({}): {}", string.len(), string);
662+ }
663+ }
664+
665+ let my_string = "Hello World".to_string();
666+ let my_string: "# , stringify!( $RcBox) , "<dyn Any> = " , stringify!( $RcBox) , "::new(my_string).unsize(Coercion::to_any());
667+ print_if_string(my_string);
668+ let my_number: " , stringify!( $RcBox) , "<dyn Any> = " , stringify!( $RcBox) , "::new(0i8).unsize(Coercion::to_any());
669+ print_if_string(my_number);
670+ ```" ) ,
671+ unsafe impl <T , U : ?Sized > unsize:: CoerciblePtr <U > for $RcBox<T > {
672+ type Pointee = T ;
673+ type Output = $RcBox<U >;
674+ fn as_sized_ptr( & mut self ) -> * mut T {
675+ $RcBox:: as_raw( self ) . as_ptr( )
676+ }
677+ unsafe fn replace_ptr( self , new: * mut U ) -> $RcBox<U > {
678+ let new = $RcBox:: into_raw( self ) . replace_ptr( new) ;
679+ $RcBox:: from_raw( new. as_ptr( ) as * const U )
680+ }
681+ }
682+ }
637683 ) * } ;
638684}
639685
0 commit comments