Skip to content

Parser backports for beta #32795

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 7, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -255,6 +256,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,
@@ -629,6 +631,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,
@@ -1039,6 +1043,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;
@@ -1218,6 +1223,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,
4 changes: 4 additions & 0 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
@@ -421,6 +421,8 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
// 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 {
@@ -436,6 +438,8 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
}
});

sess.diagnostic().set_continue_after_error(true);

if sess.opts.debugging_opts.ast_json_noexpand {
println!("{}", json::as_json(&krate));
}
9 changes: 9 additions & 0 deletions src/libsyntax/errors/mod.rs
Original file line number Diff line number Diff line change
@@ -370,6 +370,7 @@ pub struct Handler {
emit: RefCell<Box<Emitter>>,
pub can_emit_warnings: bool,
treat_err_as_bug: bool,
continue_after_error: Cell<bool>,
delayed_span_bug: RefCell<Option<(MultiSpan, String)>>,
}

@@ -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(); }
}
}

48 changes: 38 additions & 10 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
@@ -261,6 +261,7 @@ pub struct Parser<'a> {
/// the previous token or None (only stashed sometimes).
pub last_token: Option<Box<token::Token>>,
last_token_interpolated: bool,
last_token_eof: bool,
pub buffer: [TokenAndSpan; 4],
pub buffer_start: isize,
pub buffer_end: isize,
@@ -369,6 +370,7 @@ impl<'a> Parser<'a> {
last_span: span,
last_token: None,
last_token_interpolated: false,
last_token_eof: false,
buffer: [
placeholder.clone(),
placeholder.clone(),
@@ -939,7 +941,9 @@ impl<'a> Parser<'a> {
{
try!(self.expect(bra));
let result = self.parse_seq_to_before_end(ket, sep, f);
self.bump();
if self.token == *ket {
self.bump();
}
Ok(result)
}

@@ -982,6 +986,15 @@ impl<'a> Parser<'a> {

/// Advance the parser by one token
pub fn bump(&mut self) {
if self.last_token_eof {
// Bumping after EOF is a bad sign, usually an infinite loop.
self.bug("attempted to bump the parser past EOF (may be stuck in a loop)");
}

if self.token == token::Eof {
self.last_token_eof = true;
}

self.last_span = self.span;
// Stash token for error recovery (sometimes; clone is not necessarily cheap).
self.last_token = if self.token.is_ident() ||
@@ -1265,15 +1278,21 @@ impl<'a> Parser<'a> {
Ok(cua) => cua,
Err(e) => {
loop {
p.bump();
if p.token == token::Semi {
p.bump();
break;
}
match p.token {
token::Eof => break,

if p.token == token::OpenDelim(token::DelimToken::Brace) {
try!(p.parse_token_tree());
break;
token::CloseDelim(token::Brace) |
token::Semi => {
p.bump();
break;
}

token::OpenDelim(token::Brace) => {
try!(p.parse_token_tree());
break;
}

_ => p.bump()
}
}

@@ -3790,7 +3809,9 @@ impl<'a> Parser<'a> {
fn recover_stmt_(&mut self, break_on_semi: SemiColonMode) {
let mut brace_depth = 0;
let mut bracket_depth = 0;
debug!("recover_stmt_ enter loop");
loop {
debug!("recover_stmt_ loop {:?}", self.token);
match self.token {
token::OpenDelim(token::DelimToken::Brace) => {
brace_depth += 1;
@@ -3802,6 +3823,7 @@ impl<'a> Parser<'a> {
}
token::CloseDelim(token::DelimToken::Brace) => {
if brace_depth == 0 {
debug!("recover_stmt_ return - close delim {:?}", self.token);
return;
}
brace_depth -= 1;
@@ -3814,12 +3836,16 @@ impl<'a> Parser<'a> {
}
self.bump();
}
token::Eof => return,
token::Eof => {
debug!("recover_stmt_ return - Eof");
return;
}
token::Semi => {
self.bump();
if break_on_semi == SemiColonMode::Break &&
brace_depth == 0 &&
bracket_depth == 0 {
debug!("recover_stmt_ return - Semi");
return;
}
}
@@ -4008,6 +4034,8 @@ impl<'a> Parser<'a> {
while !self.eat(&token::CloseDelim(token::Brace)) {
let Spanned {node, span} = if let Some(s) = self.parse_stmt_() {
s
} else if self.token == token::Eof {
break;
} else {
// Found only `;` or `}`.
continue;
2 changes: 2 additions & 0 deletions src/test/compile-fail/issue-12560-2.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z continue-parse-after-error

// For style and consistency reasons, non-parametrized enum variants must
// be used simply as `ident` instead of `ident ()`.
// This test-case covers enum matching.
2 changes: 2 additions & 0 deletions src/test/compile-fail/issue-28433.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z continue-parse-after-error

enum bird {
pub duck,
//~^ ERROR: expected identifier, found keyword `pub`
2 changes: 2 additions & 0 deletions src/test/compile-fail/issue-30715.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z continue-parse-after-error

macro_rules! parallel {
(
// If future has `pred`/`moelarry` fragments (where "pred" is
2 changes: 2 additions & 0 deletions src/test/compile-fail/macro-incomplete-parse.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z continue-parse-after-error

macro_rules! ignored_item {
() => {
fn foo() {}
2 changes: 2 additions & 0 deletions src/test/compile-fail/parse-error-correct.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z continue-parse-after-error

// Test that the parser is error correcting missing idents. Despite a parsing
// error (or two), we still run type checking (and don't get extra errors there).

2 changes: 2 additions & 0 deletions src/test/compile-fail/parser-recovery-1.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z continue-parse-after-error

// Test that we can recover from missing braces in the parser.

trait Foo {
2 changes: 2 additions & 0 deletions src/test/compile-fail/parser-recovery-2.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z continue-parse-after-error

// Test that we can recover from mismatched braces in the parser.

trait Foo {
2 changes: 2 additions & 0 deletions src/test/compile-fail/self_type_keyword.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z continue-parse-after-error

struct Self;
//~^ ERROR expected identifier, found keyword `Self`

2 changes: 1 addition & 1 deletion src/test/parse-fail/ascii-only-character-escape.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error

fn main() {
let x = "\x80"; //~ ERROR may only be used
2 changes: 1 addition & 1 deletion src/test/parse-fail/bad-char-literals.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error

// ignore-tidy-cr
// ignore-tidy-tab
2 changes: 1 addition & 1 deletion src/test/parse-fail/bad-lit-suffixes.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error


extern
2 changes: 1 addition & 1 deletion src/test/parse-fail/byte-literals.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error


// ignore-tidy-tab
2 changes: 1 addition & 1 deletion src/test/parse-fail/byte-string-literals.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error


// ignore-tidy-tab
2 changes: 1 addition & 1 deletion src/test/parse-fail/issue-10412.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error


trait Serializable<'self, T> { //~ ERROR no longer a special lifetime
3 changes: 1 addition & 2 deletions src/test/parse-fail/issue-10636-2.rs
Original file line number Diff line number Diff line change
@@ -17,5 +17,4 @@ pub fn trace_option(option: Option<isize>) { //~ HELP did you mean to close this
option.map(|some| 42; //~ NOTE: unclosed delimiter
//~^ ERROR: expected one of
} //~ ERROR: incorrect close delimiter
//~^ ERROR: expected one of
//~ ERROR: this file contains an un-closed delimiter
//~^ ERROR: unexpected token
2 changes: 2 additions & 0 deletions src/test/parse-fail/issue-23620-invalid-escapes.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only -Z continue-parse-after-error

fn main() {
let _ = b"\u{a66e}";
//~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string
16 changes: 16 additions & 0 deletions src/test/parse-fail/issue-32446.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only

fn main() {}

// This used to end up in an infite loop trying to bump past EOF.
trait T { ... } //~ ERROR
2 changes: 2 additions & 0 deletions src/test/parse-fail/lex-bad-binary-literal.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only -Z continue-parse-after-error

fn main() {
0b121; //~ ERROR invalid digit for a base 2 literal
0b10_10301; //~ ERROR invalid digit for a base 2 literal
2 changes: 1 addition & 1 deletion src/test/parse-fail/lex-bad-char-literals-1.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error
static c3: char =
'\x1' //~ ERROR: numeric character escape is too short
;
2 changes: 1 addition & 1 deletion src/test/parse-fail/lex-bad-numeric-literals.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error

fn main() {
0o1.0; //~ ERROR: octal float literal is not supported
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error

// ignore-tidy-cr

2 changes: 1 addition & 1 deletion src/test/parse-fail/new-unicode-escapes-4.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error

pub fn main() {
let s = "\u{lol}";
2 changes: 1 addition & 1 deletion src/test/parse-fail/no-unsafe-self.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z parse-only
// compile-flags: -Z parse-only -Z continue-parse-after-error

trait A {
fn foo(*mut self); //~ ERROR cannot pass self by raw pointer
2 changes: 1 addition & 1 deletion src/test/parse-fail/pat-lt-bracket-6.rs
Original file line number Diff line number Diff line change
@@ -10,5 +10,5 @@

fn main() {
let Test(&desc[..]) = x; //~ error: expected one of `,` or `@`, found `[`
//~^ ERROR expected one of `:`, `;`, or `=`, found `..`
//~^ ERROR expected one of `:`, `;`, `=`, or `@`, found `[`
}
2 changes: 1 addition & 1 deletion src/test/parse-fail/pat-lt-bracket-7.rs
Original file line number Diff line number Diff line change
@@ -10,5 +10,5 @@

fn main() {
for thing(x[]) in foo {} //~ error: expected one of `,` or `@`, found `[`
//~^ ERROR: expected `in`, found `]`
//~^ ERROR expected one of `@` or `in`, found `[`
}