@@ -58,6 +58,8 @@ trait Adapted: Any {
5858 fn move_from ( & self ) -> Option < Rc < dyn Adapted > > {
5959 None
6060 }
61+
62+ fn destroy ( & self ) { }
6163}
6264
6365impl < T : FnSig > Adapted for T {
@@ -72,20 +74,23 @@ trait Lambda<T: FnSig> {
7274 fn call ( & self , args : T :: Args ) -> T :: Ret ;
7375 fn copy_from ( & self ) -> Box < dyn Lambda < T > > ;
7476 fn move_from ( & self ) -> Box < dyn Lambda < T > > ;
77+ fn destroy ( & self ) ;
7578}
7679
7780struct LambdaSafe < L , C > {
7881 captures : L ,
7982 call : C ,
8083 copy_from : fn ( & L ) -> L ,
8184 move_from : fn ( & L ) -> L ,
85+ destroy : fn ( & L ) ,
8286}
8387
8488struct LambdaUnsafe < L , C > {
8589 captures : UnsafeCell < L > ,
8690 call : C ,
8791 copy_from : fn ( & mut L ) -> L ,
8892 move_from : fn ( & mut L ) -> L ,
93+ destroy : fn ( & mut L ) ,
8994}
9095
9196struct Closure < T : FnSig > ( Box < dyn Lambda < T > > ) ;
@@ -104,6 +109,10 @@ impl<T: FnSig> Adapted for Closure<T> {
104109 fn move_from ( & self ) -> Option < Rc < dyn Adapted > > {
105110 Some ( Rc :: new ( Closure :: < T > ( self . 0 . move_from ( ) ) ) )
106111 }
112+
113+ fn destroy ( & self ) {
114+ self . 0 . destroy ( ) ;
115+ }
107116}
108117
109118pub struct FnPtr < T : FnSig > {
@@ -225,6 +234,12 @@ impl<T: FnSig> FnPtr<T> {
225234 }
226235 }
227236
237+ pub fn destroy ( & self ) {
238+ if let Some ( original) = & self . original {
239+ original. destroy ( ) ;
240+ }
241+ }
242+
228243 fn boxed_original ( & self ) -> Option < Rc < dyn Adapted > > {
229244 match & self . original {
230245 Some ( original) => Some ( original. clone ( ) ) ,
@@ -254,8 +269,9 @@ macro_rules! impl_fn_ptr_call {
254269 call: fn ( & Captures $( , $a) * ) -> R ,
255270 copy_from: fn ( & Captures ) -> Captures ,
256271 move_from: fn ( & Captures ) -> Captures ,
272+ destroy: fn ( & Captures ) ,
257273 ) -> Self {
258- let lambda = LambdaSafe { captures, call, copy_from, move_from } ;
274+ let lambda = LambdaSafe { captures, call, copy_from, move_from, destroy } ;
259275 FnPtr {
260276 addr: call as usize ,
261277 current: None ,
@@ -268,12 +284,14 @@ macro_rules! impl_fn_ptr_call {
268284 call: fn ( & mut Captures $( , $a) * ) -> R ,
269285 copy_from: fn ( & mut Captures ) -> Captures ,
270286 move_from: fn ( & mut Captures ) -> Captures ,
287+ destroy: fn ( & mut Captures ) ,
271288 ) -> Self {
272289 let lambda = LambdaUnsafe {
273290 captures: UnsafeCell :: new( captures) ,
274291 call,
275292 copy_from,
276293 move_from,
294+ destroy,
277295 } ;
278296 FnPtr {
279297 addr: call as usize ,
@@ -297,6 +315,7 @@ macro_rules! impl_fn_ptr_call {
297315 call: self . call,
298316 copy_from: self . copy_from,
299317 move_from: self . move_from,
318+ destroy: self . destroy,
300319 } )
301320 }
302321
@@ -306,8 +325,13 @@ macro_rules! impl_fn_ptr_call {
306325 call: self . call,
307326 copy_from: self . copy_from,
308327 move_from: self . move_from,
328+ destroy: self . destroy,
309329 } )
310330 }
331+
332+ fn destroy( & self ) {
333+ ( self . destroy) ( & self . captures)
334+ }
311335 }
312336
313337 impl <Captures : ' static , R : FnPtrArg $( , $a: FnPtrArg ) * > Lambda <fn ( $( $a, ) * ) -> R >
@@ -326,6 +350,7 @@ macro_rules! impl_fn_ptr_call {
326350 call: self . call,
327351 copy_from: self . copy_from,
328352 move_from: self . move_from,
353+ destroy: self . destroy,
329354 } )
330355 }
331356
@@ -337,8 +362,13 @@ macro_rules! impl_fn_ptr_call {
337362 call: self . call,
338363 copy_from: self . copy_from,
339364 move_from: self . move_from,
365+ destroy: self . destroy,
340366 } )
341367 }
368+
369+ fn destroy( & self ) {
370+ ( self . destroy) ( unsafe { & mut * self . captures. get( ) } )
371+ }
342372 }
343373 impl_fn_ptr_call!( @peel $( $a) * ) ;
344374 } ;
0 commit comments