1
- use std:: cell:: Cell ;
2
1
use std:: marker:: PhantomData ;
3
2
use std:: ops:: { Generator , GeneratorState } ;
4
3
use std:: pin:: Pin ;
@@ -14,24 +13,23 @@ impl AccessAction {
14
13
15
14
#[ derive( Copy , Clone ) ]
16
15
pub enum Action {
16
+ Initial ,
17
17
Access ( AccessAction ) ,
18
18
Complete ,
19
19
}
20
20
21
- thread_local ! ( pub static BOX_REGION_ARG : Cell <Action > = Cell :: new( Action :: Complete ) ) ;
22
-
23
21
pub 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 > > > ,
25
23
}
26
24
27
25
impl < 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 > (
29
27
generator : T ,
30
28
) -> ( I , Self ) {
31
29
let mut result = PinnedGenerator { generator : Box :: pin ( generator) } ;
32
30
33
31
// 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 ) {
35
33
GeneratorState :: Yielded ( YieldType :: Initial ( y) ) => y,
36
34
_ => panic ! ( ) ,
37
35
} ;
@@ -40,21 +38,17 @@ impl<I, A, R> PinnedGenerator<I, A, R> {
40
38
}
41
39
42
40
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
+ {
49
45
panic ! ( )
50
46
}
51
47
}
52
48
53
49
pub fn complete ( & mut self ) -> R {
54
50
// 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 ) ;
58
52
if let GeneratorState :: Complete ( r) = result { r } else { panic ! ( ) }
59
53
}
60
54
}
@@ -89,7 +83,7 @@ macro_rules! declare_box_region_type {
89
83
>) ;
90
84
91
85
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 >(
93
87
generator: T
94
88
) -> ( $reti, Self ) {
95
89
let ( initial, pinned) = $crate:: box_region:: PinnedGenerator :: new( generator) ;
@@ -98,7 +92,7 @@ macro_rules! declare_box_region_type {
98
92
99
93
$v fn access<F : for <$( $lifetimes) * > FnOnce ( $( $args, ) * ) -> R , R >( & mut self , f: F ) -> R {
100
94
// 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
102
96
let mut r = None ;
103
97
let mut f = Some ( f) ;
104
98
let mut_f: & mut dyn for <$( $lifetimes) * > FnMut ( ( $( $args, ) * ) ) =
@@ -140,9 +134,9 @@ macro_rules! declare_box_region_type {
140
134
#[ macro_export]
141
135
#[ allow_internal_unstable( fn_traits) ]
142
136
macro_rules! box_region_allow_access {
143
- ( for ( $( $lifetimes: tt) * ) , ( $( $args: ty) ,* ) , ( $( $exprs: expr) ,* ) ) => {
137
+ ( for ( $( $lifetimes: tt) * ) , ( $( $args: ty) ,* ) , ( $( $exprs: expr) ,* ) , $action : ident ) => {
144
138
loop {
145
- match $crate :: box_region :: BOX_REGION_ARG . with ( |i| i . get ( ) ) {
139
+ match $action {
146
140
$crate:: box_region:: Action :: Access ( accessor) => {
147
141
let accessor: & mut dyn for <$( $lifetimes) * > FnMut ( $( $args) ,* ) = unsafe {
148
142
:: std:: mem:: transmute( accessor. get( ) )
@@ -152,10 +146,11 @@ macro_rules! box_region_allow_access {
152
146
let marker = $crate:: box_region:: Marker :: <
153
147
for <$( $lifetimes) * > fn ( ( $( $args, ) * ) )
154
148
>:: new( ) ;
155
- yield $crate:: box_region:: YieldType :: Accessor ( marker)
149
+ $action = yield $crate:: box_region:: YieldType :: Accessor ( marker) ;
156
150
} ;
157
151
}
158
152
$crate:: box_region:: Action :: Complete => break ,
153
+ $crate:: box_region:: Action :: Initial => panic!( ) ,
159
154
}
160
155
}
161
156
}
0 commit comments