@@ -36,6 +36,7 @@ use rustc::session::config::nightly_options;
36
36
use rustc:: session:: { early_error, early_warn} ;
37
37
use rustc:: lint:: Lint ;
38
38
use rustc:: lint;
39
+ use rustc:: ty:: TyCtxt ;
39
40
use rustc:: hir:: def_id:: { LocalCrate , LOCAL_CRATE } ;
40
41
use rustc:: util:: common:: { time, ErrorReported , install_panic_hook} ;
41
42
use rustc_metadata:: locator;
@@ -103,11 +104,19 @@ pub trait Callbacks {
103
104
/// Called before creating the compiler instance
104
105
fn config ( & mut self , _config : & mut interface:: Config ) { }
105
106
/// Called after parsing and returns true to continue execution
106
- fn after_parsing ( & mut self , _compiler : & interface:: Compiler ) -> bool {
107
+ fn after_parsing < ' tcx > (
108
+ & mut self ,
109
+ _compiler : & interface:: Compiler ,
110
+ _tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
111
+ ) -> bool {
107
112
true
108
113
}
109
114
/// Called after analysis and returns true to continue execution
110
- fn after_analysis ( & mut self , _compiler : & interface:: Compiler ) -> bool {
115
+ fn after_analysis < ' tcx > (
116
+ & mut self ,
117
+ _compiler : & interface:: Compiler ,
118
+ _tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
119
+ ) -> bool {
111
120
true
112
121
}
113
122
}
@@ -229,7 +238,8 @@ pub fn run_compiler(
229
238
let pretty_info = parse_pretty ( & mut config. opts , & matches) ;
230
239
231
240
interface:: run_compiler ( config, |compiler| {
232
- let sess = compiler. session ( ) ;
241
+ let sess = compiler. session ( ) . clone ( ) ;
242
+ let sess = & * sess;
233
243
let should_stop = RustcDefaultCalls :: print_crate_info (
234
244
& * * compiler. codegen_backend ( ) ,
235
245
sess,
@@ -247,9 +257,9 @@ pub fn run_compiler(
247
257
return sess. compile_status ( ) ;
248
258
}
249
259
250
- if let Some ( ( ppm , opt_uii ) ) = pretty_info {
251
- if ppm . needs_ast_map ( & opt_uii) {
252
- compiler . enter ( |tcx| {
260
+ let link = compiler . enter ( |compiler , tcx| {
261
+ if let Some ( ( ppm , opt_uii) ) = pretty_info {
262
+ if ppm . needs_ast_map ( & opt_uii ) {
253
263
let expansion_result = tcx. expand_macros ( LocalCrate ) ?;
254
264
pretty:: print_after_hir_lowering (
255
265
tcx,
@@ -259,11 +269,8 @@ pub fn run_compiler(
259
269
opt_uii. clone ( ) ,
260
270
compiler. output_file ( ) . as_ref ( ) . map ( |p| & * * p) ,
261
271
) ;
262
- Ok ( ( ) )
263
- } ) ?;
264
- return sess. compile_status ( ) ;
265
- } else {
266
- compiler. enter ( |tcx| {
272
+ return sess. compile_status ( ) . map ( |_| None ) ;
273
+ } else {
267
274
let krate = tcx. parse ( LocalCrate ) ?;
268
275
let krate = krate. borrow ( ) ;
269
276
pretty:: print_after_parsing (
@@ -273,57 +280,48 @@ pub fn run_compiler(
273
280
ppm,
274
281
compiler. output_file ( ) . as_ref ( ) . map ( |p| & * * p) ,
275
282
) ;
276
- Ok ( ( ) )
277
- } ) ?;
278
- return sess. compile_status ( ) ;
283
+ return sess. compile_status ( ) . map ( |_| None ) ;
284
+ }
279
285
}
280
- }
281
286
282
- compiler . enter ( |tcx| tcx. parse ( LocalCrate ) ) ?;
287
+ tcx. parse ( LocalCrate ) ?;
283
288
284
- if !callbacks. after_parsing ( compiler) {
285
- return sess. compile_status ( ) ;
286
- }
289
+ if !callbacks. after_parsing ( compiler, tcx ) {
290
+ return sess. compile_status ( ) . map ( |_| None ) ;
291
+ }
287
292
288
- if sess. opts . debugging_opts . parse_only ||
289
- sess. opts . debugging_opts . show_span . is_some ( ) ||
290
- sess. opts . debugging_opts . ast_json_noexpand {
291
- return sess. compile_status ( ) ;
292
- }
293
+ if sess. opts . debugging_opts . parse_only ||
294
+ sess. opts . debugging_opts . show_span . is_some ( ) ||
295
+ sess. opts . debugging_opts . ast_json_noexpand {
296
+ return sess. compile_status ( ) . map ( |_| None ) ;
297
+ }
293
298
294
- compiler . enter ( |tcx| tcx. register_plugins ( LocalCrate ) ) ?;
299
+ tcx. register_plugins ( LocalCrate ) ?;
295
300
296
- // Lint plugins are registered; now we can process command line flags.
297
- if sess. opts . describe_lints {
298
- describe_lints ( & sess, & sess. lint_store . borrow ( ) , true ) ;
299
- return sess. compile_status ( ) ;
300
- }
301
+ // Lint plugins are registered; now we can process command line flags.
302
+ if sess. opts . describe_lints {
303
+ describe_lints ( & sess, & sess. lint_store . borrow ( ) , true ) ;
304
+ return sess. compile_status ( ) . map ( |_| None ) ;
305
+ }
301
306
302
- compiler. enter ( |tcx| {
303
307
tcx. prepare_outputs ( LocalCrate ) ?;
304
- Ok ( ( ) )
305
- } ) ?;
306
308
307
- if sess. opts . output_types . contains_key ( & OutputType :: DepInfo )
308
- && sess. opts . output_types . len ( ) == 1
309
- {
310
- return sess. compile_status ( ) ;
311
- }
309
+ if sess. opts . output_types . contains_key ( & OutputType :: DepInfo )
310
+ && sess. opts . output_types . len ( ) == 1
311
+ {
312
+ return sess. compile_status ( ) . map ( |_| None ) ;
313
+ }
312
314
313
- compiler. enter ( |tcx| {
314
315
tcx. lower_ast_to_hir ( LocalCrate ) ?;
315
- Ok ( ( ) )
316
- } ) ?;
317
316
318
- if sess. opts . debugging_opts . no_analysis ||
319
- sess. opts . debugging_opts . ast_json {
320
- return sess. compile_status ( ) ;
321
- }
317
+ if sess. opts . debugging_opts . no_analysis ||
318
+ sess. opts . debugging_opts . ast_json {
319
+ return sess. compile_status ( ) . map ( |_| None ) ;
320
+ }
322
321
323
- if sess. opts . debugging_opts . save_analysis {
324
- compiler. enter ( |tcx| {
322
+ if sess. opts . debugging_opts . save_analysis {
325
323
let expansion_result = tcx. expand_macros ( LocalCrate ) ?;
326
- let result = tcx. analysis ( LOCAL_CRATE ) ;
324
+ tcx. analysis ( LOCAL_CRATE ) . ok ( ) ;
327
325
let crate_name = & tcx. crate_name ( LOCAL_CRATE ) . as_str ( ) ;
328
326
329
327
time ( sess, "save analysis" , || {
@@ -336,41 +334,36 @@ pub fn run_compiler(
336
334
DumpHandler :: new ( compiler. output_dir ( ) . as_ref ( ) . map ( |p| & * * p) , crate_name)
337
335
)
338
336
} ) ;
339
-
340
- result
341
337
// AST will be dropped *after* the `after_analysis` callback
342
338
// (needed by the RLS)
343
- } ) ?;
344
- } else {
345
- compiler. enter ( |tcx| {
339
+ } else {
346
340
// Drop AST after lowering HIR to free memory
347
341
mem:: drop ( tcx. expand_macros ( LocalCrate ) . unwrap ( ) . ast_crate . steal ( ) ) ;
348
- } ) ;
349
- }
342
+ }
350
343
351
- compiler . enter ( |tcx| tcx. analysis ( LOCAL_CRATE ) ) ?;
344
+ tcx. analysis ( LOCAL_CRATE ) ?;
352
345
353
- if !callbacks. after_analysis ( compiler) {
354
- return sess. compile_status ( ) ;
355
- }
346
+ if !callbacks. after_analysis ( compiler, tcx ) {
347
+ return sess. compile_status ( ) . map ( |_| None ) ;
348
+ }
356
349
357
- if sess. opts . debugging_opts . save_analysis {
358
- compiler. enter ( |tcx| {
359
- // Drop AST after lowering HIR to free memory
350
+ if sess. opts . debugging_opts . save_analysis {
351
+ // Drop AST after running `after_analysis` callback to free memory
360
352
mem:: drop ( tcx. expand_macros ( LocalCrate ) . unwrap ( ) . ast_crate . steal ( ) ) ;
361
- } ) ;
362
- }
353
+ }
363
354
364
- compiler. ongoing_codegen ( ) ?;
355
+ compiler. linker ( tcx) . map ( |linker| Some ( linker) )
356
+ } ) ?;
365
357
366
- // Drop GlobalCtxt after starting codegen to free memory
367
- mem:: drop ( compiler. global_ctxt ( ) ?. take ( ) ) ;
368
358
369
359
if sess. opts . debugging_opts . print_type_sizes {
370
360
sess. code_stats . borrow ( ) . print_type_sizes ( ) ;
371
361
}
372
362
373
- compiler. link ( ) ?;
363
+ // Run linker outside `enter` so GlobalCtxt is freed
364
+ if let Some ( linker) = link {
365
+ linker. link ( ) ?;
366
+ }
374
367
375
368
if sess. opts . debugging_opts . perf_stats {
376
369
sess. print_perf_stats ( ) ;
0 commit comments