about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-12-17 04:57:32 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-12-27 15:51:36 +0300
commita5c52c72ae3c1d8b3896756541b115a1d5ea94b7 (patch)
tree91e535fc9e65ac6594f3480e64f9396b312bcdce /src
parentd2986970adae36939d13c79e3af34ff6378fad68 (diff)
downloadrust-a5c52c72ae3c1d8b3896756541b115a1d5ea94b7.tar.gz
rust-a5c52c72ae3c1d8b3896756541b115a1d5ea94b7.zip
AST/HIR: Introduce `ExprKind::Err` for better error recovery in the front-end
Diffstat (limited to 'src')
-rw-r--r--src/librustc/cfg/construct.rs3
-rw-r--r--src/librustc/hir/intravisit.rs1
-rw-r--r--src/librustc/hir/lowering.rs2
-rw-r--r--src/librustc/hir/mod.rs7
-rw-r--r--src/librustc/hir/print.rs9
-rw-r--r--src/librustc/ich/impls_hir.rs3
-rw-r--r--src/librustc/middle/expr_use_visitor.rs3
-rw-r--r--src/librustc/middle/liveness.rs6
-rw-r--r--src/librustc/middle/mem_categorization.rs2
-rw-r--r--src/librustc_mir/hair/cx/expr.rs1
-rw-r--r--src/librustc_passes/rvalue_promotion.rs3
-rw-r--r--src/librustc_typeck/check/mod.rs3
-rw-r--r--src/libsyntax/ast.rs4
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/print/pprust.rs9
-rw-r--r--src/libsyntax/util/parser.rs4
-rw-r--r--src/libsyntax/visit.rs1
17 files changed, 51 insertions, 11 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs
index b6d3b6665be..978d20ea947 100644
--- a/src/librustc/cfg/construct.rs
+++ b/src/librustc/cfg/construct.rs
@@ -392,7 +392,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
 
             hir::ExprKind::Closure(..) |
             hir::ExprKind::Lit(..) |
-            hir::ExprKind::Path(_) => {
+            hir::ExprKind::Path(_) |
+            hir::ExprKind::Err => {
                 self.straightline(expr, pred, None::<hir::Expr>.iter())
             }
         }
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 17b001a5ce8..2f0a95445a8 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -1099,6 +1099,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
         ExprKind::Yield(ref subexpression) => {
             visitor.visit_expr(subexpression);
         }
+        ExprKind::Err => {}
     }
 }
 
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 039b525c864..59b9f83c242 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -4117,6 +4117,8 @@ impl<'a> LoweringContext<'a> {
                 hir::ExprKind::Yield(P(expr))
             }
 
+            ExprKind::Err => hir::ExprKind::Err,
+
             // Desugar `ExprIfLet`
             // from: `if let <pat> = <sub_expr> <body> [<else_opt>]`
             ExprKind::IfLet(ref pats, ref sub_expr, ref body, ref else_opt) => {
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 30817433823..601d310fc3a 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1362,6 +1362,7 @@ impl Expr {
             ExprKind::Struct(..) => ExprPrecedence::Struct,
             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
             ExprKind::Yield(..) => ExprPrecedence::Yield,
+            ExprKind::Err => ExprPrecedence::Err,
         }
     }
 
@@ -1412,7 +1413,8 @@ impl Expr {
             ExprKind::AddrOf(..) |
             ExprKind::Binary(..) |
             ExprKind::Yield(..) |
-            ExprKind::Cast(..) => {
+            ExprKind::Cast(..) |
+            ExprKind::Err => {
                 false
             }
         }
@@ -1525,6 +1527,9 @@ pub enum ExprKind {
 
     /// A suspension point for generators. This is `yield <expr>` in Rust.
     Yield(P<Expr>),
+
+    /// Placeholder for an expression that wasn't syntactically well formed in some way.
+    Err,
 }
 
 /// Optionally `Self`-qualified value/type path or associated extension.
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 9c869998d54..e19da011be1 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -430,7 +430,9 @@ impl<'a> State<'a> {
                 self.s.word("_")?;
             }
             hir::TyKind::Err => {
-                self.s.word("?")?;
+                self.popen()?;
+                self.s.word("/*ERROR*/")?;
+                self.pclose()?;
             }
         }
         self.end()
@@ -1540,6 +1542,11 @@ impl<'a> State<'a> {
                 self.word_space("yield")?;
                 self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?;
             }
+            hir::ExprKind::Err => {
+                self.popen()?;
+                self.s.word("/*ERROR*/")?;
+                self.pclose()?;
+            }
         }
         self.ann.post(self, AnnNode::Expr(expr))?;
         self.end()
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index f5d6827e89b..006f11d51e4 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -592,7 +592,8 @@ impl_stable_hash_for!(enum hir::ExprKind {
     InlineAsm(asm, inputs, outputs),
     Struct(path, fields, base),
     Repeat(val, times),
-    Yield(val)
+    Yield(val),
+    Err
 });
 
 impl_stable_hash_for!(enum hir::LocalSource {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index e6035d42f06..f9bcbb32229 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -479,7 +479,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
             }
 
             hir::ExprKind::Continue(..) |
-            hir::ExprKind::Lit(..) => {}
+            hir::ExprKind::Lit(..) |
+            hir::ExprKind::Err => {}
 
             hir::ExprKind::Loop(ref blk, _, _) => {
                 self.walk_block(&blk);
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 4b75840263e..a78cf1a471b 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -515,6 +515,7 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
       hir::ExprKind::Box(..) |
       hir::ExprKind::Yield(..) |
       hir::ExprKind::Type(..) |
+      hir::ExprKind::Err |
       hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
           intravisit::walk_expr(ir, expr);
       }
@@ -1254,7 +1255,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 self.propagate_through_exprs(inputs, succ)
             }
 
-            hir::ExprKind::Lit(..) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
+            hir::ExprKind::Lit(..) | hir::ExprKind::Err |
+            hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
                 succ
             }
 
@@ -1521,7 +1523,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
         hir::ExprKind::Block(..) | hir::ExprKind::AddrOf(..) |
         hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
         hir::ExprKind::Closure(..) | hir::ExprKind::Path(_) | hir::ExprKind::Yield(..) |
-        hir::ExprKind::Box(..) | hir::ExprKind::Type(..) => {
+        hir::ExprKind::Box(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err => {
             intravisit::walk_expr(this, expr);
         }
     }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index f32d7c54afe..207382d5e1f 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -687,7 +687,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
             hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) |
             hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) |
             hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
-            hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) => {
+            hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) | hir::ExprKind::Err => {
                 Ok(self.cat_rvalue_node(expr.hir_id, expr.span, expr_ty))
             }
         }
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 46d666cd81d..23cfd18ef5d 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -780,6 +780,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         hir::ExprKind::Tup(ref fields) => ExprKind::Tuple { fields: fields.to_ref() },
 
         hir::ExprKind::Yield(ref v) => ExprKind::Yield { value: v.to_ref() },
+        hir::ExprKind::Err => unreachable!(),
     };
 
     Expr {
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 2fa046a698a..f0b559f80a2 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -449,7 +449,8 @@ fn check_expr_kind<'a, 'tcx>(
             struct_result
         }
 
-        hir::ExprKind::Lit(_) => Promotable,
+        hir::ExprKind::Lit(_) |
+        hir::ExprKind::Err => Promotable,
 
         hir::ExprKind::AddrOf(_, ref expr) |
         hir::ExprKind::Repeat(ref expr, _) => {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 15a9ba99fa7..0cfe06451a7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4513,6 +4513,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 }
                 tcx.mk_unit()
             }
+            hir::ExprKind::Err => {
+                tcx.types.err
+            }
         }
     }
 
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 7e228d8d7cf..f0e567f9cd6 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1001,6 +1001,7 @@ impl Expr {
             ExprKind::Paren(..) => ExprPrecedence::Paren,
             ExprKind::Try(..) => ExprPrecedence::Try,
             ExprKind::Yield(..) => ExprPrecedence::Yield,
+            ExprKind::Err => ExprPrecedence::Err,
         }
     }
 }
@@ -1160,6 +1161,9 @@ pub enum ExprKind {
 
     /// A `yield`, with an optional value to be yielded.
     Yield(Option<P<Expr>>),
+
+    /// Placeholder for an expression that wasn't syntactically well formed in some way.
+    Err,
 }
 
 /// The explicit `Self` type in a "qualified path". The actual
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 0abc74c2314..b8990264c5d 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -1367,6 +1367,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
             ExprKind::Yield(ex) => ExprKind::Yield(ex.map(|x| folder.fold_expr(x))),
             ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)),
             ExprKind::TryBlock(body) => ExprKind::TryBlock(folder.fold_block(body)),
+            ExprKind::Err => ExprKind::Err,
         },
         id: folder.new_id(id),
         span: folder.new_span(span),
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 931e91e9c79..2ad3d3a6d64 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1093,7 +1093,9 @@ impl<'a> State<'a> {
                 self.s.word("_")?;
             }
             ast::TyKind::Err => {
-                self.s.word("?")?;
+                self.popen()?;
+                self.s.word("/*ERROR*/")?;
+                self.pclose()?;
             }
             ast::TyKind::ImplicitSelf => {
                 self.s.word("Self")?;
@@ -2391,6 +2393,11 @@ impl<'a> State<'a> {
                 self.s.space()?;
                 self.print_block_with_attrs(blk, attrs)?
             }
+            ast::ExprKind::Err => {
+                self.popen()?;
+                self.s.word("/*ERROR*/")?;
+                self.pclose()?
+            }
         }
         self.ann.post(self, AnnNode::Expr(expr))?;
         self.end()
diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs
index 52390fa5b1d..89d4e53b8d1 100644
--- a/src/libsyntax/util/parser.rs
+++ b/src/libsyntax/util/parser.rs
@@ -267,6 +267,7 @@ pub enum ExprPrecedence {
     TryBlock,
     Struct,
     Async,
+    Err,
 }
 
 impl ExprPrecedence {
@@ -325,7 +326,8 @@ impl ExprPrecedence {
             ExprPrecedence::Block |
             ExprPrecedence::TryBlock |
             ExprPrecedence::Async |
-            ExprPrecedence::Struct => PREC_PAREN,
+            ExprPrecedence::Struct |
+            ExprPrecedence::Err => PREC_PAREN,
         }
     }
 }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 43f8a13609e..156546bbba9 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -802,6 +802,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         ExprKind::TryBlock(ref body) => {
             visitor.visit_block(body)
         }
+        ExprKind::Err => {}
     }
 
     visitor.visit_expr_post(expression)