diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 17f70b2d8dc66..ac0c18ea2b15f 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -138,6 +138,7 @@ pub struct Options { pub no_trans: bool, pub error_format: ErrorOutputType, pub treat_err_as_bug: bool, + pub continue_parse_after_error: bool, pub mir_opt_level: usize, /// if true, build up the dep-graph @@ -259,6 +260,7 @@ pub fn basic_options() -> Options { parse_only: false, no_trans: false, treat_err_as_bug: false, + continue_parse_after_error: false, mir_opt_level: 1, build_dep_graph: false, dump_dep_graph: false, @@ -633,6 +635,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "run all passes except translation; no output"), treat_err_as_bug: bool = (false, parse_bool, "treat all errors that occur as bugs"), + continue_parse_after_error: bool = (false, parse_bool, + "attempt to recover from parse errors (experimental)"), incr_comp: bool = (false, parse_bool, "enable incremental compilation (experimental)"), dump_dep_graph: bool = (false, parse_bool, @@ -1045,6 +1049,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let parse_only = debugging_opts.parse_only; let no_trans = debugging_opts.no_trans; let treat_err_as_bug = debugging_opts.treat_err_as_bug; + let continue_parse_after_error = debugging_opts.continue_parse_after_error; let mir_opt_level = debugging_opts.mir_opt_level.unwrap_or(1); let incremental_compilation = debugging_opts.incr_comp; let dump_dep_graph = debugging_opts.dump_dep_graph; @@ -1228,6 +1233,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { parse_only: parse_only, no_trans: no_trans, treat_err_as_bug: treat_err_as_bug, + continue_parse_after_error: continue_parse_after_error, mir_opt_level: mir_opt_level, build_dep_graph: incremental_compilation || dump_dep_graph, dump_dep_graph: dump_dep_graph, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 55b873c06630a..55c46ae38713b 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -427,6 +427,8 @@ pub fn phase_1_parse_input<'a>(sess: &'a Session, // memory, but they do not restore the initial state. syntax::ext::mtwt::reset_tables(); token::reset_ident_interner(); + let continue_after_error = sess.opts.continue_parse_after_error; + sess.diagnostic().set_continue_after_error(continue_after_error); let krate = time(sess.time_passes(), "parsing", || { match *input { @@ -442,6 +444,8 @@ pub fn phase_1_parse_input<'a>(sess: &'a Session, } })?; + sess.diagnostic().set_continue_after_error(true); + if sess.opts.debugging_opts.ast_json_noexpand { println!("{}", json::as_json(&krate)); } diff --git a/src/libsyntax/errors/mod.rs b/src/libsyntax/errors/mod.rs index 9e1cb60f54f67..c8c12d5a88334 100644 --- a/src/libsyntax/errors/mod.rs +++ b/src/libsyntax/errors/mod.rs @@ -370,6 +370,7 @@ pub struct Handler { emit: RefCell>, pub can_emit_warnings: bool, treat_err_as_bug: bool, + continue_after_error: Cell, delayed_span_bug: RefCell>, } @@ -392,10 +393,15 @@ impl Handler { emit: RefCell::new(e), can_emit_warnings: can_emit_warnings, treat_err_as_bug: treat_err_as_bug, + continue_after_error: Cell::new(true), delayed_span_bug: RefCell::new(None), } } + pub fn set_continue_after_error(&self, continue_after_error: bool) { + self.continue_after_error.set(continue_after_error); + } + pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> { DiagnosticBuilder::new(&self.emit, Level::Cancelled, "") } @@ -612,6 +618,7 @@ impl Handler { lvl: Level) { if lvl == Warning && !self.can_emit_warnings { return } self.emit.borrow_mut().emit(msp, msg, None, lvl); + if !self.continue_after_error.get() { self.abort_if_errors(); } } pub fn emit_with_code(&self, msp: Option<&MultiSpan>, @@ -620,10 +627,12 @@ impl Handler { lvl: Level) { if lvl == Warning && !self.can_emit_warnings { return } self.emit.borrow_mut().emit(msp, msg, Some(code), lvl); + if !self.continue_after_error.get() { self.abort_if_errors(); } } pub fn custom_emit(&self, rsp: RenderSpan, msg: &str, lvl: Level) { if lvl == Warning && !self.can_emit_warnings { return } self.emit.borrow_mut().custom_emit(&rsp, msg, lvl); + if !self.continue_after_error.get() { self.abort_if_errors(); } } }