@@ -6,10 +6,10 @@ use rustc_ast::mut_visit::MutVisitor;
6
6
use rustc_ast:: { self as ast, visit} ;
7
7
use rustc_codegen_ssa:: back:: link:: emit_metadata;
8
8
use rustc_codegen_ssa:: traits:: CodegenBackend ;
9
+ use rustc_data_structures:: parallel;
9
10
use rustc_data_structures:: steal:: Steal ;
10
11
use rustc_data_structures:: sync:: { par_iter, Lrc , OnceCell , ParallelIterator , WorkerLocal } ;
11
12
use rustc_data_structures:: temp_dir:: MaybeTempDir ;
12
- use rustc_data_structures:: { box_region_allow_access, declare_box_region_type, parallel} ;
13
13
use rustc_errors:: { ErrorReported , PResult } ;
14
14
use rustc_expand:: base:: ExtCtxt ;
15
15
use rustc_hir:: def_id:: LOCAL_CRATE ;
@@ -47,7 +47,9 @@ 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:: PhantomPinned ;
50
51
use std:: path:: PathBuf ;
52
+ use std:: pin:: Pin ;
51
53
use std:: rc:: Rc ;
52
54
use std:: { env, fs, iter} ;
53
55
@@ -85,11 +87,83 @@ fn count_nodes(krate: &ast::Crate) -> usize {
85
87
counter. count
86
88
}
87
89
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
+ }
93
167
94
168
/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
95
169
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
@@ -111,41 +185,16 @@ pub fn configure_and_expand(
111
185
// its contents but the results of name resolution on those contents. Hopefully we'll push
112
186
// this back at some point.
113
187
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 (
119
190
sess,
120
191
& lint_store,
121
192
krate,
122
193
& crate_name,
123
194
& 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
+ } )
149
198
}
150
199
151
200
pub fn register_plugins < ' a > (
@@ -231,11 +280,11 @@ fn pre_expansion_lint(
231
280
232
281
fn configure_and_expand_inner < ' a > (
233
282
sess : & ' a Session ,
234
- lint_store : & ' a LintStore ,
283
+ lint_store : & LintStore ,
235
284
mut krate : ast:: Crate ,
236
285
crate_name : & str ,
237
286
resolver_arenas : & ' a ResolverArenas < ' a > ,
238
- metadata_loader : & ' a MetadataLoaderDyn ,
287
+ metadata_loader : Box < MetadataLoaderDyn > ,
239
288
) -> Result < ( ast:: Crate , Resolver < ' a > ) > {
240
289
tracing:: trace!( "configure_and_expand_inner" ) ;
241
290
pre_expansion_lint ( sess, lint_store, & krate, crate_name) ;
0 commit comments