1- use std:: cell:: Cell ;
21use std:: marker:: PhantomData ;
32use std:: ops:: { Generator , GeneratorState } ;
43use std:: pin:: Pin ;
@@ -14,24 +13,23 @@ impl AccessAction {
1413
1514#[ derive( Copy , Clone ) ]
1615pub enum Action {
16+ Initial ,
1717 Access ( AccessAction ) ,
1818 Complete ,
1919}
2020
21- thread_local ! ( pub static BOX_REGION_ARG : Cell <Action > = Cell :: new( Action :: Complete ) ) ;
22-
2321pub struct PinnedGenerator < I , A , R > {
24- generator : Pin < Box < dyn Generator < Yield = YieldType < I , A > , Return = R > > > ,
22+ generator : Pin < Box < dyn Generator < Action , Yield = YieldType < I , A > , Return = R > > > ,
2523}
2624
2725impl < I , A , R > PinnedGenerator < I , A , R > {
28- pub fn new < T : Generator < Yield = YieldType < I , A > , Return = R > + ' static > (
26+ pub fn new < T : Generator < Action , Yield = YieldType < I , A > , Return = R > + ' static > (
2927 generator : T ,
3028 ) -> ( I , Self ) {
3129 let mut result = PinnedGenerator { generator : Box :: pin ( generator) } ;
3230
3331 // Run it to the first yield to set it up
34- let init = match Pin :: new ( & mut result. generator ) . resume ( ( ) ) {
32+ let init = match Pin :: new ( & mut result. generator ) . resume ( Action :: Initial ) {
3533 GeneratorState :: Yielded ( YieldType :: Initial ( y) ) => y,
3634 _ => panic ! ( ) ,
3735 } ;
@@ -40,21 +38,17 @@ impl<I, A, R> PinnedGenerator<I, A, R> {
4038 }
4139
4240 pub unsafe fn access ( & mut self , closure : * mut dyn FnMut ( ) ) {
43- BOX_REGION_ARG . with ( |i| {
44- i. set ( Action :: Access ( AccessAction ( closure) ) ) ;
45- } ) ;
46-
47- // Call the generator, which in turn will call the closure in BOX_REGION_ARG
48- if let GeneratorState :: Complete ( _) = Pin :: new ( & mut self . generator ) . resume ( ( ) ) {
41+ // Call the generator, which in turn will call the closure
42+ if let GeneratorState :: Complete ( _) =
43+ Pin :: new ( & mut self . generator ) . resume ( Action :: Access ( AccessAction ( closure) ) )
44+ {
4945 panic ! ( )
5046 }
5147 }
5248
5349 pub fn complete ( & mut self ) -> R {
5450 // Tell the generator we want it to complete, consuming it and yielding a result
55- BOX_REGION_ARG . with ( |i| i. set ( Action :: Complete ) ) ;
56-
57- let result = Pin :: new ( & mut self . generator ) . resume ( ( ) ) ;
51+ let result = Pin :: new ( & mut self . generator ) . resume ( Action :: Complete ) ;
5852 if let GeneratorState :: Complete ( r) = result { r } else { panic ! ( ) }
5953 }
6054}
@@ -89,7 +83,7 @@ macro_rules! declare_box_region_type {
8983 >) ;
9084
9185 impl $name {
92- fn new<T : :: std:: ops:: Generator <Yield = $yield_type, Return = $retc> + ' static >(
86+ fn new<T : :: std:: ops:: Generator <$crate :: box_region :: Action , Yield = $yield_type, Return = $retc> + ' static >(
9387 generator: T
9488 ) -> ( $reti, Self ) {
9589 let ( initial, pinned) = $crate:: box_region:: PinnedGenerator :: new( generator) ;
@@ -98,7 +92,7 @@ macro_rules! declare_box_region_type {
9892
9993 $v fn access<F : for <$( $lifetimes) * > FnOnce ( $( $args, ) * ) -> R , R >( & mut self , f: F ) -> R {
10094 // Turn the FnOnce closure into *mut dyn FnMut()
101- // so we can pass it in to the generator using the BOX_REGION_ARG thread local
95+ // so we can pass it in to the generator
10296 let mut r = None ;
10397 let mut f = Some ( f) ;
10498 let mut_f: & mut dyn for <$( $lifetimes) * > FnMut ( ( $( $args, ) * ) ) =
@@ -140,9 +134,9 @@ macro_rules! declare_box_region_type {
140134#[ macro_export]
141135#[ allow_internal_unstable( fn_traits) ]
142136macro_rules! box_region_allow_access {
143- ( for ( $( $lifetimes: tt) * ) , ( $( $args: ty) ,* ) , ( $( $exprs: expr) ,* ) ) => {
137+ ( for ( $( $lifetimes: tt) * ) , ( $( $args: ty) ,* ) , ( $( $exprs: expr) ,* ) , $action : ident ) => {
144138 loop {
145- match $crate :: box_region :: BOX_REGION_ARG . with ( |i| i . get ( ) ) {
139+ match $action {
146140 $crate:: box_region:: Action :: Access ( accessor) => {
147141 let accessor: & mut dyn for <$( $lifetimes) * > FnMut ( $( $args) ,* ) = unsafe {
148142 :: std:: mem:: transmute( accessor. get( ) )
@@ -152,10 +146,11 @@ macro_rules! box_region_allow_access {
152146 let marker = $crate:: box_region:: Marker :: <
153147 for <$( $lifetimes) * > fn ( ( $( $args, ) * ) )
154148 >:: new( ) ;
155- yield $crate:: box_region:: YieldType :: Accessor ( marker)
149+ $action = yield $crate:: box_region:: YieldType :: Accessor ( marker) ;
156150 } ;
157151 }
158152 $crate:: box_region:: Action :: Complete => break ,
153+ $crate:: box_region:: Action :: Initial => panic!( ) ,
159154 }
160155 }
161156 }
0 commit comments