Skip to content

Commit a5c52c7

Browse files
committed
AST/HIR: Introduce ExprKind::Err for better error recovery in the front-end
1 parent d298697 commit a5c52c7

File tree

17 files changed

+51
-11
lines changed

17 files changed

+51
-11
lines changed

src/librustc/cfg/construct.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
392392

393393
hir::ExprKind::Closure(..) |
394394
hir::ExprKind::Lit(..) |
395-
hir::ExprKind::Path(_) => {
395+
hir::ExprKind::Path(_) |
396+
hir::ExprKind::Err => {
396397
self.straightline(expr, pred, None::<hir::Expr>.iter())
397398
}
398399
}

src/librustc/hir/intravisit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
10991099
ExprKind::Yield(ref subexpression) => {
11001100
visitor.visit_expr(subexpression);
11011101
}
1102+
ExprKind::Err => {}
11021103
}
11031104
}
11041105

src/librustc/hir/lowering.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4117,6 +4117,8 @@ impl<'a> LoweringContext<'a> {
41174117
hir::ExprKind::Yield(P(expr))
41184118
}
41194119

4120+
ExprKind::Err => hir::ExprKind::Err,
4121+
41204122
// Desugar `ExprIfLet`
41214123
// from: `if let <pat> = <sub_expr> <body> [<else_opt>]`
41224124
ExprKind::IfLet(ref pats, ref sub_expr, ref body, ref else_opt) => {

src/librustc/hir/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,7 @@ impl Expr {
13621362
ExprKind::Struct(..) => ExprPrecedence::Struct,
13631363
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
13641364
ExprKind::Yield(..) => ExprPrecedence::Yield,
1365+
ExprKind::Err => ExprPrecedence::Err,
13651366
}
13661367
}
13671368

@@ -1412,7 +1413,8 @@ impl Expr {
14121413
ExprKind::AddrOf(..) |
14131414
ExprKind::Binary(..) |
14141415
ExprKind::Yield(..) |
1415-
ExprKind::Cast(..) => {
1416+
ExprKind::Cast(..) |
1417+
ExprKind::Err => {
14161418
false
14171419
}
14181420
}
@@ -1525,6 +1527,9 @@ pub enum ExprKind {
15251527

15261528
/// A suspension point for generators. This is `yield <expr>` in Rust.
15271529
Yield(P<Expr>),
1530+
1531+
/// Placeholder for an expression that wasn't syntactically well formed in some way.
1532+
Err,
15281533
}
15291534

15301535
/// Optionally `Self`-qualified value/type path or associated extension.

src/librustc/hir/print.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,9 @@ impl<'a> State<'a> {
430430
self.s.word("_")?;
431431
}
432432
hir::TyKind::Err => {
433-
self.s.word("?")?;
433+
self.popen()?;
434+
self.s.word("/*ERROR*/")?;
435+
self.pclose()?;
434436
}
435437
}
436438
self.end()
@@ -1540,6 +1542,11 @@ impl<'a> State<'a> {
15401542
self.word_space("yield")?;
15411543
self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?;
15421544
}
1545+
hir::ExprKind::Err => {
1546+
self.popen()?;
1547+
self.s.word("/*ERROR*/")?;
1548+
self.pclose()?;
1549+
}
15431550
}
15441551
self.ann.post(self, AnnNode::Expr(expr))?;
15451552
self.end()

src/librustc/ich/impls_hir.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,8 @@ impl_stable_hash_for!(enum hir::ExprKind {
592592
InlineAsm(asm, inputs, outputs),
593593
Struct(path, fields, base),
594594
Repeat(val, times),
595-
Yield(val)
595+
Yield(val),
596+
Err
596597
});
597598

598599
impl_stable_hash_for!(enum hir::LocalSource {

src/librustc/middle/expr_use_visitor.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
479479
}
480480

481481
hir::ExprKind::Continue(..) |
482-
hir::ExprKind::Lit(..) => {}
482+
hir::ExprKind::Lit(..) |
483+
hir::ExprKind::Err => {}
483484

484485
hir::ExprKind::Loop(ref blk, _, _) => {
485486
self.walk_block(&blk);

src/librustc/middle/liveness.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
515515
hir::ExprKind::Box(..) |
516516
hir::ExprKind::Yield(..) |
517517
hir::ExprKind::Type(..) |
518+
hir::ExprKind::Err |
518519
hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
519520
intravisit::walk_expr(ir, expr);
520521
}
@@ -1254,7 +1255,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
12541255
self.propagate_through_exprs(inputs, succ)
12551256
}
12561257

1257-
hir::ExprKind::Lit(..) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
1258+
hir::ExprKind::Lit(..) | hir::ExprKind::Err |
1259+
hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
12581260
succ
12591261
}
12601262

@@ -1521,7 +1523,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
15211523
hir::ExprKind::Block(..) | hir::ExprKind::AddrOf(..) |
15221524
hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
15231525
hir::ExprKind::Closure(..) | hir::ExprKind::Path(_) | hir::ExprKind::Yield(..) |
1524-
hir::ExprKind::Box(..) | hir::ExprKind::Type(..) => {
1526+
hir::ExprKind::Box(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err => {
15251527
intravisit::walk_expr(this, expr);
15261528
}
15271529
}

src/librustc/middle/mem_categorization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
687687
hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) |
688688
hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) |
689689
hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
690-
hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) => {
690+
hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) | hir::ExprKind::Err => {
691691
Ok(self.cat_rvalue_node(expr.hir_id, expr.span, expr_ty))
692692
}
693693
}

src/librustc_mir/hair/cx/expr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
780780
hir::ExprKind::Tup(ref fields) => ExprKind::Tuple { fields: fields.to_ref() },
781781

782782
hir::ExprKind::Yield(ref v) => ExprKind::Yield { value: v.to_ref() },
783+
hir::ExprKind::Err => unreachable!(),
783784
};
784785

785786
Expr {

src/librustc_passes/rvalue_promotion.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,8 @@ fn check_expr_kind<'a, 'tcx>(
449449
struct_result
450450
}
451451

452-
hir::ExprKind::Lit(_) => Promotable,
452+
hir::ExprKind::Lit(_) |
453+
hir::ExprKind::Err => Promotable,
453454

454455
hir::ExprKind::AddrOf(_, ref expr) |
455456
hir::ExprKind::Repeat(ref expr, _) => {

src/librustc_typeck/check/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -4513,6 +4513,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
45134513
}
45144514
tcx.mk_unit()
45154515
}
4516+
hir::ExprKind::Err => {
4517+
tcx.types.err
4518+
}
45164519
}
45174520
}
45184521

src/libsyntax/ast.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ impl Expr {
10011001
ExprKind::Paren(..) => ExprPrecedence::Paren,
10021002
ExprKind::Try(..) => ExprPrecedence::Try,
10031003
ExprKind::Yield(..) => ExprPrecedence::Yield,
1004+
ExprKind::Err => ExprPrecedence::Err,
10041005
}
10051006
}
10061007
}
@@ -1160,6 +1161,9 @@ pub enum ExprKind {
11601161

11611162
/// A `yield`, with an optional value to be yielded.
11621163
Yield(Option<P<Expr>>),
1164+
1165+
/// Placeholder for an expression that wasn't syntactically well formed in some way.
1166+
Err,
11631167
}
11641168

11651169
/// The explicit `Self` type in a "qualified path". The actual

src/libsyntax/fold.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1367,6 +1367,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
13671367
ExprKind::Yield(ex) => ExprKind::Yield(ex.map(|x| folder.fold_expr(x))),
13681368
ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)),
13691369
ExprKind::TryBlock(body) => ExprKind::TryBlock(folder.fold_block(body)),
1370+
ExprKind::Err => ExprKind::Err,
13701371
},
13711372
id: folder.new_id(id),
13721373
span: folder.new_span(span),

src/libsyntax/print/pprust.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,9 @@ impl<'a> State<'a> {
10931093
self.s.word("_")?;
10941094
}
10951095
ast::TyKind::Err => {
1096-
self.s.word("?")?;
1096+
self.popen()?;
1097+
self.s.word("/*ERROR*/")?;
1098+
self.pclose()?;
10971099
}
10981100
ast::TyKind::ImplicitSelf => {
10991101
self.s.word("Self")?;
@@ -2391,6 +2393,11 @@ impl<'a> State<'a> {
23912393
self.s.space()?;
23922394
self.print_block_with_attrs(blk, attrs)?
23932395
}
2396+
ast::ExprKind::Err => {
2397+
self.popen()?;
2398+
self.s.word("/*ERROR*/")?;
2399+
self.pclose()?
2400+
}
23942401
}
23952402
self.ann.post(self, AnnNode::Expr(expr))?;
23962403
self.end()

src/libsyntax/util/parser.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ pub enum ExprPrecedence {
267267
TryBlock,
268268
Struct,
269269
Async,
270+
Err,
270271
}
271272

272273
impl ExprPrecedence {
@@ -325,7 +326,8 @@ impl ExprPrecedence {
325326
ExprPrecedence::Block |
326327
ExprPrecedence::TryBlock |
327328
ExprPrecedence::Async |
328-
ExprPrecedence::Struct => PREC_PAREN,
329+
ExprPrecedence::Struct |
330+
ExprPrecedence::Err => PREC_PAREN,
329331
}
330332
}
331333
}

src/libsyntax/visit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
802802
ExprKind::TryBlock(ref body) => {
803803
visitor.visit_block(body)
804804
}
805+
ExprKind::Err => {}
805806
}
806807

807808
visitor.visit_expr_post(expression)

0 commit comments

Comments
 (0)