@@ -47,7 +47,10 @@ use std::cell::RefCell;
47
47
use std:: ffi:: OsString ;
48
48
use std:: io:: { self , BufWriter , Write } ;
49
49
use std:: lazy:: SyncLazy ;
50
+ use std:: marker:: PhantomData ;
51
+ use std:: ops:: { Generator , GeneratorState } ;
50
52
use std:: path:: PathBuf ;
53
+ use std:: pin:: Pin ;
51
54
use std:: rc:: Rc ;
52
55
use std:: { env, fs, iter} ;
53
56
@@ -85,27 +88,85 @@ fn count_nodes(krate: &ast::Crate) -> usize {
85
88
counter. count
86
89
}
87
90
91
+ #[ derive( Copy , Clone ) ]
92
+ pub struct AccessAction ( * mut dyn FnMut ( ) ) ;
93
+
94
+ impl AccessAction {
95
+ pub fn get ( self ) -> * mut dyn FnMut ( ) {
96
+ self . 0
97
+ }
98
+ }
99
+
100
+ #[ derive( Copy , Clone ) ]
101
+ pub enum Action {
102
+ Initial ,
103
+ Access ( AccessAction ) ,
104
+ Complete ,
105
+ }
106
+
107
+ pub struct PinnedGenerator < I , A , R > {
108
+ generator : Pin < Box < dyn Generator < Action , Yield = YieldType < I , A > , Return = R > > > ,
109
+ }
110
+
111
+ impl < I , A , R > PinnedGenerator < I , A , R > {
112
+ pub fn new < T : Generator < Action , Yield = YieldType < I , A > , Return = R > + ' static > (
113
+ generator : T ,
114
+ ) -> ( I , Self ) {
115
+ let mut result = PinnedGenerator { generator : Box :: pin ( generator) } ;
116
+
117
+ // Run it to the first yield to set it up
118
+ let init = match Pin :: new ( & mut result. generator ) . resume ( Action :: Initial ) {
119
+ GeneratorState :: Yielded ( YieldType :: Initial ( y) ) => y,
120
+ _ => panic ! ( ) ,
121
+ } ;
122
+
123
+ ( init, result)
124
+ }
125
+
126
+ pub unsafe fn access ( & mut self , closure : * mut dyn FnMut ( ) ) {
127
+ // Call the generator, which in turn will call the closure
128
+ if let GeneratorState :: Complete ( _) =
129
+ Pin :: new ( & mut self . generator ) . resume ( Action :: Access ( AccessAction ( closure) ) )
130
+ {
131
+ panic ! ( )
132
+ }
133
+ }
134
+
135
+ pub fn complete ( & mut self ) -> R {
136
+ // Tell the generator we want it to complete, consuming it and yielding a result
137
+ let result = Pin :: new ( & mut self . generator ) . resume ( Action :: Complete ) ;
138
+ if let GeneratorState :: Complete ( r) = result { r } else { panic ! ( ) }
139
+ }
140
+ }
141
+
142
+ #[ derive( PartialEq ) ]
143
+ pub struct Marker < T > ( PhantomData < T > ) ;
144
+
145
+ impl < T > Marker < T > {
146
+ pub unsafe fn new ( ) -> Self {
147
+ Marker ( PhantomData )
148
+ }
149
+ }
150
+
151
+ pub enum YieldType < I , A > {
152
+ Initial ( I ) ,
153
+ Accessor ( Marker < A > ) ,
154
+ }
155
+
88
156
pub struct BoxedResolver (
89
- rustc_data_structures:: box_region:: PinnedGenerator <
90
- Result < ast:: Crate > ,
91
- fn ( & mut Resolver < ' _ > ) ,
92
- ResolverOutputs ,
93
- > ,
157
+ PinnedGenerator < Result < ast:: Crate > , fn ( & mut Resolver < ' _ > ) , ResolverOutputs > ,
94
158
) ;
95
159
96
160
impl BoxedResolver {
97
161
fn new < T > ( generator : T ) -> ( Result < ast:: Crate > , Self )
98
162
where
99
163
T : :: std:: ops:: Generator <
100
- rustc_data_structures:: box_region:: Action ,
101
- Yield = rustc_data_structures:: box_region:: YieldType <
102
- Result < ast:: Crate > ,
103
- fn ( & mut Resolver < ' _ > ) ,
104
- > ,
164
+ Action ,
165
+ Yield = YieldType < Result < ast:: Crate > , fn ( & mut Resolver < ' _ > ) > ,
105
166
Return = ResolverOutputs ,
106
167
> + ' static ,
107
168
{
108
- let ( initial, pinned) = rustc_data_structures :: box_region :: PinnedGenerator :: new ( generator) ;
169
+ let ( initial, pinned) = PinnedGenerator :: new ( generator) ;
109
170
( initial, BoxedResolver ( pinned) )
110
171
}
111
172
@@ -135,9 +196,8 @@ impl BoxedResolver {
135
196
136
197
fn initial_yield (
137
198
value : Result < ast:: Crate > ,
138
- ) -> rustc_data_structures:: box_region:: YieldType < Result < ast:: Crate > , fn ( & mut Resolver < ' _ > ) >
139
- {
140
- rustc_data_structures:: box_region:: YieldType :: Initial ( value)
199
+ ) -> YieldType < Result < ast:: Crate > , fn ( & mut Resolver < ' _ > ) > {
200
+ YieldType :: Initial ( value)
141
201
}
142
202
}
143
203
@@ -186,20 +246,17 @@ pub fn configure_and_expand(
186
246
187
247
loop {
188
248
match action {
189
- rustc_data_structures :: box_region :: Action :: Access ( accessor) => {
249
+ Action :: Access ( accessor) => {
190
250
let accessor: & mut dyn FnMut ( & mut Resolver < ' _ > ) =
191
251
unsafe { :: std:: mem:: transmute ( accessor. get ( ) ) } ;
192
252
( * accessor) ( & mut resolver) ;
193
253
unsafe {
194
- let marker = rustc_data_structures:: box_region:: Marker :: <
195
- fn ( & mut Resolver < ' _ > ) ,
196
- > :: new ( ) ;
197
- action =
198
- yield rustc_data_structures:: box_region:: YieldType :: Accessor ( marker) ;
254
+ let marker = Marker :: < fn ( & mut Resolver < ' _ > ) > :: new ( ) ;
255
+ action = yield YieldType :: Accessor ( marker) ;
199
256
} ;
200
257
}
201
- rustc_data_structures :: box_region :: Action :: Complete => break ,
202
- rustc_data_structures :: box_region :: Action :: Initial => {
258
+ Action :: Complete => break ,
259
+ Action :: Initial => {
203
260
panic ! ( "unexpected box_region action: Initial" )
204
261
}
205
262
}
0 commit comments