about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2017-12-13 23:05:49 -0800
committerEsteban Küber <esteban@kuber.com.ar>2017-12-21 14:57:42 -0800
commitaaf3e318fc33edcc6dbf0920998c3f27d00dd818 (patch)
treea9dadd8df5519666c6293b0f2b3b59f67ef32f6b /src/libsyntax
parentb7b52cc8bf2bcc4cbd223a4b61fe3e35e798f6e2 (diff)
downloadrust-aaf3e318fc33edcc6dbf0920998c3f27d00dd818.tar.gz
rust-aaf3e318fc33edcc6dbf0920998c3f27d00dd818.zip
Do not emit type errors on recovered blocks
When a parse error occurs on a block, the parser will recover and create
a block with the statements collected until that point. Now a flag
stating that a recovery has been performed in this block is propagated
so that the type checker knows that the type of the block (which will be
identified as `()`) shouldn't be checked against the expectation to
reduce the amount of irrelevant diagnostic errors shown to the user.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/ext/build.rs1
-rw-r--r--src/libsyntax/fold.rs3
-rw-r--r--src/libsyntax/parse/mod.rs1
-rw-r--r--src/libsyntax/parse/parser.rs7
5 files changed, 10 insertions, 3 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 1d399f159c8..a8bc8f7e0ce 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -468,6 +468,7 @@ pub struct Block {
     /// Distinguishes between `unsafe { ... }` and `{ ... }`
     pub rules: BlockCheckMode,
     pub span: Span,
+    pub recovered: bool,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 9a96432f11d..8aeebecf661 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -594,6 +594,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
            id: ast::DUMMY_NODE_ID,
            rules: BlockCheckMode::Default,
            span,
+           recovered: false,
         })
     }
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 6f973e2bcfa..279add5d299 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -851,11 +851,12 @@ fn noop_fold_bounds<T: Folder>(bounds: TyParamBounds, folder: &mut T)
 }
 
 pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
-    b.map(|Block {id, stmts, rules, span}| Block {
+    b.map(|Block {id, stmts, rules, span, recovered}| Block {
         id: folder.new_id(id),
         stmts: stmts.move_flat_map(|s| folder.fold_stmt(s).into_iter()),
         rules,
         span: folder.new_span(span),
+        recovered,
     })
 }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 89a54989f96..f96c7e8598f 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -931,6 +931,7 @@ mod tests {
                                         id: ast::DUMMY_NODE_ID,
                                         rules: ast::BlockCheckMode::Default, // no idea
                                         span: sp(15,21),
+                                        recovered: false,
                                     })),
                             vis: ast::Visibility::Inherited,
                             span: sp(0,21)})));
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index d9434539246..bb46cef5ee2 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4371,13 +4371,15 @@ impl<'a> Parser<'a> {
     /// Precondition: already parsed the '{'.
     fn parse_block_tail(&mut self, lo: Span, s: BlockCheckMode) -> PResult<'a, P<Block>> {
         let mut stmts = vec![];
+        let mut recovered = false;
 
         while !self.eat(&token::CloseDelim(token::Brace)) {
             let stmt = match self.parse_full_stmt(false) {
                 Err(mut err) => {
                     err.emit();
-                    self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Break);
+                    self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore);
                     self.eat(&token::CloseDelim(token::Brace));
+                    recovered = true;
                     break;
                 }
                 Ok(stmt) => stmt,
@@ -4396,12 +4398,13 @@ impl<'a> Parser<'a> {
             id: ast::DUMMY_NODE_ID,
             rules: s,
             span: lo.to(self.prev_span),
+            recovered,
         }))
     }
 
     /// Parse a statement, including the trailing semicolon.
     pub fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
-        let mut stmt = match self.parse_stmt_(macro_legacy_warnings) {
+        let mut stmt = match self.parse_stmt_without_recovery(macro_legacy_warnings)? {
             Some(stmt) => stmt,
             None => return Ok(None),
         };