Skip to content

Commit 91d57b8

Browse files
committed
Add unsizing for {Arc,Rc}Box
To avoid the unstable traits this uses a helper crate that provides the necessary checks and mechanisms for the raw pointer conversion while opting into them via a trait implemented for the smart pointers here.
1 parent d80e810 commit 91d57b8

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/rc-box/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,7 @@ slice-dst = { version = "1.4.0", optional = true }
2727
version = "1.0.0"
2828
path = "../erasable"
2929
optional = true
30+
31+
[dependencies.unsize]
32+
version = "1.1"
33+
optional = true

crates/rc-box/src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,50 @@ then the data will be pinned in memory and unable to be moved."),
634634

635635
#[cfg(feature = "std")]
636636
impl<T: ?Sized> UnwindSafe for $RcBox<T> where Box<T>: UnwindSafe {}
637+
638+
#[cfg(feature = "unsize")]
639+
doc_comment! {
640+
concat!("Unsizes a pointer using the `unsize` crate.
641+
# Usage
642+
643+
```
644+
# use rc_box::*;
645+
use unsize::{Coercion, CoerceUnsize};
646+
647+
let unique = ", stringify!($RcBox), "::new(|| 42u32);
648+
let unique:", stringify!($RcBox), r"<dyn Fn() -> u32> =
649+
unique.unsize(Coercion::<_, dyn Fn() -> u32>::to_fn());
650+
651+
let value = (*unique)();
652+
assert_eq!(value, 42);
653+
```
654+
655+
Another common usage would be to create an `dyn Any`.
656+
657+
fn print_if_string(value: ", stringify!($RcBox), r#"<dyn Any>) {
658+
if let Ok(string) = value.downcast::<String>() {
659+
println!("String ({}): {}", string.len(), string);
660+
}
661+
}
662+
663+
let my_string = "Hello World".to_string();
664+
let my_string: "#, stringify!($RcBox), "<dyn Any> = ", stringify!($RcBox), "::new(my_string).unsize(Coercion::to_any());
665+
print_if_string(my_string);
666+
let my_number: ", stringify!($RcBox), "<dyn Any> = ", stringify!($RcBox), "::new(0i8).unsize(Coercion::to_any());
667+
print_if_string(my_number);
668+
```"),
669+
unsafe impl<T, U: ?Sized> unsize::CoerciblePtr<U> for $RcBox<T> {
670+
type Pointee = T;
671+
type Output = $RcBox<U>;
672+
fn as_sized_ptr(&mut self) -> *mut T {
673+
$RcBox::as_raw(self).as_ptr()
674+
}
675+
unsafe fn replace_ptr(self, new: *mut U) -> $RcBox<U> {
676+
let new = $RcBox::into_raw(self).replace_ptr(new);
677+
$RcBox::from_raw(new.as_ptr() as *const U)
678+
}
679+
}
680+
}
637681
)*};
638682
}
639683

0 commit comments

Comments
 (0)