Skip to content

Commit bed669c

Browse files
committed
syntax: Display spans for open delimiters when a file ends prematurely
It's more helpful to list the span of each open delimiter seen so far than to print out an error with the span of the last position in the file. Closes #2354
1 parent 8eb28bb commit bed669c

File tree

3 files changed

+25
-9
lines changed

3 files changed

+25
-9
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ pub fn Parser(sess: @mut ParseSess,
308308
quote_depth: @mut 0,
309309
obsolete_set: @mut HashSet::new(),
310310
mod_path_stack: @mut ~[],
311+
open_braces: @mut ~[]
311312
}
312313
}
313314

@@ -336,6 +337,8 @@ pub struct Parser {
336337
obsolete_set: @mut HashSet<ObsoleteSyntax>,
337338
/// Used to determine the path to externally loaded source files
338339
mod_path_stack: @mut ~[@str],
340+
/// Stack of spans of open delimiters. Used for error message.
341+
open_braces: @mut ~[@Span]
339342
}
340343

341344
#[unsafe_destructor]
@@ -2022,12 +2025,18 @@ impl Parser {
20222025

20232026
match *self.token {
20242027
token::EOF => {
2025-
self.fatal("file ended with unbalanced delimiters");
2028+
for sp in self.open_braces.iter() {
2029+
self.span_note(**sp, "Did you mean to close this delimiter?");
2030+
}
2031+
// There shouldn't really be a span, but it's easier for the test runner
2032+
// if we give it one
2033+
self.fatal("This file contains an un-closed delimiter ");
20262034
}
20272035
token::LPAREN | token::LBRACE | token::LBRACKET => {
20282036
let close_delim = token::flip_delimiter(&*self.token);
20292037

20302038
// Parse the open delimiter.
2039+
(*self.open_braces).push(@*self.span);
20312040
let mut result = ~[parse_any_tt_tok(self)];
20322041

20332042
let trees =
@@ -2038,6 +2047,7 @@ impl Parser {
20382047

20392048
// Parse the close delimiter.
20402049
result.push(parse_any_tt_tok(self));
2050+
self.open_braces.pop();
20412051

20422052
tt_delim(@mut result)
20432053
}

src/test/compile-fail/issue-2354-1.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
static foo: int = 2; } //~ ERROR incorrect close delimiter:
12+

src/test/compile-fail/issue-2354.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// xfail-test
12-
/*
13-
Ideally, the error about the missing close brace in foo would be reported
14-
near the corresponding open brace. But currently it's reported at the end.
15-
xfailed for now (see Issue #2354)
16-
*/
17-
fn foo() { //~ ERROR this open brace is not closed
11+
fn foo() { //~ NOTE Did you mean to close this delimiter?
1812
match Some(x) {
1913
Some(y) { fail!(); }
2014
None { fail!(); }
@@ -25,4 +19,4 @@ fn bar() {
2519
while (i < 1000) {}
2620
}
2721

28-
fn main() {}
22+
fn main() {} //~ ERROR This file contains an un-closed delimiter

0 commit comments

Comments
 (0)