@@ -65,7 +65,7 @@ pub fn compile_input(sess: Session,
65
65
// We need nested scopes here, because the intermediate results can keep
66
66
// large chunks of memory alive and we want to free them as soon as
67
67
// possible to keep the peak memory usage low
68
- let ( outputs , trans , sess ) = {
68
+ let ( sess , result ) = {
69
69
let ( outputs, expanded_crate, id) = {
70
70
let krate = phase_1_parse_input ( & sess, cfg, input) ;
71
71
@@ -119,37 +119,52 @@ pub fn compile_input(sess: Session,
119
119
& ast_map. krate( ) ,
120
120
& id[ ..] ) ) ;
121
121
122
- let ( tcx, analysis) = phase_3_run_analysis_passes ( sess,
123
- ast_map,
124
- & arenas,
125
- id,
126
- control. make_glob_map ) ;
127
-
128
- controller_entry_point ! ( after_analysis,
129
- tcx. sess,
130
- CompileState :: state_after_analysis( input,
131
- & tcx. sess,
132
- outdir,
133
- tcx. map. krate( ) ,
134
- & analysis,
135
- & tcx) ) ;
136
-
137
- if log_enabled ! ( :: log:: INFO ) {
138
- println ! ( "Pre-trans" ) ;
139
- tcx. print_debug_stats ( ) ;
140
- }
141
- let trans = phase_4_translate_to_llvm ( & tcx, analysis) ;
122
+ phase_3_run_analysis_passes ( sess,
123
+ ast_map,
124
+ & arenas,
125
+ id,
126
+ control. make_glob_map ,
127
+ |tcx, analysis| {
128
+
129
+ {
130
+ let state = CompileState :: state_after_analysis ( input,
131
+ & tcx. sess ,
132
+ outdir,
133
+ tcx. map . krate ( ) ,
134
+ & analysis,
135
+ tcx) ;
136
+ ( control. after_analysis . callback ) ( state) ;
137
+
138
+ tcx. sess . abort_if_errors ( ) ;
139
+ if control. after_analysis . stop == Compilation :: Stop {
140
+ return Err ( ( ) ) ;
141
+ }
142
+ }
142
143
143
- if log_enabled ! ( :: log:: INFO ) {
144
- println ! ( "Post-trans" ) ;
145
- tcx. print_debug_stats ( ) ;
146
- }
144
+ if log_enabled ! ( :: log:: INFO ) {
145
+ println ! ( "Pre-trans" ) ;
146
+ tcx. print_debug_stats ( ) ;
147
+ }
148
+ let trans = phase_4_translate_to_llvm ( tcx, analysis) ;
149
+
150
+ if log_enabled ! ( :: log:: INFO ) {
151
+ println ! ( "Post-trans" ) ;
152
+ tcx. print_debug_stats ( ) ;
153
+ }
147
154
148
- // Discard interned strings as they are no longer required.
149
- token:: get_ident_interner ( ) . clear ( ) ;
155
+ // Discard interned strings as they are no longer required.
156
+ token:: get_ident_interner ( ) . clear ( ) ;
150
157
151
- ( outputs, trans, tcx. sess )
158
+ Ok ( ( outputs, trans) )
159
+ } )
152
160
} ;
161
+
162
+ let ( outputs, trans) = if let Ok ( out) = result {
163
+ out
164
+ } else {
165
+ return ;
166
+ } ;
167
+
153
168
phase_5_run_llvm_passes ( & sess, & trans, & outputs) ;
154
169
155
170
controller_entry_point ! ( after_llvm,
@@ -578,12 +593,16 @@ pub fn assign_node_ids_and_map<'ast>(sess: &Session,
578
593
/// Run the resolution, typechecking, region checking and other
579
594
/// miscellaneous analysis passes on the crate. Return various
580
595
/// structures carrying the results of the analysis.
581
- pub fn phase_3_run_analysis_passes < ' tcx > ( sess : Session ,
582
- ast_map : ast_map:: Map < ' tcx > ,
583
- arenas : & ' tcx ty:: CtxtArenas < ' tcx > ,
584
- name : String ,
585
- make_glob_map : resolve:: MakeGlobMap )
586
- -> ( ty:: ctxt < ' tcx > , ty:: CrateAnalysis ) {
596
+ pub fn phase_3_run_analysis_passes < ' tcx , F , R > ( sess : Session ,
597
+ ast_map : ast_map:: Map < ' tcx > ,
598
+ arenas : & ' tcx ty:: CtxtArenas < ' tcx > ,
599
+ name : String ,
600
+ make_glob_map : resolve:: MakeGlobMap ,
601
+ f : F )
602
+ -> ( Session , R )
603
+ where F : FnOnce ( & ty:: ctxt < ' tcx > ,
604
+ ty:: CrateAnalysis ) -> R
605
+ {
587
606
let time_passes = sess. time_passes ( ) ;
588
607
let krate = ast_map. krate ( ) ;
589
608
@@ -627,86 +646,88 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
627
646
time ( time_passes, "static item recursion checking" , ( ) , |_|
628
647
middle:: check_static_recursion:: check_crate ( & sess, krate, & def_map, & ast_map) ) ;
629
648
630
- let ty_cx = ty:: mk_ctxt ( sess,
631
- arenas,
632
- def_map,
633
- named_region_map,
634
- ast_map,
635
- freevars,
636
- region_map,
637
- lang_items,
638
- stability:: Index :: new ( krate) ) ;
639
-
640
- // passes are timed inside typeck
641
- typeck:: check_crate ( & ty_cx, trait_map) ;
642
-
643
- time ( time_passes, "const checking" , ( ) , |_|
644
- middle:: check_const:: check_crate ( & ty_cx) ) ;
645
-
646
- let ( exported_items, public_items) =
647
- time ( time_passes, "privacy checking" , ( ) , |_|
648
- rustc_privacy:: check_crate ( & ty_cx, & export_map, external_exports) ) ;
649
-
650
- // Do not move this check past lint
651
- time ( time_passes, "stability index" , ( ) , |_|
652
- ty_cx. stability . borrow_mut ( ) . build ( & ty_cx, krate, & public_items) ) ;
653
-
654
- time ( time_passes, "intrinsic checking" , ( ) , |_|
655
- middle:: intrinsicck:: check_crate ( & ty_cx) ) ;
656
-
657
- time ( time_passes, "effect checking" , ( ) , |_|
658
- middle:: effect:: check_crate ( & ty_cx) ) ;
659
-
660
- time ( time_passes, "match checking" , ( ) , |_|
661
- middle:: check_match:: check_crate ( & ty_cx) ) ;
662
-
663
- time ( time_passes, "liveness checking" , ( ) , |_|
664
- middle:: liveness:: check_crate ( & ty_cx) ) ;
665
-
666
- time ( time_passes, "borrow checking" , ( ) , |_|
667
- borrowck:: check_crate ( & ty_cx) ) ;
668
-
669
- time ( time_passes, "rvalue checking" , ( ) , |_|
670
- middle:: check_rvalues:: check_crate ( & ty_cx, krate) ) ;
671
-
672
- // Avoid overwhelming user with errors if type checking failed.
673
- // I'm not sure how helpful this is, to be honest, but it avoids a
674
- // lot of annoying errors in the compile-fail tests (basically,
675
- // lint warnings and so on -- kindck used to do this abort, but
676
- // kindck is gone now). -nmatsakis
677
- ty_cx. sess . abort_if_errors ( ) ;
678
-
679
- let reachable_map =
680
- time ( time_passes, "reachability checking" , ( ) , |_|
681
- reachable:: find_reachable ( & ty_cx, & exported_items) ) ;
682
-
683
- time ( time_passes, "death checking" , ( ) , |_| {
684
- middle:: dead:: check_crate ( & ty_cx,
685
- & exported_items,
686
- & reachable_map)
687
- } ) ;
688
-
689
- let ref lib_features_used =
690
- time ( time_passes, "stability checking" , ( ) , |_|
691
- stability:: check_unstable_api_usage ( & ty_cx) ) ;
692
-
693
- time ( time_passes, "unused lib feature checking" , ( ) , |_|
694
- stability:: check_unused_or_stable_features (
695
- & ty_cx. sess , lib_features_used) ) ;
696
-
697
- time ( time_passes, "lint checking" , ( ) , |_|
698
- lint:: check_crate ( & ty_cx, & exported_items) ) ;
699
-
700
- // The above three passes generate errors w/o aborting
701
- ty_cx. sess . abort_if_errors ( ) ;
702
-
703
- ( ty_cx, ty:: CrateAnalysis {
704
- export_map : export_map,
705
- exported_items : exported_items,
706
- public_items : public_items,
707
- reachable : reachable_map,
708
- name : name,
709
- glob_map : glob_map,
649
+ ty:: with_ctxt ( sess,
650
+ arenas,
651
+ def_map,
652
+ named_region_map,
653
+ ast_map,
654
+ freevars,
655
+ region_map,
656
+ lang_items,
657
+ stability:: Index :: new ( krate) ,
658
+ |tcx| {
659
+
660
+ // passes are timed inside typeck
661
+ typeck:: check_crate ( tcx, trait_map) ;
662
+
663
+ time ( time_passes, "const checking" , ( ) , |_|
664
+ middle:: check_const:: check_crate ( tcx) ) ;
665
+
666
+ let ( exported_items, public_items) =
667
+ time ( time_passes, "privacy checking" , ( ) , |_|
668
+ rustc_privacy:: check_crate ( tcx, & export_map, external_exports) ) ;
669
+
670
+ // Do not move this check past lint
671
+ time ( time_passes, "stability index" , ( ) , |_|
672
+ tcx. stability . borrow_mut ( ) . build ( tcx, krate, & public_items) ) ;
673
+
674
+ time ( time_passes, "intrinsic checking" , ( ) , |_|
675
+ middle:: intrinsicck:: check_crate ( tcx) ) ;
676
+
677
+ time ( time_passes, "effect checking" , ( ) , |_|
678
+ middle:: effect:: check_crate ( tcx) ) ;
679
+
680
+ time ( time_passes, "match checking" , ( ) , |_|
681
+ middle:: check_match:: check_crate ( tcx) ) ;
682
+
683
+ time ( time_passes, "liveness checking" , ( ) , |_|
684
+ middle:: liveness:: check_crate ( tcx) ) ;
685
+
686
+ time ( time_passes, "borrow checking" , ( ) , |_|
687
+ borrowck:: check_crate ( tcx) ) ;
688
+
689
+ time ( time_passes, "rvalue checking" , ( ) , |_|
690
+ middle:: check_rvalues:: check_crate ( tcx, krate) ) ;
691
+
692
+ // Avoid overwhelming user with errors if type checking failed.
693
+ // I'm not sure how helpful this is, to be honest, but it avoids a
694
+ // lot of annoying errors in the compile-fail tests (basically,
695
+ // lint warnings and so on -- kindck used to do this abort, but
696
+ // kindck is gone now). -nmatsakis
697
+ tcx. sess . abort_if_errors ( ) ;
698
+
699
+ let reachable_map =
700
+ time ( time_passes, "reachability checking" , ( ) , |_|
701
+ reachable:: find_reachable ( tcx, & exported_items) ) ;
702
+
703
+ time ( time_passes, "death checking" , ( ) , |_| {
704
+ middle:: dead:: check_crate ( tcx,
705
+ & exported_items,
706
+ & reachable_map)
707
+ } ) ;
708
+
709
+ let ref lib_features_used =
710
+ time ( time_passes, "stability checking" , ( ) , |_|
711
+ stability:: check_unstable_api_usage ( tcx) ) ;
712
+
713
+ time ( time_passes, "unused lib feature checking" , ( ) , |_|
714
+ stability:: check_unused_or_stable_features (
715
+ & tcx. sess , lib_features_used) ) ;
716
+
717
+ time ( time_passes, "lint checking" , ( ) , |_|
718
+ lint:: check_crate ( tcx, & exported_items) ) ;
719
+
720
+ // The above three passes generate errors w/o aborting
721
+ tcx. sess . abort_if_errors ( ) ;
722
+
723
+ f ( tcx, ty:: CrateAnalysis {
724
+ export_map : export_map,
725
+ exported_items : exported_items,
726
+ public_items : public_items,
727
+ reachable : reachable_map,
728
+ name : name,
729
+ glob_map : glob_map,
730
+ } )
710
731
} )
711
732
}
712
733
0 commit comments