@@ -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 {
133124fn 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 ) ) ;
0 commit comments