Skip to content

Commit 49f5106

Browse files
committed
AST/HIR: Introduce ExprKind::Err for better error recovery in the front-end
1 parent 09d6ab9 commit 49f5106

File tree

17 files changed

+51
-11
lines changed

17 files changed

+51
-11
lines changed

src/librustc/cfg/construct.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
402402

403403
hir::ExprKind::Closure(..) |
404404
hir::ExprKind::Lit(..) |
405-
hir::ExprKind::Path(_) => {
405+
hir::ExprKind::Path(_) |
406+
hir::ExprKind::Err => {
406407
self.straightline(expr, pred, None::<hir::Expr>.iter())
407408
}
408409
}

src/librustc/hir/intravisit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
11091109
ExprKind::Yield(ref subexpression) => {
11101110
visitor.visit_expr(subexpression);
11111111
}
1112+
ExprKind::Err => {}
11121113
}
11131114
}
11141115

src/librustc/hir/lowering.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4127,6 +4127,8 @@ impl<'a> LoweringContext<'a> {
41274127
hir::ExprKind::Yield(P(expr))
41284128
}
41294129

4130+
ExprKind::Err => hir::ExprKind::Err,
4131+
41304132
// Desugar `ExprIfLet`
41314133
// from: `if let <pat> = <sub_expr> <body> [<else_opt>]`
41324134
ExprKind::IfLet(ref pats, ref sub_expr, ref body, ref else_opt) => {

src/librustc/hir/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,7 @@ impl Expr {
13721372
ExprKind::Struct(..) => ExprPrecedence::Struct,
13731373
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
13741374
ExprKind::Yield(..) => ExprPrecedence::Yield,
1375+
ExprKind::Err => ExprPrecedence::Err,
13751376
}
13761377
}
13771378

@@ -1422,7 +1423,8 @@ impl Expr {
14221423
ExprKind::AddrOf(..) |
14231424
ExprKind::Binary(..) |
14241425
ExprKind::Yield(..) |
1425-
ExprKind::Cast(..) => {
1426+
ExprKind::Cast(..) |
1427+
ExprKind::Err => {
14261428
false
14271429
}
14281430
}
@@ -1535,6 +1537,9 @@ pub enum ExprKind {
15351537

15361538
/// A suspension point for generators. This is `yield <expr>` in Rust.
15371539
Yield(P<Expr>),
1540+
1541+
/// Placeholder for an expression that wasn't syntactically well formed in some way.
1542+
Err,
15381543
}
15391544

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

src/librustc/hir/print.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,9 @@ impl<'a> State<'a> {
440440
self.s.word("_")?;
441441
}
442442
hir::TyKind::Err => {
443-
self.s.word("?")?;
443+
self.popen()?;
444+
self.s.word("/*ERROR*/")?;
445+
self.pclose()?;
444446
}
445447
}
446448
self.end()
@@ -1550,6 +1552,11 @@ impl<'a> State<'a> {
15501552
self.word_space("yield")?;
15511553
self.print_expr_maybe_paren(&expr, parser::PREC_JUMP)?;
15521554
}
1555+
hir::ExprKind::Err => {
1556+
self.popen()?;
1557+
self.s.word("/*ERROR*/")?;
1558+
self.pclose()?;
1559+
}
15531560
}
15541561
self.ann.post(self, AnnNode::Expr(expr))?;
15551562
self.end()

src/librustc/ich/impls_hir.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,8 @@ impl_stable_hash_for!(enum hir::ExprKind {
602602
InlineAsm(asm, inputs, outputs),
603603
Struct(path, fields, base),
604604
Repeat(val, times),
605-
Yield(val)
605+
Yield(val),
606+
Err
606607
});
607608

608609
impl_stable_hash_for!(enum hir::LocalSource {

src/librustc/middle/expr_use_visitor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
489489
}
490490

491491
hir::ExprKind::Continue(..) |
492-
hir::ExprKind::Lit(..) => {}
492+
hir::ExprKind::Lit(..) |
493+
hir::ExprKind::Err => {}
493494

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

src/librustc/middle/liveness.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
525525
hir::ExprKind::Box(..) |
526526
hir::ExprKind::Yield(..) |
527527
hir::ExprKind::Type(..) |
528+
hir::ExprKind::Err |
528529
hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
529530
intravisit::walk_expr(ir, expr);
530531
}
@@ -1264,7 +1265,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
12641265
self.propagate_through_exprs(inputs, succ)
12651266
}
12661267

1267-
hir::ExprKind::Lit(..) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
1268+
hir::ExprKind::Lit(..) | hir::ExprKind::Err |
1269+
hir::ExprKind::Path(hir::QPath::TypeRelative(..)) => {
12681270
succ
12691271
}
12701272

@@ -1531,7 +1533,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
15311533
hir::ExprKind::Block(..) | hir::ExprKind::AddrOf(..) |
15321534
hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
15331535
hir::ExprKind::Closure(..) | hir::ExprKind::Path(_) | hir::ExprKind::Yield(..) |
1534-
hir::ExprKind::Box(..) | hir::ExprKind::Type(..) => {
1536+
hir::ExprKind::Box(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err => {
15351537
intravisit::walk_expr(this, expr);
15361538
}
15371539
}

src/librustc/middle/mem_categorization.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
697697
hir::ExprKind::Block(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..) |
698698
hir::ExprKind::Lit(..) | hir::ExprKind::Break(..) |
699699
hir::ExprKind::Continue(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) |
700-
hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) => {
700+
hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) | hir::ExprKind::Err => {
701701
Ok(self.cat_rvalue_node(expr.hir_id, expr.span, expr_ty))
702702
}
703703
}

src/librustc_mir/hair/cx/expr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
790790
hir::ExprKind::Tup(ref fields) => ExprKind::Tuple { fields: fields.to_ref() },
791791

792792
hir::ExprKind::Yield(ref v) => ExprKind::Yield { value: v.to_ref() },
793+
hir::ExprKind::Err => unreachable!(),
793794
};
794795

795796
Expr {

src/librustc_passes/rvalue_promotion.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,8 @@ fn check_expr_kind<'a, 'tcx>(
459459
struct_result
460460
}
461461

462-
hir::ExprKind::Lit(_) => Promotable,
462+
hir::ExprKind::Lit(_) |
463+
hir::ExprKind::Err => Promotable,
463464

464465
hir::ExprKind::AddrOf(_, ref expr) |
465466
hir::ExprKind::Repeat(ref expr, _) => {

src/librustc_typeck/check/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4498,6 +4498,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
44984498
}
44994499
tcx.mk_unit()
45004500
}
4501+
hir::ExprKind::Err => {
4502+
tcx.types.err
4503+
}
45014504
}
45024505
}
45034506

src/libsyntax/ast.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,7 @@ impl Expr {
10111011
ExprKind::Paren(..) => ExprPrecedence::Paren,
10121012
ExprKind::Try(..) => ExprPrecedence::Try,
10131013
ExprKind::Yield(..) => ExprPrecedence::Yield,
1014+
ExprKind::Err => ExprPrecedence::Err,
10141015
}
10151016
}
10161017
}
@@ -1170,6 +1171,9 @@ pub enum ExprKind {
11701171

11711172
/// A `yield`, with an optional value to be yielded.
11721173
Yield(Option<P<Expr>>),
1174+
1175+
/// Placeholder for an expression that wasn't syntactically well formed in some way.
1176+
Err,
11731177
}
11741178

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

src/libsyntax/fold.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
13771377
ExprKind::Yield(ex) => ExprKind::Yield(ex.map(|x| folder.fold_expr(x))),
13781378
ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)),
13791379
ExprKind::TryBlock(body) => ExprKind::TryBlock(folder.fold_block(body)),
1380+
ExprKind::Err => ExprKind::Err,
13801381
},
13811382
id: folder.new_id(id),
13821383
span: folder.new_span(span),

src/libsyntax/print/pprust.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,9 @@ impl<'a> State<'a> {
11031103
self.s.word("_")?;
11041104
}
11051105
ast::TyKind::Err => {
1106-
self.s.word("?")?;
1106+
self.popen()?;
1107+
self.s.word("/*ERROR*/")?;
1108+
self.pclose()?;
11071109
}
11081110
ast::TyKind::ImplicitSelf => {
11091111
self.s.word("Self")?;
@@ -2401,6 +2403,11 @@ impl<'a> State<'a> {
24012403
self.s.space()?;
24022404
self.print_block_with_attrs(blk, attrs)?
24032405
}
2406+
ast::ExprKind::Err => {
2407+
self.popen()?;
2408+
self.s.word("/*ERROR*/")?;
2409+
self.pclose()?
2410+
}
24042411
}
24052412
self.ann.post(self, AnnNode::Expr(expr))?;
24062413
self.end()

src/libsyntax/util/parser.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ pub enum ExprPrecedence {
276276
TryBlock,
277277
Struct,
278278
Async,
279+
Err,
279280
}
280281

281282
impl ExprPrecedence {
@@ -334,7 +335,8 @@ impl ExprPrecedence {
334335
ExprPrecedence::Block |
335336
ExprPrecedence::TryBlock |
336337
ExprPrecedence::Async |
337-
ExprPrecedence::Struct => PREC_PAREN,
338+
ExprPrecedence::Struct |
339+
ExprPrecedence::Err => PREC_PAREN,
338340
}
339341
}
340342
}

src/libsyntax/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
812812
ExprKind::TryBlock(ref body) => {
813813
visitor.visit_block(body)
814814
}
815+
ExprKind::Err => {}
815816
}
816817

817818
visitor.visit_expr_post(expression)

0 commit comments

Comments
 (0)