@@ -6,10 +6,10 @@ use rustc_ast::mut_visit::MutVisitor;
66use rustc_ast:: { self as ast, visit} ;
77use rustc_codegen_ssa:: back:: link:: emit_metadata;
88use rustc_codegen_ssa:: traits:: CodegenBackend ;
9+ use rustc_data_structures:: parallel;
910use rustc_data_structures:: steal:: Steal ;
1011use rustc_data_structures:: sync:: { par_iter, Lrc , OnceCell , ParallelIterator , WorkerLocal } ;
1112use rustc_data_structures:: temp_dir:: MaybeTempDir ;
12- use rustc_data_structures:: { box_region_allow_access, declare_box_region_type, parallel} ;
1313use rustc_errors:: { ErrorReported , PResult } ;
1414use rustc_expand:: base:: ExtCtxt ;
1515use rustc_hir:: def_id:: LOCAL_CRATE ;
@@ -47,7 +47,9 @@ use std::cell::RefCell;
4747use std:: ffi:: OsString ;
4848use std:: io:: { self , BufWriter , Write } ;
4949use std:: lazy:: SyncLazy ;
50+ use std:: marker:: PhantomPinned ;
5051use std:: path:: PathBuf ;
52+ use std:: pin:: Pin ;
5153use std:: rc:: Rc ;
5254use std:: { env, fs, iter} ;
5355
@@ -85,11 +87,83 @@ fn count_nodes(krate: &ast::Crate) -> usize {
8587 counter. count
8688}
8789
88- declare_box_region_type ! (
89- pub BoxedResolver ,
90- for ( ) ,
91- ( & mut Resolver <' _>) -> ( Result <ast:: Crate >, ResolverOutputs )
92- ) ;
90+ pub use boxed_resolver:: BoxedResolver ;
91+ mod boxed_resolver {
92+ use super :: * ;
93+
94+ pub struct BoxedResolver ( Pin < Box < BoxedResolverInner > > ) ;
95+
96+ struct BoxedResolverInner {
97+ session : Lrc < Session > ,
98+ resolver_arenas : Option < ResolverArenas < ' static > > ,
99+ resolver : Option < Resolver < ' static > > ,
100+ _pin : PhantomPinned ,
101+ }
102+
103+ // Note: Drop order is important to prevent dangling references. Resolver must be dropped first,
104+ // then resolver_arenas and finally session.
105+ impl Drop for BoxedResolverInner {
106+ fn drop ( & mut self ) {
107+ self . resolver . take ( ) ;
108+ self . resolver_arenas . take ( ) ;
109+ }
110+ }
111+
112+ impl BoxedResolver {
113+ pub ( super ) fn new < F > ( session : Lrc < Session > , make_resolver : F ) -> Result < ( ast:: Crate , Self ) >
114+ where
115+ F : for < ' a > FnOnce (
116+ & ' a Session ,
117+ & ' a ResolverArenas < ' a > ,
118+ ) -> Result < ( ast:: Crate , Resolver < ' a > ) > ,
119+ {
120+ let mut boxed_resolver = Box :: new ( BoxedResolverInner {
121+ session,
122+ resolver_arenas : Some ( Resolver :: arenas ( ) ) ,
123+ resolver : None ,
124+ _pin : PhantomPinned ,
125+ } ) ;
126+ // SAFETY: `make_resolver` takes a resolver arena with an arbitrary lifetime and
127+ // returns a resolver with the same lifetime as the arena. We ensure that the arena
128+ // outlives the resolver in the drop impl and elsewhere so these transmutes are sound.
129+ unsafe {
130+ let ( crate_, resolver) = make_resolver (
131+ std:: mem:: transmute :: < & Session , & Session > ( & boxed_resolver. session ) ,
132+ std:: mem:: transmute :: < & ResolverArenas < ' _ > , & ResolverArenas < ' _ > > (
133+ boxed_resolver. resolver_arenas . as_ref ( ) . unwrap ( ) ,
134+ ) ,
135+ ) ?;
136+ boxed_resolver. resolver = Some ( resolver) ;
137+ Ok ( ( crate_, BoxedResolver ( Pin :: new_unchecked ( boxed_resolver) ) ) )
138+ }
139+ }
140+
141+ pub fn access < F : for < ' a > FnOnce ( & mut Resolver < ' a > ) -> R , R > ( & mut self , f : F ) -> R {
142+ // SAFETY: The resolver doesn't need to be pinned.
143+ let mut resolver = unsafe {
144+ self . 0 . as_mut ( ) . map_unchecked_mut ( |boxed_resolver| & mut boxed_resolver. resolver )
145+ } ;
146+ f ( ( & mut * resolver) . as_mut ( ) . unwrap ( ) )
147+ }
148+
149+ pub fn to_resolver_outputs ( resolver : Rc < RefCell < BoxedResolver > > ) -> ResolverOutputs {
150+ match Rc :: try_unwrap ( resolver) {
151+ Ok ( resolver) => {
152+ let mut resolver = resolver. into_inner ( ) ;
153+ // SAFETY: The resolver doesn't need to be pinned.
154+ let mut resolver = unsafe {
155+ resolver
156+ . 0
157+ . as_mut ( )
158+ . map_unchecked_mut ( |boxed_resolver| & mut boxed_resolver. resolver )
159+ } ;
160+ resolver. take ( ) . unwrap ( ) . into_outputs ( )
161+ }
162+ Err ( resolver) => resolver. borrow_mut ( ) . access ( |resolver| resolver. clone_outputs ( ) ) ,
163+ }
164+ }
165+ }
166+ }
93167
94168/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
95169/// syntax expansion, secondary `cfg` expansion, synthesis of a test
@@ -111,41 +185,16 @@ pub fn configure_and_expand(
111185 // its contents but the results of name resolution on those contents. Hopefully we'll push
112186 // this back at some point.
113187 let crate_name = crate_name. to_string ( ) ;
114- let ( result, resolver) = BoxedResolver :: new ( static move |mut action| {
115- let _ = action;
116- let sess = & * sess;
117- let resolver_arenas = Resolver :: arenas ( ) ;
118- let res = configure_and_expand_inner (
188+ BoxedResolver :: new ( sess, move |sess, resolver_arenas| {
189+ configure_and_expand_inner (
119190 sess,
120191 & lint_store,
121192 krate,
122193 & crate_name,
123194 & resolver_arenas,
124- & * metadata_loader,
125- ) ;
126- let mut resolver = match res {
127- Err ( v) => {
128- yield BoxedResolver :: initial_yield ( Err ( v) ) ;
129- panic ! ( )
130- }
131- Ok ( ( krate, resolver) ) => {
132- action = yield BoxedResolver :: initial_yield ( Ok ( krate) ) ;
133- resolver
134- }
135- } ;
136- box_region_allow_access ! ( for ( ) , ( & mut Resolver <' _>) , ( & mut resolver) , action) ;
137- resolver. into_outputs ( )
138- } ) ;
139- result. map ( |k| ( k, resolver) )
140- }
141-
142- impl BoxedResolver {
143- pub fn to_resolver_outputs ( resolver : Rc < RefCell < BoxedResolver > > ) -> ResolverOutputs {
144- match Rc :: try_unwrap ( resolver) {
145- Ok ( resolver) => resolver. into_inner ( ) . complete ( ) ,
146- Err ( resolver) => resolver. borrow_mut ( ) . access ( |resolver| resolver. clone_outputs ( ) ) ,
147- }
148- }
195+ metadata_loader,
196+ )
197+ } )
149198}
150199
151200pub fn register_plugins < ' a > (
@@ -231,11 +280,11 @@ fn pre_expansion_lint(
231280
232281fn configure_and_expand_inner < ' a > (
233282 sess : & ' a Session ,
234- lint_store : & ' a LintStore ,
283+ lint_store : & LintStore ,
235284 mut krate : ast:: Crate ,
236285 crate_name : & str ,
237286 resolver_arenas : & ' a ResolverArenas < ' a > ,
238- metadata_loader : & ' a MetadataLoaderDyn ,
287+ metadata_loader : Box < MetadataLoaderDyn > ,
239288) -> Result < ( ast:: Crate , Resolver < ' a > ) > {
240289 tracing:: trace!( "configure_and_expand_inner" ) ;
241290 pre_expansion_lint ( sess, lint_store, & krate, crate_name) ;
0 commit comments