@@ -105,57 +105,103 @@ pub mod target_features;
105
105
const BUG_REPORT_URL : & ' static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
106
106
md#bug-reports";
107
107
108
+ // Err(0) means compilation was stopped, but no errors were found.
109
+ // This would be better as a dedicated enum, but using try! is so convenient.
110
+ pub type CompileResult = Result < ( ) , usize > ;
111
+
112
+ pub fn compile_result_from_err_count ( err_count : usize ) -> CompileResult {
113
+ if err_count == 0 {
114
+ Ok ( ( ) )
115
+ } else {
116
+ Err ( err_count)
117
+ }
118
+ }
119
+
120
+ #[ inline]
121
+ fn abort_msg ( err_count : usize ) -> String {
122
+ match err_count {
123
+ 0 => "aborting with no errors (maybe a bug?)" . to_owned ( ) ,
124
+ 1 => "aborting due to previous error" . to_owned ( ) ,
125
+ e => format ! ( "aborting due to {} previous errors" , e) ,
126
+ }
127
+ }
128
+
129
+ pub fn abort_on_err < T > ( result : Result < T , usize > , sess : & Session ) -> T {
130
+ match result {
131
+ Err ( err_count) => {
132
+ sess. fatal ( & abort_msg ( err_count) ) ;
133
+ }
134
+ Ok ( x) => x,
135
+ }
136
+ }
137
+
108
138
pub fn run ( args : Vec < String > ) -> isize {
109
- monitor ( move || run_compiler ( & args, & mut RustcDefaultCalls ) ) ;
139
+ monitor ( move || {
140
+ let ( result, session) = run_compiler ( & args, & mut RustcDefaultCalls ) ;
141
+ if let Err ( err_count) = result {
142
+ if err_count > 0 {
143
+ match session {
144
+ Some ( sess) => sess. fatal ( & abort_msg ( err_count) ) ,
145
+ None => {
146
+ let mut emitter =
147
+ errors:: emitter:: BasicEmitter :: stderr ( errors:: ColorConfig :: Auto ) ;
148
+ emitter. emit ( None , & abort_msg ( err_count) , None , errors:: Level :: Fatal ) ;
149
+ panic ! ( errors:: FatalError ) ;
150
+ }
151
+ }
152
+ }
153
+ }
154
+ } ) ;
110
155
0
111
156
}
112
157
113
158
// Parse args and run the compiler. This is the primary entry point for rustc.
114
159
// See comments on CompilerCalls below for details about the callbacks argument.
115
- pub fn run_compiler < ' a > ( args : & [ String ] , callbacks : & mut CompilerCalls < ' a > ) {
116
- macro_rules! do_or_return { ( $expr: expr) => {
160
+ pub fn run_compiler < ' a > ( args : & [ String ] ,
161
+ callbacks : & mut CompilerCalls < ' a > )
162
+ -> ( CompileResult , Option < Session > ) {
163
+ macro_rules! do_or_return { ( $expr: expr, $sess: expr) => {
117
164
match $expr {
118
- Compilation :: Stop => return ,
165
+ Compilation :: Stop => return ( Ok ( ( ) ) , $sess ) ,
119
166
Compilation :: Continue => { }
120
167
}
121
168
} }
122
169
123
170
let matches = match handle_options ( args. to_vec ( ) ) {
124
171
Some ( matches) => matches,
125
- None => return ,
172
+ None => return ( Ok ( ( ) ) , None ) ,
126
173
} ;
127
174
128
175
let sopts = config:: build_session_options ( & matches) ;
129
176
130
177
let descriptions = diagnostics_registry ( ) ;
131
178
132
- do_or_return ! ( callbacks. early_callback( & matches, & descriptions, sopts. error_format) ) ;
179
+ do_or_return ! ( callbacks. early_callback( & matches, & descriptions, sopts. error_format) , None ) ;
133
180
134
181
let ( odir, ofile) = make_output ( & matches) ;
135
182
let ( input, input_file_path) = match make_input ( & matches. free ) {
136
183
Some ( ( input, input_file_path) ) => callbacks. some_input ( input, input_file_path) ,
137
184
None => match callbacks. no_input ( & matches, & sopts, & odir, & ofile, & descriptions) {
138
185
Some ( ( input, input_file_path) ) => ( input, input_file_path) ,
139
- None => return ,
186
+ None => return ( Ok ( ( ) ) , None ) ,
140
187
} ,
141
188
} ;
142
189
143
190
let cstore = Rc :: new ( CStore :: new ( token:: get_ident_interner ( ) ) ) ;
144
- let sess = build_session ( sopts, input_file_path, descriptions,
145
- cstore. clone ( ) ) ;
191
+ let sess = build_session ( sopts, input_file_path, descriptions, cstore. clone ( ) ) ;
146
192
rustc_lint:: register_builtins ( & mut sess. lint_store . borrow_mut ( ) , Some ( & sess) ) ;
147
193
let mut cfg = config:: build_configuration ( & sess) ;
148
194
target_features:: add_configuration ( & mut cfg, & sess) ;
149
195
150
- do_or_return ! ( callbacks. late_callback( & matches, & sess, & input, & odir, & ofile) ) ;
196
+ do_or_return ! ( callbacks. late_callback( & matches, & sess, & input, & odir, & ofile) , Some ( sess ) ) ;
151
197
152
198
// It is somewhat unfortunate that this is hardwired in - this is forced by
153
199
// the fact that pretty_print_input requires the session by value.
154
200
let pretty = callbacks. parse_pretty ( & sess, & matches) ;
155
201
match pretty {
156
202
Some ( ( ppm, opt_uii) ) => {
157
203
pretty:: pretty_print_input ( sess, & cstore, cfg, & input, ppm, opt_uii, ofile) ;
158
- return ;
204
+ return ( Ok ( ( ) ) , None ) ;
159
205
}
160
206
None => {
161
207
// continue
@@ -164,8 +210,9 @@ pub fn run_compiler<'a>(args: &[String], callbacks: &mut CompilerCalls<'a>) {
164
210
165
211
let plugins = sess. opts . debugging_opts . extra_plugins . clone ( ) ;
166
212
let control = callbacks. build_controller ( & sess) ;
167
- driver:: compile_input ( sess, & cstore, cfg, & input, & odir, & ofile,
168
- Some ( plugins) , control) ;
213
+ ( driver:: compile_input ( & sess, & cstore, cfg, & input, & odir, & ofile,
214
+ Some ( plugins) , control) ,
215
+ Some ( sess) )
169
216
}
170
217
171
218
// Extract output directory and file from matches.
0 commit comments