Skip to content

Commit dd884e0

Browse files
committed
Do not discern between statements with and without semicolon after lowering to HIR
1 parent 374c63e commit dd884e0

19 files changed

+55
-146
lines changed

src/librustc/cfg/construct.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
106106
hir::StmtKind::Item(_) => {
107107
pred
108108
}
109-
hir::StmtKind::Expr(ref expr) |
110-
hir::StmtKind::Semi(ref expr) => {
109+
hir::StmtKind::Expr(ref expr) => {
111110
self.expr(&expr, pred)
112111
}
113112
};

src/librustc/hir/intravisit.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -967,8 +967,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
967967
match statement.node {
968968
StmtKind::Local(ref local) => visitor.visit_local(local),
969969
StmtKind::Item(item) => visitor.visit_nested_item(item),
970-
StmtKind::Expr(ref expression) |
971-
StmtKind::Semi(ref expression) => {
970+
StmtKind::Expr(ref expression) => {
972971
visitor.visit_expr(expression)
973972
}
974973
}

src/librustc/hir/lowering.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -4902,12 +4902,11 @@ impl<'a> LoweringContext<'a> {
49024902

49034903
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
49044904
let body_expr = P(self.expr_block(body_block, ThinVec::new()));
4905-
let body_stmt = self.stmt(body.span, hir::StmtKind::Expr(body_expr));
49064905

49074906
let loop_block = P(self.block_all(
49084907
e.span,
4909-
hir_vec![next_let, match_stmt, pat_let, body_stmt],
4910-
None,
4908+
hir_vec![next_let, match_stmt, pat_let],
4909+
Some(body_expr),
49114910
));
49124911

49134912
// `[opt_ident]: loop { ... }`
@@ -5110,20 +5109,13 @@ impl<'a> LoweringContext<'a> {
51105109
})
51115110
.collect();
51125111
}
5113-
StmtKind::Expr(ref e) => {
5112+
StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => {
51145113
hir::Stmt {
51155114
hir_id: self.lower_node_id(s.id),
51165115
node: hir::StmtKind::Expr(P(self.lower_expr(e))),
51175116
span: s.span,
51185117
}
51195118
},
5120-
StmtKind::Semi(ref e) => {
5121-
hir::Stmt {
5122-
hir_id: self.lower_node_id(s.id),
5123-
node: hir::StmtKind::Semi(P(self.lower_expr(e))),
5124-
span: s.span,
5125-
}
5126-
},
51275119
StmtKind::Mac(..) => panic!("Shouldn't exist here"),
51285120
}]
51295121
}

src/librustc/hir/mod.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1205,20 +1205,16 @@ pub enum StmtKind {
12051205
/// An item binding.
12061206
Item(ItemId),
12071207

1208-
/// An expression without a trailing semi-colon (must have unit type).
1208+
/// An expression statement.
12091209
Expr(P<Expr>),
1210-
1211-
/// An expression with a trailing semi-colon (may have any type).
1212-
Semi(P<Expr>),
12131210
}
12141211

12151212
impl StmtKind {
12161213
pub fn attrs(&self) -> &[Attribute] {
12171214
match *self {
12181215
StmtKind::Local(ref l) => &l.attrs,
12191216
StmtKind::Item(_) => &[],
1220-
StmtKind::Expr(ref e) |
1221-
StmtKind::Semi(ref e) => &e.attrs,
1217+
StmtKind::Expr(ref e) => &e.attrs,
12221218
}
12231219
}
12241220
}

src/librustc/hir/print.rs

+1-37
Original file line numberDiff line numberDiff line change
@@ -992,23 +992,17 @@ impl<'a> State<'a> {
992992
match st.node {
993993
hir::StmtKind::Local(ref loc) => {
994994
self.print_local(loc.init.deref(), |this| this.print_local_decl(&loc))?;
995+
self.s.word(";")?;
995996
}
996997
hir::StmtKind::Item(item) => {
997998
self.ann.nested(self, Nested::Item(item))?
998999
}
9991000
hir::StmtKind::Expr(ref expr) => {
10001001
self.space_if_not_bol()?;
10011002
self.print_expr(&expr)?;
1002-
}
1003-
hir::StmtKind::Semi(ref expr) => {
1004-
self.space_if_not_bol()?;
1005-
self.print_expr(&expr)?;
10061003
self.s.word(";")?;
10071004
}
10081005
}
1009-
if stmt_ends_with_semi(&st.node) {
1010-
self.s.word(";")?;
1011-
}
10121006
self.maybe_print_trailing_comment(st.span, None)
10131007
}
10141008

@@ -2325,36 +2319,6 @@ impl<'a> State<'a> {
23252319
}
23262320
}
23272321

2328-
// Dup'ed from parse::classify, but adapted for the HIR.
2329-
/// Does this expression require a semicolon to be treated
2330-
/// as a statement? The negation of this: 'can this expression
2331-
/// be used as a statement without a semicolon' -- is used
2332-
/// as an early-bail-out in the parser so that, for instance,
2333-
/// if true {...} else {...}
2334-
/// |x| 5
2335-
/// isn't parsed as (if true {...} else {...} | x) | 5
2336-
fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
2337-
match e.node {
2338-
hir::ExprKind::Match(..) |
2339-
hir::ExprKind::Block(..) |
2340-
hir::ExprKind::While(..) |
2341-
hir::ExprKind::Loop(..) => false,
2342-
_ => true,
2343-
}
2344-
}
2345-
2346-
/// this statement requires a semicolon after it.
2347-
/// note that in one case (stmt_semi), we've already
2348-
/// seen the semicolon, and thus don't need another.
2349-
fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool {
2350-
match *stmt {
2351-
hir::StmtKind::Local(_) => true,
2352-
hir::StmtKind::Item(_) => false,
2353-
hir::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(&e),
2354-
hir::StmtKind::Semi(..) => false,
2355-
}
2356-
}
2357-
23582322
fn bin_op_to_assoc_op(op: hir::BinOpKind) -> AssocOp {
23592323
use crate::hir::BinOpKind::*;
23602324
match op {

src/librustc/middle/expr_use_visitor.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -603,8 +603,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
603603
// only the fn body we were given.
604604
}
605605

606-
hir::StmtKind::Expr(ref expr) |
607-
hir::StmtKind::Semi(ref expr) => {
606+
hir::StmtKind::Expr(ref expr) => {
608607
self.consume_expr(&expr);
609608
}
610609
}

src/librustc/middle/liveness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
10041004
self.define_bindings_in_pat(&local.pat, succ)
10051005
}
10061006
hir::StmtKind::Item(..) => succ,
1007-
hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => {
1007+
hir::StmtKind::Expr(ref expr) => {
10081008
self.propagate_through_expr(&expr, succ)
10091009
}
10101010
}

src/librustc/middle/region.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -804,8 +804,7 @@ fn resolve_block<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, blk: &'tcx h
804804
);
805805
visitor.cx.var_parent = visitor.cx.parent;
806806
}
807-
hir::StmtKind::Expr(..) |
808-
hir::StmtKind::Semi(..) => {}
807+
hir::StmtKind::Expr(..) => {}
809808
}
810809
visitor.visit_stmt(statement)
811810
}

src/librustc_lint/unused.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ declare_lint_pass!(UnusedResults => [UNUSED_MUST_USE, UNUSED_RESULTS]);
3939
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
4040
fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) {
4141
let expr = match s.node {
42-
hir::StmtKind::Semi(ref expr) => &**expr,
42+
hir::StmtKind::Expr(ref expr) => &**expr,
4343
_ => return,
4444
};
4545

@@ -227,7 +227,7 @@ declare_lint_pass!(PathStatements => [PATH_STATEMENTS]);
227227

228228
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PathStatements {
229229
fn check_stmt(&mut self, cx: &LateContext<'_, '_>, s: &hir::Stmt) {
230-
if let hir::StmtKind::Semi(ref expr) = s.node {
230+
if let hir::StmtKind::Expr(ref expr) = s.node {
231231
if let hir::ExprKind::Path(_) = expr.node {
232232
cx.span_lint(PATH_STATEMENTS, s.span, "path statement with no effect");
233233
}

src/librustc_mir/hair/cx/block.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ fn mirror_stmts<'a, 'tcx>(
5151
let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
5252
let stmt_span = StatementSpan(cx.tcx.hir().span_by_hir_id(hir_id));
5353
match stmt.node {
54-
hir::StmtKind::Expr(ref expr) |
55-
hir::StmtKind::Semi(ref expr) => {
54+
hir::StmtKind::Expr(ref expr) => {
5655
result.push(StmtRef::Mirror(Box::new(Stmt {
5756
kind: StmtKind::Expr {
5857
scope: region::Scope {

src/librustc_passes/rvalue_promotion.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
227227
}
228228
// Item statements are allowed
229229
hir::StmtKind::Item(..) => Promotable,
230-
hir::StmtKind::Expr(ref box_expr) |
231-
hir::StmtKind::Semi(ref box_expr) => {
230+
hir::StmtKind::Expr(ref box_expr) => {
232231
let _ = self.check_expr(box_expr);
233232
NotPromotable
234233
}

src/librustc_typeck/check/mod.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -4851,7 +4851,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
48514851
// Don't do all the complex logic below for `DeclItem`.
48524852
match stmt.node {
48534853
hir::StmtKind::Item(..) => return,
4854-
hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
4854+
hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) => {}
48554855
}
48564856

48574857
self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
@@ -4869,10 +4869,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
48694869
// Ignore for now.
48704870
hir::StmtKind::Item(_) => {}
48714871
hir::StmtKind::Expr(ref expr) => {
4872-
// Check with expected type of `()`.
4873-
self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
4874-
}
4875-
hir::StmtKind::Semi(ref expr) => {
48764872
self.check_expr(&expr);
48774873
}
48784874
}
@@ -5289,7 +5285,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
52895285
// taking the `;` off is enough to fix the error.
52905286
let last_stmt = blk.stmts.last()?;
52915287
let last_expr = match last_stmt.node {
5292-
hir::StmtKind::Semi(ref e) => e,
5288+
hir::StmtKind::Expr(ref e) => e,
52935289
_ => return None,
52945290
};
52955291
let last_expr_ty = self.node_ty(last_expr.hir_id);

src/test/ui/parser/expr-as-stmt.fixed

-4
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,20 @@
55

66
fn foo() -> i32 {
77
({2}) + {2} //~ ERROR expected expression, found `+`
8-
//~^ ERROR mismatched types
98
}
109

1110
fn bar() -> i32 {
1211
({2}) + 2 //~ ERROR expected expression, found `+`
13-
//~^ ERROR mismatched types
1412
}
1513

1614
fn zul() -> u32 {
1715
let foo = 3;
1816
({ 42 }) + foo; //~ ERROR expected expression, found `+`
19-
//~^ ERROR mismatched types
2017
32
2118
}
2219

2320
fn baz() -> i32 {
2421
({ 3 }) * 3 //~ ERROR type `{integer}` cannot be dereferenced
25-
//~^ ERROR mismatched types
2622
}
2723

2824
fn qux(a: Option<u32>, b: Option<u32>) -> bool {

src/test/ui/parser/expr-as-stmt.rs

-4
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,20 @@
55

66
fn foo() -> i32 {
77
{2} + {2} //~ ERROR expected expression, found `+`
8-
//~^ ERROR mismatched types
98
}
109

1110
fn bar() -> i32 {
1211
{2} + 2 //~ ERROR expected expression, found `+`
13-
//~^ ERROR mismatched types
1412
}
1513

1614
fn zul() -> u32 {
1715
let foo = 3;
1816
{ 42 } + foo; //~ ERROR expected expression, found `+`
19-
//~^ ERROR mismatched types
2017
32
2118
}
2219

2320
fn baz() -> i32 {
2421
{ 3 } * 3 //~ ERROR type `{integer}` cannot be dereferenced
25-
//~^ ERROR mismatched types
2622
}
2723

2824
fn qux(a: Option<u32>, b: Option<u32>) -> bool {

src/test/ui/parser/expr-as-stmt.stderr

+7-44
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,31 @@ LL | {2} + {2}
77
| help: parentheses are required to parse this as an expression: `({2})`
88

99
error: expected expression, found `+`
10-
--> $DIR/expr-as-stmt.rs:12:9
10+
--> $DIR/expr-as-stmt.rs:11:9
1111
|
1212
LL | {2} + 2
1313
| --- ^ expected expression
1414
| |
1515
| help: parentheses are required to parse this as an expression: `({2})`
1616

1717
error: expected expression, found `+`
18-
--> $DIR/expr-as-stmt.rs:18:12
18+
--> $DIR/expr-as-stmt.rs:16:12
1919
|
2020
LL | { 42 } + foo;
2121
| ------ ^ expected expression
2222
| |
2323
| help: parentheses are required to parse this as an expression: `({ 42 })`
2424

2525
error: expected expression, found `&&`
26-
--> $DIR/expr-as-stmt.rs:30:5
26+
--> $DIR/expr-as-stmt.rs:26:5
2727
|
2828
LL | if let Some(x) = a { true } else { false }
2929
| ------------------------------------------ help: parentheses are required to parse this as an expression: `(if let Some(x) = a { true } else { false })`
3030
LL | &&
3131
| ^^ expected expression
3232

3333
error: expected expression, found `>`
34-
--> $DIR/expr-as-stmt.rs:37:7
34+
--> $DIR/expr-as-stmt.rs:33:7
3535
|
3636
LL | } > 0
3737
| ^ expected expression
@@ -42,51 +42,14 @@ LL | _ => 1,
4242
LL | }) > 0
4343
|
4444

45-
error[E0308]: mismatched types
46-
--> $DIR/expr-as-stmt.rs:7:6
47-
|
48-
LL | {2} + {2}
49-
| ^ expected (), found integer
50-
|
51-
= note: expected type `()`
52-
found type `{integer}`
53-
54-
error[E0308]: mismatched types
55-
--> $DIR/expr-as-stmt.rs:12:6
56-
|
57-
LL | {2} + 2
58-
| ^ expected (), found integer
59-
|
60-
= note: expected type `()`
61-
found type `{integer}`
62-
63-
error[E0308]: mismatched types
64-
--> $DIR/expr-as-stmt.rs:18:7
65-
|
66-
LL | { 42 } + foo;
67-
| ^^ expected (), found integer
68-
|
69-
= note: expected type `()`
70-
found type `{integer}`
71-
72-
error[E0308]: mismatched types
73-
--> $DIR/expr-as-stmt.rs:24:7
74-
|
75-
LL | { 3 } * 3
76-
| ^ expected (), found integer
77-
|
78-
= note: expected type `()`
79-
found type `{integer}`
80-
8145
error[E0614]: type `{integer}` cannot be dereferenced
82-
--> $DIR/expr-as-stmt.rs:24:11
46+
--> $DIR/expr-as-stmt.rs:21:11
8347
|
8448
LL | { 3 } * 3
8549
| ----- ^^^
8650
| |
8751
| help: parentheses are required to parse this as an expression: `({ 3 })`
8852

89-
error: aborting due to 10 previous errors
53+
error: aborting due to 6 previous errors
9054

91-
Some errors have detailed explanations: E0308, E0614.
92-
For more information about an error, try `rustc --explain E0308`.
55+
For more information about this error, try `rustc --explain E0614`.

src/test/ui/resolve/token-error-correct-3.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ pub mod raw {
1515
callback(path.as_ref();
1616
//~^ ERROR expected one of
1717
fs::create_dir_all(path.as_ref()).map(|()| true)
18-
//~^ ERROR mismatched types
1918
} else {
2019
//~^ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
2120
Ok(false);
21+
//~^ ERROR if and else have incompatible types
2222
}
2323

2424
panic!();

0 commit comments

Comments
 (0)