diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 17198040d25b..e67d3f6991af 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -1412,21 +1412,18 @@ impl<'a> Parser<'a> {
// verify that the last statement is either an implicit return (no `;`) or an explicit
// return. This won't catch blocks with an explicit `return`, but that would be caught by
// the dead code lint.
- if self.eat_keyword(kw::Else) || !cond.returns() {
- let sp = self.sess.source_map().next_point(lo);
- let mut err =
- self.diagnostic().struct_span_err(sp, "missing condition for `if` expression");
- err.span_label(sp, "expected if condition here");
- return Err(err);
- }
- let not_block = self.token != token::OpenDelim(token::Brace);
- let thn = self.parse_block().map_err(|mut err| {
- if not_block {
- err.span_label(lo, "this `if` statement has a condition, but no block");
- }
- err
- })?;
- let mut els: Option
> = None;
+ let thn = if self.eat_keyword(kw::Else) || !cond.returns() {
+ self.error_missing_if_cond(lo, cond.span)
+ } else {
+ let not_block = self.token != token::OpenDelim(token::Brace);
+ self.parse_block().map_err(|mut err| {
+ if not_block {
+ err.span_label(lo, "this `if` expression has a condition, but no block");
+ }
+ err
+ })?
+ };
+ let mut els = None;
let mut hi = thn.span;
if self.eat_keyword(kw::Else) {
let elexpr = self.parse_else_expr()?;
@@ -1436,6 +1433,16 @@ impl<'a> Parser<'a> {
Ok(self.mk_expr(lo.to(hi), ExprKind::If(cond, thn, els), attrs))
}
+ fn error_missing_if_cond(&self, lo: Span, span: Span) -> P {
+ let sp = self.sess.source_map().next_point(lo);
+ self.struct_span_err(sp, "missing condition for `if` expression")
+ .span_label(sp, "expected if condition here")
+ .emit();
+ let expr = self.mk_expr_err(span);
+ let stmt = self.mk_stmt(span, ast::StmtKind::Expr(expr));
+ self.mk_block(vec![stmt], BlockCheckMode::Default, span)
+ }
+
/// Parses the condition of a `if` or `while` expression.
fn parse_cond_expr(&mut self) -> PResult<'a, P> {
let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
@@ -1465,10 +1472,10 @@ impl<'a> Parser<'a> {
/// Parses an `else { ... }` expression (`else` token already eaten).
fn parse_else_expr(&mut self) -> PResult<'a, P> {
if self.eat_keyword(kw::If) {
- return self.parse_if_expr(AttrVec::new());
+ self.parse_if_expr(AttrVec::new())
} else {
let blk = self.parse_block()?;
- return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()));
+ Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()))
}
}
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index ed5649310e3f..44a197503bd7 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -411,7 +411,7 @@ impl<'a> Parser<'a> {
continue;
};
}
- Ok(P(ast::Block { stmts, id: DUMMY_NODE_ID, rules: s, span: lo.to(self.prev_span) }))
+ Ok(self.mk_block(stmts, s, lo.to(self.prev_span)))
}
/// Parses a statement, including the trailing semicolon.
@@ -471,7 +471,11 @@ impl<'a> Parser<'a> {
.emit();
}
- fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt {
+ pub(super) fn mk_block(&self, stmts: Vec, rules: BlockCheckMode, span: Span) -> P {
+ P(Block { stmts, id: DUMMY_NODE_ID, rules, span })
+ }
+
+ pub(super) fn mk_stmt(&self, span: Span, kind: StmtKind) -> Stmt {
Stmt { id: DUMMY_NODE_ID, kind, span }
}
}
diff --git a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr
index f5edbe2a3af5..8025886a9eb4 100644
--- a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr
+++ b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr
@@ -26,7 +26,7 @@ error: expected `{`, found `;`
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:31
|
LL | if not // lack of braces is [sic]
- | -- this `if` statement has a condition, but no block
+ | -- this `if` expression has a condition, but no block
LL | println!("Then when?");
| ^
| |
diff --git a/src/test/ui/if/if-without-block.rs b/src/test/ui/if/if-without-block.rs
index 3dde0ed7c718..8a4c59f32613 100644
--- a/src/test/ui/if/if-without-block.rs
+++ b/src/test/ui/if/if-without-block.rs
@@ -1,7 +1,7 @@
fn main() {
let n = 1;
if 5 == {
- //~^ NOTE this `if` statement has a condition, but no block
+ //~^ NOTE this `if` expression has a condition, but no block
println!("five");
}
}
diff --git a/src/test/ui/if/if-without-block.stderr b/src/test/ui/if/if-without-block.stderr
index 1e45045adece..34df8e3d7794 100644
--- a/src/test/ui/if/if-without-block.stderr
+++ b/src/test/ui/if/if-without-block.stderr
@@ -2,7 +2,7 @@ error: expected `{`, found `}`
--> $DIR/if-without-block.rs:7:1
|
LL | if 5 == {
- | -- this `if` statement has a condition, but no block
+ | -- this `if` expression has a condition, but no block
...
LL | }
| ^ expected `{`
diff --git a/src/test/ui/issues/issue-13483.rs b/src/test/ui/issues/issue-13483.rs
index cb53523b3b04..a2fd9264b153 100644
--- a/src/test/ui/issues/issue-13483.rs
+++ b/src/test/ui/issues/issue-13483.rs
@@ -1,6 +1,7 @@
fn main() {
if true {
} else if { //~ ERROR missing condition
+ //~^ ERROR mismatched types
} else {
}
}
@@ -8,6 +9,7 @@ fn main() {
fn foo() {
if true {
} else if { //~ ERROR missing condition
+ //~^ ERROR mismatched types
}
bar();
}
diff --git a/src/test/ui/issues/issue-13483.stderr b/src/test/ui/issues/issue-13483.stderr
index df9f1dd0115d..5fd05b18ce06 100644
--- a/src/test/ui/issues/issue-13483.stderr
+++ b/src/test/ui/issues/issue-13483.stderr
@@ -5,10 +5,29 @@ LL | } else if {
| ^ expected if condition here
error: missing condition for `if` expression
- --> $DIR/issue-13483.rs:10:14
+ --> $DIR/issue-13483.rs:11:14
|
LL | } else if {
| ^ expected if condition here
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+ --> $DIR/issue-13483.rs:3:15
+ |
+LL | } else if {
+ | _______________^
+LL | |
+LL | | } else {
+ | |_____^ expected `bool`, found `()`
+error[E0308]: mismatched types
+ --> $DIR/issue-13483.rs:11:15
+ |
+LL | } else if {
+ | _______________^
+LL | |
+LL | | }
+ | |_____^ expected `bool`, found `()`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-39848.stderr b/src/test/ui/issues/issue-39848.stderr
index 47aa8e17a304..11b145d6e0dc 100644
--- a/src/test/ui/issues/issue-39848.stderr
+++ b/src/test/ui/issues/issue-39848.stderr
@@ -4,7 +4,7 @@ error: expected `{`, found `foo`
LL | if $tgt.has_$field() {}
| -- -- help: try placing this code inside a block: `{ () }`
| |
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
...
LL | get_opt!(bar, foo);
| ^^^ expected `{`
diff --git a/src/test/ui/issues/issue-51602.stderr b/src/test/ui/issues/issue-51602.stderr
index 1ad69c0191b5..d800890bca38 100644
--- a/src/test/ui/issues/issue-51602.stderr
+++ b/src/test/ui/issues/issue-51602.stderr
@@ -4,7 +4,7 @@ error: expected `{`, found keyword `in`
LL | if i in 1..10 {
| -- ^^ expected `{`
| |
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-61858.stderr b/src/test/ui/issues/issue-61858.stderr
index ea2ec3d013f5..8b95d9c6ae48 100644
--- a/src/test/ui/issues/issue-61858.stderr
+++ b/src/test/ui/issues/issue-61858.stderr
@@ -4,7 +4,7 @@ error: expected `{`, found `)`
LL | (if foobar)
| -- ^ expected `{`
| |
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-62554.stderr b/src/test/ui/issues/issue-62554.stderr
index 87aaa0366132..d59546e23839 100644
--- a/src/test/ui/issues/issue-62554.stderr
+++ b/src/test/ui/issues/issue-62554.stderr
@@ -17,7 +17,7 @@ error: expected `{`, found `macro_rules`
LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
| -- ^^^^^^^^^^^ expected `{`
| |
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
|
help: try placing this code inside a block
|
diff --git a/src/test/ui/label/label_break_value_illegal_uses.stderr b/src/test/ui/label/label_break_value_illegal_uses.stderr
index 0036f0f1db0f..46b53c65b481 100644
--- a/src/test/ui/label/label_break_value_illegal_uses.stderr
+++ b/src/test/ui/label/label_break_value_illegal_uses.stderr
@@ -12,7 +12,7 @@ LL | if true 'b: {}
| | |
| | expected `{`
| | help: try placing this code inside a block: `{ 'b: {} }`
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
error: expected `{`, found `'b`
--> $DIR/label_break_value_illegal_uses.rs:14:21
diff --git a/src/test/ui/missing/missing-block-hint.stderr b/src/test/ui/missing/missing-block-hint.stderr
index ee86a3241e82..0f635817bf46 100644
--- a/src/test/ui/missing/missing-block-hint.stderr
+++ b/src/test/ui/missing/missing-block-hint.stderr
@@ -4,13 +4,13 @@ error: expected `{`, found `=>`
LL | if (foo) => {}
| -- ^^ expected `{`
| |
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
error: expected `{`, found `bar`
--> $DIR/missing-block-hint.rs:7:13
|
LL | if (foo)
- | -- this `if` statement has a condition, but no block
+ | -- this `if` expression has a condition, but no block
LL | bar;
| ^^^-
| |
diff --git a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr
index 9a0d3176714f..30aa820141cf 100644
--- a/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr
+++ b/src/test/ui/parser/attr-stmt-expr-attr-bad.stderr
@@ -149,7 +149,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 #[attr] {}; }
| -- ^ --- help: try placing this code inside a block: `{ {}; }`
| | |
| | expected `{`
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:43:38
@@ -202,7 +202,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if 0 {} else if 0 #[attr] {}; }
| -- ^ --- help: try placing this code inside a block: `{ {}; }`
| | |
| | expected `{`
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:56:51
@@ -225,7 +225,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 #[attr] {}; }
| -- ^ --- help: try placing this code inside a block: `{ {}; }`
| | |
| | expected `{`
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:62:46
@@ -278,7 +278,7 @@ LL | #[cfg(FALSE)] fn e() { let _ = if let _ = 0 {} else if let _ = 0 #[attr] {}
| -- ^ --- help: try placing this code inside a block: `{ {}; }`
| | |
| | expected `{`
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
error: an inner attribute is not permitted in this context
--> $DIR/attr-stmt-expr-attr-bad.rs:75:67
diff --git a/src/test/ui/parser/doc-comment-in-if-statement.stderr b/src/test/ui/parser/doc-comment-in-if-statement.stderr
index 6bcb77385d7d..a720dd68bd03 100644
--- a/src/test/ui/parser/doc-comment-in-if-statement.stderr
+++ b/src/test/ui/parser/doc-comment-in-if-statement.stderr
@@ -4,7 +4,7 @@ error: expected `{`, found doc comment `/*!*/`
LL | if true /*!*/ {}
| -- ^^^^^ expected `{`
| |
- | this `if` statement has a condition, but no block
+ | this `if` expression has a condition, but no block
error: aborting due to previous error