Skip to content

Commit 8421c73

Browse files
committed
more
1 parent 8b167b9 commit 8421c73

2 files changed

Lines changed: 56 additions & 40 deletions

File tree

internal/src/dyn_init.rs

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ pub fn expand(args: TokenStream, item: TokenStream) -> Result<TokenStream> {
1919
0,
2020
parse_quote!(#[doc = ::core::concat!("Dynamic version of `", #name, "`.")]),
2121
);
22-
fun.sig.ident = format_ident!("dyn_{}", fun.sig.ident);
2322
let OutputSet {
2423
raw_recv,
2524
real_recv,
@@ -30,20 +29,12 @@ pub fn expand(args: TokenStream, item: TokenStream) -> Result<TokenStream> {
3029
set_body(
3130
default,
3231
(raw_recv, real_recv),
33-
fun.sig
34-
.inputs
35-
.iter()
36-
.filter_map(|r| match r {
37-
FnArg::Receiver(_) => None,
38-
FnArg::Typed(arg) => Some(arg),
39-
})
40-
.cloned()
41-
.collect(),
4232
&mut fun.sig,
4333
dyn_,
4434
recv_span,
4535
);
4636
}
37+
fun.sig.ident = format_ident!("dyn_{}", fun.sig.ident);
4738
Ok(quote! {
4839
#normal
4940
#fun
@@ -133,38 +124,10 @@ fn is_self_ty(ty: &Type) -> bool {
133124
fn set_body(
134125
body: &mut Block,
135126
(raw, real): (Type, Type),
136-
args: Vec<PatType>,
137127
sig: &mut Signature,
138128
dyn_: Type,
139129
recv_span: Span,
140130
) {
141-
let arg_pats = args.iter().map(|arg| &arg.pat);
142-
let arg_types = args.iter().map(|arg| &arg.ty);
143-
let mut this = format_ident!("this");
144-
this.set_span(recv_span);
145-
let mut stmts = mem::take(&mut body.stmts);
146-
for s in &mut stmts {
147-
SelfReplacer(this.clone()).visit_stmt_mut(s);
148-
}
149-
body.stmts.push(parse_quote! {
150-
unsafe fn __raw_init(
151-
slot: *mut (),
152-
(#this, #(#arg_pats),*): (#raw, #(#arg_types),*),
153-
) -> <#dyn_ as ::core::ptr::Pointee>::Metadata {
154-
let value = move || {
155-
let #this = unsafe { &*(#this as *const Baz) };
156-
#(#stmts)*
157-
}();
158-
let slot = slot.cast();
159-
unsafe { slot.write(value) };
160-
let r = unsafe { &*slot };
161-
let r = r as &#dyn_;
162-
Ok(::core::ptr::metadata(r))
163-
}
164-
});
165-
body.stmts.push(parse_quote! {
166-
let this: *const Self = self;
167-
});
168131
let args = sig
169132
.inputs
170133
.iter_mut()
@@ -183,10 +146,54 @@ fn set_body(
183146
subpat: None,
184147
}));
185148
ident
186-
});
149+
})
150+
.collect::<Vec<_>>();
151+
let arg_types = sig
152+
.inputs
153+
.iter()
154+
.filter_map(|r| match r {
155+
FnArg::Receiver(_) => None,
156+
FnArg::Typed(arg) => Some(arg),
157+
})
158+
.map(|arg| &arg.ty);
159+
let name = &sig.ident;
160+
let mut this = format_ident!("this");
161+
this.set_span(recv_span);
162+
body.stmts.clear();
163+
body.stmts.push(parse_quote! {
164+
let __raw_init = |
165+
slot: *mut (),
166+
(#this, #(#args),*): (#raw, #(#arg_types),*),
167+
| -> ::pin_init::InitOk<#dyn_> {
168+
let #this = unsafe { &*(#this as *const Baz) };
169+
let mut ptr = ::core::ptr::null_mut();
170+
let value = Self::#name(#this, #(#args),*);
171+
if false {
172+
unsafe { *ptr = value };
173+
::core::unreachable!()
174+
} else {
175+
ptr = slot.cast();
176+
unsafe { ptr.write(value) };
177+
let r = unsafe { &*ptr };
178+
let r = r as &#dyn_;
179+
::pin_init::InitOk::from_metadata(::core::ptr::metadata(r))
180+
}
181+
};
182+
});
183+
body.stmts.push(parse_quote!(let this: *const Self = self;));
184+
body.stmts.push(parse_quote!(let layout = {
185+
let mut ptr = ::core::ptr::null_mut();
186+
if false {
187+
unsafe { *ptr = Self::#name(self, #(#args),*) };
188+
}
189+
fn layout_for<T>(_: *mut T) -> ::core::alloc::Layout {
190+
::core::alloc::Layout::new::<T>()
191+
}
192+
layout_for(ptr)
193+
};));
187194
body.stmts.push(Stmt::Expr(
188195
parse_quote!(unsafe {
189-
::pin_init::DynInit::new(__raw_init, (this.cast::<()>(), #(#args),*, layout))
196+
::pin_init::DynInit::new(__raw_init, (this.cast::<()>(), #(#args),*), layout)
190197
}),
191198
None,
192199
));

src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,15 @@ impl<T: ?Sized> InitOk<T> {
997997
_phantom: PhantomData,
998998
}
999999
}
1000+
1001+
///
1002+
#[cfg(feature = "dyn")]
1003+
pub fn from_metadata(meta: <T as ptr::Pointee>::Metadata) -> Self {
1004+
Self {
1005+
meta,
1006+
_phantom: PhantomData,
1007+
}
1008+
}
10001009
}
10011010

10021011
/// A pin-initializer for the type `T`.

0 commit comments

Comments
 (0)