@@ -36,6 +36,7 @@ use rustc::session::config::nightly_options;
3636use rustc:: session:: { early_error, early_warn} ;
3737use rustc:: lint:: Lint ;
3838use rustc:: lint;
39+ use rustc:: ty:: TyCtxt ;
3940use rustc:: hir:: def_id:: { LocalCrate , LOCAL_CRATE } ;
4041use rustc:: util:: common:: { time, ErrorReported , install_panic_hook} ;
4142use rustc_metadata:: locator;
@@ -103,11 +104,19 @@ pub trait Callbacks {
103104 /// Called before creating the compiler instance
104105 fn config ( & mut self , _config : & mut interface:: Config ) { }
105106 /// 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 {
107112 true
108113 }
109114 /// 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 {
111120 true
112121 }
113122}
@@ -229,7 +238,8 @@ pub fn run_compiler(
229238 let pretty_info = parse_pretty ( & mut config. opts , & matches) ;
230239
231240 interface:: run_compiler ( config, |compiler| {
232- let sess = compiler. session ( ) ;
241+ let sess = compiler. session ( ) . clone ( ) ;
242+ let sess = & * sess;
233243 let should_stop = RustcDefaultCalls :: print_crate_info (
234244 & * * compiler. codegen_backend ( ) ,
235245 sess,
@@ -247,9 +257,9 @@ pub fn run_compiler(
247257 return sess. compile_status ( ) ;
248258 }
249259
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 ) {
253263 let expansion_result = tcx. expand_macros ( LocalCrate ) ?;
254264 pretty:: print_after_hir_lowering (
255265 tcx,
@@ -259,11 +269,8 @@ pub fn run_compiler(
259269 opt_uii. clone ( ) ,
260270 compiler. output_file ( ) . as_ref ( ) . map ( |p| & * * p) ,
261271 ) ;
262- Ok ( ( ) )
263- } ) ?;
264- return sess. compile_status ( ) ;
265- } else {
266- compiler. enter ( |tcx| {
272+ return sess. compile_status ( ) . map ( |_| None ) ;
273+ } else {
267274 let krate = tcx. parse ( LocalCrate ) ?;
268275 let krate = krate. borrow ( ) ;
269276 pretty:: print_after_parsing (
@@ -273,57 +280,48 @@ pub fn run_compiler(
273280 ppm,
274281 compiler. output_file ( ) . as_ref ( ) . map ( |p| & * * p) ,
275282 ) ;
276- Ok ( ( ) )
277- } ) ?;
278- return sess. compile_status ( ) ;
283+ return sess. compile_status ( ) . map ( |_| None ) ;
284+ }
279285 }
280- }
281286
282- compiler . enter ( |tcx| tcx. parse ( LocalCrate ) ) ?;
287+ tcx. parse ( LocalCrate ) ?;
283288
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+ }
287292
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+ }
293298
294- compiler . enter ( |tcx| tcx. register_plugins ( LocalCrate ) ) ?;
299+ tcx. register_plugins ( LocalCrate ) ?;
295300
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+ }
301306
302- compiler. enter ( |tcx| {
303307 tcx. prepare_outputs ( LocalCrate ) ?;
304- Ok ( ( ) )
305- } ) ?;
306308
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+ }
312314
313- compiler. enter ( |tcx| {
314315 tcx. lower_ast_to_hir ( LocalCrate ) ?;
315- Ok ( ( ) )
316- } ) ?;
317316
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+ }
322321
323- if sess. opts . debugging_opts . save_analysis {
324- compiler. enter ( |tcx| {
322+ if sess. opts . debugging_opts . save_analysis {
325323 let expansion_result = tcx. expand_macros ( LocalCrate ) ?;
326- let result = tcx. analysis ( LOCAL_CRATE ) ;
324+ tcx. analysis ( LOCAL_CRATE ) . ok ( ) ;
327325 let crate_name = & tcx. crate_name ( LOCAL_CRATE ) . as_str ( ) ;
328326
329327 time ( sess, "save analysis" , || {
@@ -336,41 +334,36 @@ pub fn run_compiler(
336334 DumpHandler :: new ( compiler. output_dir ( ) . as_ref ( ) . map ( |p| & * * p) , crate_name)
337335 )
338336 } ) ;
339-
340- result
341337 // AST will be dropped *after* the `after_analysis` callback
342338 // (needed by the RLS)
343- } ) ?;
344- } else {
345- compiler. enter ( |tcx| {
339+ } else {
346340 // Drop AST after lowering HIR to free memory
347341 mem:: drop ( tcx. expand_macros ( LocalCrate ) . unwrap ( ) . ast_crate . steal ( ) ) ;
348- } ) ;
349- }
342+ }
350343
351- compiler . enter ( |tcx| tcx. analysis ( LOCAL_CRATE ) ) ?;
344+ tcx. analysis ( LOCAL_CRATE ) ?;
352345
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+ }
356349
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
360352 mem:: drop ( tcx. expand_macros ( LocalCrate ) . unwrap ( ) . ast_crate . steal ( ) ) ;
361- } ) ;
362- }
353+ }
363354
364- compiler. ongoing_codegen ( ) ?;
355+ compiler. linker ( tcx) . map ( |linker| Some ( linker) )
356+ } ) ?;
365357
366- // Drop GlobalCtxt after starting codegen to free memory
367- mem:: drop ( compiler. global_ctxt ( ) ?. take ( ) ) ;
368358
369359 if sess. opts . debugging_opts . print_type_sizes {
370360 sess. code_stats . borrow ( ) . print_type_sizes ( ) ;
371361 }
372362
373- compiler. link ( ) ?;
363+ // Run linker outside `enter` so GlobalCtxt is freed
364+ if let Some ( linker) = link {
365+ linker. link ( ) ?;
366+ }
374367
375368 if sess. opts . debugging_opts . perf_stats {
376369 sess. print_perf_stats ( ) ;
0 commit comments