@@ -499,13 +499,40 @@ impl Builder {
499499        let  output_capture = crate :: io:: set_output_capture ( None ) ; 
500500        crate :: io:: set_output_capture ( output_capture. clone ( ) ) ; 
501501
502+         // Pass `f` in `MaybeUninit` because actually that closure might *run longer than the lifetime of `F`*. 
503+         // See <https://github.com/rust-lang/rust/issues/101983> for more details. 
504+         // To prevent leaks we use a wrapper that drops its contents. 
505+         #[ repr( transparent) ]  
506+         struct  MaybeDangling < T > ( mem:: MaybeUninit < T > ) ; 
507+         impl < T >  MaybeDangling < T >  { 
508+             fn  new ( x :  T )  -> Self  { 
509+                 MaybeDangling ( mem:: MaybeUninit :: new ( x) ) 
510+             } 
511+             fn  into_inner ( self )  -> T  { 
512+                 // SAFETY: we are always initiailized. 
513+                 let  ret = unsafe  {  self . 0 . assume_init_read ( )  } ; 
514+                 // Make sure we don't drop. 
515+                 mem:: forget ( self ) ; 
516+                 ret
517+             } 
518+         } 
519+         impl < T >  Drop  for  MaybeDangling < T >  { 
520+             fn  drop ( & mut  self )  { 
521+                 // SAFETY: we are always initiailized. 
522+                 unsafe  {  self . 0 . assume_init_drop ( )  } ; 
523+             } 
524+         } 
525+ 
526+         let  f = MaybeDangling :: new ( f) ; 
502527        let  main = move  || { 
503528            if  let  Some ( name)  = their_thread. cname ( )  { 
504529                imp:: Thread :: set_name ( name) ; 
505530            } 
506531
507532            crate :: io:: set_output_capture ( output_capture) ; 
508533
534+             // SAFETY: we constructed `f` initialized. 
535+             let  f = f. into_inner ( ) ; 
509536            // SAFETY: the stack guard passed is the one for the current thread. 
510537            // This means the current thread's stack and the new thread's stack 
511538            // are properly set and protected from each other. 
@@ -518,6 +545,12 @@ impl Builder {
518545            // same `JoinInner` as this closure meaning the mutation will be 
519546            // safe (not modify it and affect a value far away). 
520547            unsafe  {  * their_packet. result . get ( )  = Some ( try_result)  } ; 
548+             // Here `their_packet` gets dropped, and if this is the last `Arc` for that packet that 
549+             // will call `decrement_num_running_threads` and therefore signal that this thread is 
550+             // done. 
551+             drop ( their_packet) ; 
552+             // Here, the lifetime `'a` and even `'scope` can end. `main` keeps running for a bit 
553+             // after that before returning itself. 
521554        } ; 
522555
523556        if  let  Some ( scope_data)  = & my_packet. scope  { 
0 commit comments