@@ -46,8 +46,7 @@ use std::cell::RefCell;
4646use std:: ffi:: OsString ;
4747use std:: io:: { self , BufWriter , Write } ;
4848use std:: lazy:: SyncLazy ;
49- use std:: marker:: PhantomData ;
50- use std:: ops:: { Generator , GeneratorState } ;
49+ use std:: marker:: PhantomPinned ;
5150use std:: path:: PathBuf ;
5251use std:: pin:: Pin ;
5352use std:: rc:: Rc ;
@@ -87,99 +86,64 @@ fn count_nodes(krate: &ast::Crate) -> usize {
8786 counter. count
8887}
8988
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 ,
128100}
129101
130102impl 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 ) >
132104 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 > ) > ,
138109 {
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+ }
148127 }
149128
150129 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 )
158132 } ;
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 ( ) )
175134 }
176135
177136 pub fn to_resolver_outputs ( resolver : Rc < RefCell < BoxedResolver > > ) -> ResolverOutputs {
178137 match Rc :: try_unwrap ( resolver) {
179138 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 ( )
183147 }
184148 Err ( resolver) => resolver. borrow_mut ( ) . access ( |resolver| resolver. clone_outputs ( ) ) ,
185149 }
@@ -206,48 +170,15 @@ pub fn configure_and_expand(
206170 // its contents but the results of name resolution on those contents. Hopefully we'll push
207171 // this back at some point.
208172 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 (
214175 sess,
215176 & lint_store,
216177 krate,
217178 & crate_name,
218179 & resolver_arenas,
219180 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+ )
251182 } )
252183}
253184
0 commit comments