Skip to content

Commit 5b296c5

Browse files
bors[bot]197g
andauthored
Merge #71
71: Add an unsizing operation to {Arc,Rc}Box r=HeroicKatora a=HeroicKatora Co-authored-by: Andreas Molzer <[email protected]>
2 parents 1481056 + e8b7cc3 commit 5b296c5

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,10 @@ 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
34+
35+
[package.metadata.docs.rs]
36+
all-features = true

crates/rc-box/src/lib.rs

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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
124122
The 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
166165
The 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
208208
The 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

Comments
 (0)