@@ -46,8 +46,7 @@ use std::cell::RefCell;
46
46
use std:: ffi:: OsString ;
47
47
use std:: io:: { self , BufWriter , Write } ;
48
48
use std:: lazy:: SyncLazy ;
49
- use std:: marker:: PhantomData ;
50
- use std:: ops:: { Generator , GeneratorState } ;
49
+ use std:: marker:: PhantomPinned ;
51
50
use std:: path:: PathBuf ;
52
51
use std:: pin:: Pin ;
53
52
use std:: rc:: Rc ;
@@ -87,99 +86,64 @@ fn count_nodes(krate: &ast::Crate) -> usize {
87
86
counter. count
88
87
}
89
88
90
- pub struct AccessAction ( * mut dyn for < ' a > FnMut ( & mut Resolver < ' a > ) ) ;
91
-
92
- impl AccessAction {
93
- pub fn get ( self ) -> * mut dyn for < ' a > FnMut ( & mut Resolver < ' a > ) {
94
- self . 0
95
- }
96
- }
97
-
98
- pub enum Action {
99
- Initial ,
100
- Access ( AccessAction ) ,
101
- Complete ,
102
- }
103
-
104
- #[ derive( PartialEq ) ]
105
- struct Marker < T > ( PhantomData < T > ) ;
106
-
107
- impl < T > Marker < T > {
108
- unsafe fn new ( ) -> Self {
109
- Marker ( PhantomData )
110
- }
111
- }
112
-
113
- enum YieldType < I , A > {
114
- Initial ( I ) ,
115
- Accessor ( Marker < A > ) ,
116
- }
117
-
118
- pub struct BoxedResolver {
119
- generator : Pin <
120
- Box <
121
- dyn Generator <
122
- Action ,
123
- Yield = YieldType < Result < ast:: Crate > , for <' a > fn ( & mut Resolver < ' a > ) > ,
124
- Return = ResolverOutputs ,
125
- > ,
126
- > ,
127
- > ,
89
+ pub struct BoxedResolver ( Pin < Box < BoxedResolverInner > > ) ;
90
+
91
+ // Note: Drop order is important to prevent dangling references. Resolver must be dropped first,
92
+ // then resolver_arenas and finally session.
93
+ // The drop order is defined to be from top to bottom in RFC1857, so there is no need for
94
+ // ManuallyDrop for as long as the fields are not reordered.
95
+ struct BoxedResolverInner {
96
+ resolver : Option < Resolver < ' static > > ,
97
+ resolver_arenas : ResolverArenas < ' static > ,
98
+ session : Lrc < Session > ,
99
+ _pin : PhantomPinned ,
128
100
}
129
101
130
102
impl BoxedResolver {
131
- fn new < T > ( generator : T ) -> Result < ( ast:: Crate , Self ) >
103
+ fn new < F > ( session : Lrc < Session > , make_resolver : F ) -> Result < ( ast:: Crate , Self ) >
132
104
where
133
- T : :: std:: ops:: Generator <
134
- Action ,
135
- Yield = YieldType < Result < ast:: Crate > , fn ( & mut Resolver < ' _ > ) > ,
136
- Return = ResolverOutputs ,
137
- > + ' static ,
105
+ F : for < ' a > FnOnce (
106
+ & ' a Session ,
107
+ & ' a ResolverArenas < ' a > ,
108
+ ) -> Result < ( ast:: Crate , Resolver < ' a > ) > ,
138
109
{
139
- let mut generator = Box :: pin ( generator) ;
140
-
141
- // Run it to the first yield to set it up
142
- let init = match generator. as_mut ( ) . resume ( Action :: Initial ) {
143
- GeneratorState :: Yielded ( YieldType :: Initial ( y) ) => y,
144
- _ => panic ! ( ) ,
145
- } ;
146
-
147
- init. map ( |init| ( init, BoxedResolver { generator } ) )
110
+ let mut boxed_resolver = Box :: new ( BoxedResolverInner {
111
+ session,
112
+ resolver_arenas : Resolver :: arenas ( ) ,
113
+ resolver : None ,
114
+ _pin : PhantomPinned ,
115
+ } ) ;
116
+ unsafe {
117
+ let ( crate_, resolver) = make_resolver (
118
+ std:: mem:: transmute :: < & Session , & Session > ( & boxed_resolver. session ) ,
119
+ std:: mem:: transmute :: < & ResolverArenas < ' _ > , & ResolverArenas < ' _ > > (
120
+ & boxed_resolver. resolver_arenas ,
121
+ ) ,
122
+ ) ?;
123
+ boxed_resolver. resolver =
124
+ Some ( std:: mem:: transmute :: < Resolver < ' _ > , Resolver < ' _ > > ( resolver) ) ;
125
+ Ok ( ( crate_, BoxedResolver ( Pin :: new_unchecked ( boxed_resolver) ) ) )
126
+ }
148
127
}
149
128
150
129
pub fn access < F : for < ' a > FnOnce ( & mut Resolver < ' a > ) -> R , R > ( & mut self , f : F ) -> R {
151
- // Turn the FnOnce closure into *mut dyn FnMut()
152
- // so we can pass it in to the generator
153
- let mut r = None ;
154
- let mut f = Some ( f) ;
155
- let mut_f: & mut dyn for < ' a > FnMut ( & mut Resolver < ' a > ) = & mut |resolver| {
156
- let f = f. take ( ) . unwrap ( ) ;
157
- r = Some ( f ( resolver) ) ;
130
+ let mut resolver = unsafe {
131
+ self . 0 . as_mut ( ) . map_unchecked_mut ( |boxed_resolver| & mut boxed_resolver. resolver )
158
132
} ;
159
- let mut_f = mut_f as * mut dyn for < ' a > FnMut ( & mut Resolver < ' a > ) ;
160
-
161
- // Get the generator to call our closure
162
- unsafe {
163
- // Call the generator, which in turn will call the closure
164
- if let GeneratorState :: Complete ( _) = self
165
- . generator
166
- . as_mut ( )
167
- . resume ( Action :: Access ( AccessAction ( :: std:: mem:: transmute ( mut_f) ) ) )
168
- {
169
- panic ! ( )
170
- }
171
- }
172
-
173
- // Unwrap the result
174
- r. unwrap ( )
133
+ f ( ( & mut * resolver) . as_mut ( ) . unwrap ( ) )
175
134
}
176
135
177
136
pub fn to_resolver_outputs ( resolver : Rc < RefCell < BoxedResolver > > ) -> ResolverOutputs {
178
137
match Rc :: try_unwrap ( resolver) {
179
138
Ok ( resolver) => {
180
- // Tell the generator we want it to complete, consuming it and yielding a result
181
- let result = resolver. into_inner ( ) . generator . as_mut ( ) . resume ( Action :: Complete ) ;
182
- if let GeneratorState :: Complete ( r) = result { r } else { panic ! ( ) }
139
+ let mut resolver = resolver. into_inner ( ) ;
140
+ let mut resolver = unsafe {
141
+ resolver
142
+ . 0
143
+ . as_mut ( )
144
+ . map_unchecked_mut ( |boxed_resolver| & mut boxed_resolver. resolver )
145
+ } ;
146
+ resolver. take ( ) . unwrap ( ) . into_outputs ( )
183
147
}
184
148
Err ( resolver) => resolver. borrow_mut ( ) . access ( |resolver| resolver. clone_outputs ( ) ) ,
185
149
}
@@ -206,48 +170,15 @@ pub fn configure_and_expand(
206
170
// its contents but the results of name resolution on those contents. Hopefully we'll push
207
171
// this back at some point.
208
172
let crate_name = crate_name. to_string ( ) ;
209
- BoxedResolver :: new ( static move |mut action| {
210
- let _ = action;
211
- let sess = & * sess;
212
- let resolver_arenas = Resolver :: arenas ( ) ;
213
- let res = configure_and_expand_inner (
173
+ BoxedResolver :: new ( sess, move |sess, resolver_arenas| {
174
+ configure_and_expand_inner (
214
175
sess,
215
176
& lint_store,
216
177
krate,
217
178
& crate_name,
218
179
& resolver_arenas,
219
180
metadata_loader,
220
- ) ;
221
- let mut resolver = match res {
222
- Err ( v) => {
223
- yield YieldType :: Initial ( Err ( v) ) ;
224
- panic ! ( )
225
- }
226
- Ok ( ( krate, resolver) ) => {
227
- action = yield YieldType :: Initial ( Ok ( krate) ) ;
228
- resolver
229
- }
230
- } ;
231
-
232
- loop {
233
- match action {
234
- Action :: Access ( accessor) => {
235
- let accessor: & mut dyn FnMut ( & mut Resolver < ' _ > ) =
236
- unsafe { :: std:: mem:: transmute ( accessor. get ( ) ) } ;
237
- ( * accessor) ( & mut resolver) ;
238
- unsafe {
239
- let marker = Marker :: < fn ( & mut Resolver < ' _ > ) > :: new ( ) ;
240
- action = yield YieldType :: Accessor ( marker) ;
241
- } ;
242
- }
243
- Action :: Complete => break ,
244
- Action :: Initial => {
245
- panic ! ( "unexpected box_region action: Initial" )
246
- }
247
- }
248
- }
249
-
250
- resolver. into_outputs ( )
181
+ )
251
182
} )
252
183
}
253
184
0 commit comments