]> git.lizzy.rs Git - rust.git/commitdiff
syntax: Display spans for open delimiters when a file ends prematurely
authorTim Chevalier <chevalier@alum.wellesley.edu>
Mon, 7 Oct 2013 19:43:42 +0000 (15:43 -0400)
committerTim Chevalier <chevalier@alum.wellesley.edu>
Tue, 8 Oct 2013 01:06:30 +0000 (18:06 -0700)
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

src/libsyntax/parse/parser.rs
src/test/compile-fail/issue-2354-1.rs [new file with mode: 0644]
src/test/compile-fail/issue-2354.rs

index cad19543608ba1ab19d387c6ee3381e2cb3f3c5a..e9f55c62b6c55b3dbb32aea313ad8ff527d5b7cf 100644 (file)
@@ -308,6 +308,7 @@ pub fn Parser(sess: @mut ParseSess,
         quote_depth: @mut 0,
         obsolete_set: @mut HashSet::new(),
         mod_path_stack: @mut ~[],
+        open_braces: @mut ~[]
     }
 }
 
@@ -336,6 +337,8 @@ pub struct Parser {
     obsolete_set: @mut HashSet<ObsoleteSyntax>,
     /// Used to determine the path to externally loaded source files
     mod_path_stack: @mut ~[@str],
+    /// Stack of spans of open delimiters. Used for error message.
+    open_braces: @mut ~[@Span]
 }
 
 #[unsafe_destructor]
@@ -2022,12 +2025,18 @@ fn parse_any_tt_tok(p: &Parser) -> token_tree{
 
         match *self.token {
             token::EOF => {
-                self.fatal("file ended with unbalanced delimiters");
+                for sp in self.open_braces.iter() {
+                    self.span_note(**sp, "Did you mean to close this delimiter?");
+                }
+                // There shouldn't really be a span, but it's easier for the test runner
+                // if we give it one
+                self.fatal("This file contains an un-closed delimiter ");
             }
             token::LPAREN | token::LBRACE | token::LBRACKET => {
                 let close_delim = token::flip_delimiter(&*self.token);
 
                 // Parse the open delimiter.
+                (*self.open_braces).push(@*self.span);
                 let mut result = ~[parse_any_tt_tok(self)];
 
                 let trees =
@@ -2038,6 +2047,7 @@ fn parse_any_tt_tok(p: &Parser) -> token_tree{
 
                 // Parse the close delimiter.
                 result.push(parse_any_tt_tok(self));
+                self.open_braces.pop();
 
                 tt_delim(@mut result)
             }
diff --git a/src/test/compile-fail/issue-2354-1.rs b/src/test/compile-fail/issue-2354-1.rs
new file mode 100644 (file)
index 0000000..67b5c6b
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2013 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.
+
+static foo: int = 2; } //~ ERROR incorrect close delimiter:
+
index 409e1c1f040204cc149ad836586479037939a97f..9761bd3317c703f0f73cc8c333cdfa3d011282ed 100644 (file)
@@ -8,13 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-test
-/*
-  Ideally, the error about the missing close brace in foo would be reported
-  near the corresponding open brace. But currently it's reported at the end.
-  xfailed for now (see Issue #2354)
- */
-fn foo() { //~ ERROR this open brace is not closed
+fn foo() { //~ NOTE Did you mean to close this delimiter?
   match Some(x) {
       Some(y) { fail!(); }
       None    { fail!(); }
@@ -25,4 +19,4 @@ fn bar() {
     while (i < 1000) {}
 }
 
-fn main() {}
+fn main() {} //~ ERROR This file contains an un-closed delimiter