Skip to content

Commit bd4d19f

Browse files
author
YOSHIOKA Takuma
committed
Implement derive for IntoArc and IntoRc
cf. <rust-lang/rust#45990>
1 parent 8aa29b1 commit bd4d19f

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

opaque_typedef_macros/src/derives.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ pub enum Derive {
1818
DerefMut,
1919
Display,
2020
FromInner,
21+
IntoArc,
2122
IntoBox,
2223
IntoInner,
24+
IntoRc,
2325
}
2426

2527
impl Derive {
@@ -55,7 +57,9 @@ impl Derive {
5557
"Display" => &[Derive::Display],
5658
"FromInner" => &[Derive::FromInner],
5759
"IntoBox" => &[Derive::IntoBox],
60+
"IntoArc" => &[Derive::IntoArc],
5861
"IntoInner" => &[Derive::IntoInner],
62+
"IntoRc" => &[Derive::IntoRc],
5963
target => panic!(
6064
"`#[opaque_typedef({}({}))] is specified but the target `{}` is unknown",
6165
names::DERIVE,

opaque_typedef_macros/src/utils.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,15 @@ impl<'a> TypeProperties<'a> {
387387
}
388388
}
389389
},
390+
(Derive::IntoArc, Sizedness::Unsized) => quote! {
391+
impl<'a> ::std::convert::From<&'a #ty_outer> for ::std::sync::Arc<#ty_outer> {
392+
fn from(other: &'a #ty_outer) -> Self {
393+
let arc_inner = ::std::sync::Arc::<#ty_inner>::from(&other.#field_inner);
394+
let rw = ::std::sync::Arc::into_raw(arc_inner) as *mut #ty_outer;
395+
unsafe { ::std::sync::Arc::from_raw(rw) }
396+
}
397+
}
398+
},
390399
(Derive::IntoBox, Sizedness::Unsized) => quote! {
391400
impl<'a> ::std::convert::From<&'a #ty_outer> for ::std::boxed::Box<#ty_outer> {
392401
fn from(other: &'a #ty_outer) -> Self {
@@ -396,6 +405,15 @@ impl<'a> TypeProperties<'a> {
396405
}
397406
}
398407
},
408+
(Derive::IntoRc, Sizedness::Unsized) => quote! {
409+
impl<'a> ::std::convert::From<&'a #ty_outer> for ::std::rc::Rc<#ty_outer> {
410+
fn from(other: &'a #ty_outer) -> Self {
411+
let rc_inner = ::std::rc::Rc::<#ty_inner>::from(&other.#field_inner);
412+
let rw = ::std::rc::Rc::into_raw(rc_inner) as *mut #ty_outer;
413+
unsafe { ::std::rc::Rc::from_raw(rw) }
414+
}
415+
}
416+
},
399417
(Derive::IntoInner, Sizedness::Sized) => quote! {
400418
impl ::std::convert::Into<#ty_inner> for #ty_outer {
401419
fn into(self) -> #ty_inner {

opaque_typedef_tests/src/my_str.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
/// My string slice.
55
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, OpaqueTypedefUnsized)]
66
#[opaque_typedef(derive(AsciiExt, AsMutDeref, AsRefDeref, DefaultRef, Deref, DerefMut, Display,
7-
FromInner, IntoBox, IntoInner))]
7+
FromInner, IntoArc, IntoBox, IntoRc, IntoInner))]
88
#[opaque_typedef(allow_mut_ref)]
99
pub struct MyStr {
1010
#[opaque_typedef(inner)] inner: str,

opaque_typedef_tests/tests/my_str.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ mod my_str {
8686
let _: &MyStr = <&MyStr as From<&str>>::from(ok_str);
8787
}
8888

89+
#[test]
90+
fn into_arc() {
91+
let ok_str = "foobar";
92+
let my_str = MyStr::new(ok_str);
93+
let my_str_arc = ::std::sync::Arc::<MyStr>::from(my_str);
94+
let inner = <&MyStr as Into<&str>>::into(&*my_str_arc);
95+
assert_eq!(ok_str, inner);
96+
}
97+
8998
#[test]
9099
fn into_box() {
91100
let ok_str = "foobar";
@@ -95,6 +104,15 @@ mod my_str {
95104
assert_eq!(ok_str, inner);
96105
}
97106

107+
#[test]
108+
fn into_rc() {
109+
let ok_str = "foobar";
110+
let my_str = MyStr::new(ok_str);
111+
let my_str_rc = ::std::rc::Rc::<MyStr>::from(my_str);
112+
let inner = <&MyStr as Into<&str>>::into(&*my_str_rc);
113+
assert_eq!(ok_str, inner);
114+
}
115+
98116
#[test]
99117
fn into_inner() {
100118
let ok_str = "foobar";

0 commit comments

Comments
 (0)