Improve parsing errors and suggestions for bad if statements
This commit is contained in:
parent
3bdec3c8ab
commit
d1ba2d25d4
21 changed files with 325 additions and 143 deletions
|
@ -2248,36 +2248,59 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
attrs: AttrVec,
|
attrs: AttrVec,
|
||||||
lo: Span,
|
lo: Span,
|
||||||
cond: P<Expr>,
|
mut cond: P<Expr>,
|
||||||
) -> PResult<'a, P<Expr>> {
|
) -> PResult<'a, P<Expr>> {
|
||||||
let missing_then_block_binop_span = || {
|
let cond_span = cond.span;
|
||||||
match cond.kind {
|
// Tries to interpret `cond` as either a missing expression if it's a block,
|
||||||
ExprKind::Binary(Spanned { span: binop_span, .. }, _, ref right)
|
// or as an unfinished expression if it's a binop and the RHS is a block.
|
||||||
if let ExprKind::Block(..) = right.kind => Some(binop_span),
|
// We could probably add more recoveries here too...
|
||||||
_ => None
|
let mut recover_block_from_condition = |this: &mut Self| {
|
||||||
|
let block = match &mut cond.kind {
|
||||||
|
ExprKind::Binary(Spanned { span: binop_span, .. }, _, right)
|
||||||
|
if let ExprKind::Block(_, None) = right.kind => {
|
||||||
|
this.error_missing_if_then_block(lo, cond_span.shrink_to_lo().to(*binop_span), true).emit();
|
||||||
|
std::mem::replace(right, this.mk_expr_err(binop_span.shrink_to_hi()))
|
||||||
|
},
|
||||||
|
ExprKind::Block(_, None) => {
|
||||||
|
this.error_missing_if_cond(lo, cond_span).emit();
|
||||||
|
std::mem::replace(&mut cond, this.mk_expr_err(cond_span.shrink_to_hi()))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Verify that the parsed `if` condition makes sense as a condition. If it is a block, then
|
if let ExprKind::Block(block, _) = &block.kind {
|
||||||
// verify that the last statement is either an implicit return (no `;`) or an explicit
|
Some(block.clone())
|
||||||
// return. This won't catch blocks with an explicit `return`, but that would be caught by
|
|
||||||
// the dead code lint.
|
|
||||||
let thn = if self.token.is_keyword(kw::Else) || !cond.returns() {
|
|
||||||
if let Some(binop_span) = missing_then_block_binop_span() {
|
|
||||||
self.error_missing_if_then_block(lo, None, Some(binop_span)).emit();
|
|
||||||
self.mk_block_err(cond.span)
|
|
||||||
} else {
|
} else {
|
||||||
self.error_missing_if_cond(lo, cond.span)
|
unreachable!()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Parse then block
|
||||||
|
let thn = if self.token.is_keyword(kw::Else) {
|
||||||
|
if let Some(block) = recover_block_from_condition(self) {
|
||||||
|
block
|
||||||
|
} else {
|
||||||
|
self.error_missing_if_then_block(lo, cond_span, false).emit();
|
||||||
|
self.mk_block_err(cond_span.shrink_to_hi())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery.
|
let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery.
|
||||||
let not_block = self.token != token::OpenDelim(Delimiter::Brace);
|
let block = if self.check(&token::OpenDelim(Delimiter::Brace)) {
|
||||||
let block = self.parse_block().map_err(|err| {
|
self.parse_block()?
|
||||||
if not_block {
|
|
||||||
self.error_missing_if_then_block(lo, Some(err), missing_then_block_binop_span())
|
|
||||||
} else {
|
} else {
|
||||||
|
if let Some(block) = recover_block_from_condition(self) {
|
||||||
|
block
|
||||||
|
} else {
|
||||||
|
// Parse block, which will always fail, but we can add a nice note to the error
|
||||||
|
self.parse_block().map_err(|mut err| {
|
||||||
|
err.span_note(
|
||||||
|
cond_span,
|
||||||
|
"the `if` expression is missing a block after this condition",
|
||||||
|
);
|
||||||
err
|
err
|
||||||
|
})?
|
||||||
}
|
}
|
||||||
})?;
|
};
|
||||||
self.error_on_if_block_attrs(lo, false, block.span, &attrs);
|
self.error_on_if_block_attrs(lo, false, block.span, &attrs);
|
||||||
block
|
block
|
||||||
};
|
};
|
||||||
|
@ -2288,31 +2311,34 @@ impl<'a> Parser<'a> {
|
||||||
fn error_missing_if_then_block(
|
fn error_missing_if_then_block(
|
||||||
&self,
|
&self,
|
||||||
if_span: Span,
|
if_span: Span,
|
||||||
err: Option<DiagnosticBuilder<'a, ErrorGuaranteed>>,
|
cond_span: Span,
|
||||||
binop_span: Option<Span>,
|
is_unfinished: bool,
|
||||||
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||||
let msg = "this `if` expression has a condition, but no block";
|
let mut err = self.struct_span_err(
|
||||||
|
if_span,
|
||||||
let mut err = if let Some(mut err) = err {
|
"this `if` expression is missing a block after the condition",
|
||||||
err.span_label(if_span, msg);
|
);
|
||||||
err
|
if is_unfinished {
|
||||||
|
err.span_help(cond_span, "this binary operation is possibly unfinished");
|
||||||
} else {
|
} else {
|
||||||
self.struct_span_err(if_span, msg)
|
err.span_help(cond_span.shrink_to_hi(), "add a block here");
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(binop_span) = binop_span {
|
|
||||||
err.span_help(binop_span, "maybe you forgot the right operand of the condition?");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_missing_if_cond(&self, lo: Span, span: Span) -> P<ast::Block> {
|
fn error_missing_if_cond(
|
||||||
let sp = self.sess.source_map().next_point(lo);
|
&self,
|
||||||
self.struct_span_err(sp, "missing condition for `if` expression")
|
lo: Span,
|
||||||
.span_label(sp, "expected if condition here")
|
span: Span,
|
||||||
.emit();
|
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||||
self.mk_block_err(span)
|
let next_span = self.sess.source_map().next_point(lo);
|
||||||
|
let mut err = self.struct_span_err(next_span, "missing condition for `if` expression");
|
||||||
|
err.span_label(next_span, "expected condition here");
|
||||||
|
err.span_label(
|
||||||
|
self.sess.source_map().start_point(span),
|
||||||
|
"if this block is the condition of the `if` expression, then it must be followed by another block"
|
||||||
|
);
|
||||||
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses the condition of a `if` or `while` expression.
|
/// Parses the condition of a `if` or `while` expression.
|
||||||
|
|
|
@ -432,10 +432,23 @@ impl<'a> Parser<'a> {
|
||||||
//
|
//
|
||||||
// which is valid in other languages, but not Rust.
|
// which is valid in other languages, but not Rust.
|
||||||
match self.parse_stmt_without_recovery(false, ForceCollect::No) {
|
match self.parse_stmt_without_recovery(false, ForceCollect::No) {
|
||||||
// If the next token is an open brace (e.g., `if a b {`), the place-
|
// If the next token is an open brace, e.g., we have:
|
||||||
// inside-a-block suggestion would be more likely wrong than right.
|
//
|
||||||
|
// if expr other_expr {
|
||||||
|
// ^ ^ ^- lookahead(1) is a brace
|
||||||
|
// | |- current token is not "else"
|
||||||
|
// |- (statement we just parsed)
|
||||||
|
//
|
||||||
|
// the place-inside-a-block suggestion would be more likely wrong than right.
|
||||||
|
//
|
||||||
|
// FIXME(compiler-errors): this should probably parse an arbitrary expr and not
|
||||||
|
// just lookahead one token, so we can see if there's a brace after _that_,
|
||||||
|
// since we want to protect against:
|
||||||
|
// `if 1 1 + 1 {` being suggested as `if { 1 } 1 + 1 {`
|
||||||
|
// + +
|
||||||
Ok(Some(_))
|
Ok(Some(_))
|
||||||
if self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace))
|
if (!self.token.is_keyword(kw::Else)
|
||||||
|
&& self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace)))
|
||||||
|| do_not_suggest_help => {}
|
|| do_not_suggest_help => {}
|
||||||
// Do not suggest `if foo println!("") {;}` (as would be seen in test for #46836).
|
// Do not suggest `if foo println!("") {;}` (as would be seen in test for #46836).
|
||||||
Ok(Some(Stmt { kind: StmtKind::Empty, .. })) => {}
|
Ok(Some(Stmt { kind: StmtKind::Empty, .. })) => {}
|
||||||
|
|
|
@ -25,10 +25,16 @@ LL | println!("Then when?");
|
||||||
error: expected `{`, found `;`
|
error: expected `{`, found `;`
|
||||||
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:31
|
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:31
|
||||||
|
|
|
|
||||||
LL | if not // lack of braces is [sic]
|
|
||||||
| -- this `if` expression has a condition, but no block
|
|
||||||
LL | println!("Then when?");
|
LL | println!("Then when?");
|
||||||
| ^ expected `{`
|
| ^ expected `{`
|
||||||
|
|
|
||||||
|
note: the `if` expression is missing a block after this condition
|
||||||
|
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:19:8
|
||||||
|
|
|
||||||
|
LL | if not // lack of braces is [sic]
|
||||||
|
| ________^
|
||||||
|
LL | | println!("Then when?");
|
||||||
|
| |______________________________^
|
||||||
|
|
||||||
error: unexpected `2` after identifier
|
error: unexpected `2` after identifier
|
||||||
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:26:24
|
--> $DIR/issue-46836-identifier-not-instead-of-negation.rs:26:24
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
let n = 1;
|
let n = 1;
|
||||||
if 5 == {
|
if 5 == {
|
||||||
//~^ NOTE this `if` expression has a condition, but no block
|
//~^ ERROR this `if` expression is missing a block after the condition
|
||||||
println!("five");
|
println!("five");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//~^ ERROR expected `{`, found `}`
|
|
||||||
//~| NOTE expected `{`
|
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
error: expected `{`, found `}`
|
error: this `if` expression is missing a block after the condition
|
||||||
--> $DIR/if-without-block.rs:7:1
|
--> $DIR/if-without-block.rs:3:5
|
||||||
|
|
|
||||||
LL | if 5 == {
|
|
||||||
| -- this `if` expression has a condition, but no block
|
|
||||||
...
|
|
||||||
LL | }
|
|
||||||
| ^ expected `{`
|
|
||||||
|
|
|
||||||
help: maybe you forgot the right operand of the condition?
|
|
||||||
--> $DIR/if-without-block.rs:3:10
|
|
||||||
|
|
|
|
||||||
LL | if 5 == {
|
LL | if 5 == {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
||||||
|
help: this binary operation is possibly unfinished
|
||||||
|
--> $DIR/if-without-block.rs:3:8
|
||||||
|
|
|
||||||
|
LL | if 5 == {
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,19 @@ error: expected `{`, found `foo`
|
||||||
--> $DIR/issue-39848.rs:3:21
|
--> $DIR/issue-39848.rs:3:21
|
||||||
|
|
|
|
||||||
LL | if $tgt.has_$field() {}
|
LL | if $tgt.has_$field() {}
|
||||||
| -- ^^^^^^ expected `{`
|
| ^^^^^^ expected `{`
|
||||||
| |
|
|
||||||
| this `if` expression has a condition, but no block
|
|
||||||
...
|
...
|
||||||
LL | get_opt!(bar, foo);
|
LL | get_opt!(bar, foo);
|
||||||
| ------------------ in this macro invocation
|
| ------------------ in this macro invocation
|
||||||
|
|
|
|
||||||
|
note: the `if` expression is missing a block after this condition
|
||||||
|
--> $DIR/issue-39848.rs:3:12
|
||||||
|
|
|
||||||
|
LL | if $tgt.has_$field() {}
|
||||||
|
| ^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | get_opt!(bar, foo);
|
||||||
|
| ------------------ in this macro invocation
|
||||||
= note: this error originates in the macro `get_opt` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `get_opt` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
help: try placing this code inside a block
|
help: try placing this code inside a block
|
||||||
|
|
|
|
||||||
|
|
|
@ -2,18 +2,25 @@ error: expected `{`, found `=>`
|
||||||
--> $DIR/missing-block-hint.rs:3:18
|
--> $DIR/missing-block-hint.rs:3:18
|
||||||
|
|
|
|
||||||
LL | if (foo) => {}
|
LL | if (foo) => {}
|
||||||
| -- ^^ expected `{`
|
| ^^ expected `{`
|
||||||
| |
|
|
|
||||||
| this `if` expression has a condition, but no block
|
note: the `if` expression is missing a block after this condition
|
||||||
|
--> $DIR/missing-block-hint.rs:3:12
|
||||||
|
|
|
||||||
|
LL | if (foo) => {}
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
error: expected `{`, found `bar`
|
error: expected `{`, found `bar`
|
||||||
--> $DIR/missing-block-hint.rs:7:13
|
--> $DIR/missing-block-hint.rs:7:13
|
||||||
|
|
|
|
||||||
LL | if (foo)
|
|
||||||
| -- this `if` expression has a condition, but no block
|
|
||||||
LL | bar;
|
LL | bar;
|
||||||
| ^^^ expected `{`
|
| ^^^ expected `{`
|
||||||
|
|
|
|
||||||
|
note: the `if` expression is missing a block after this condition
|
||||||
|
--> $DIR/missing-block-hint.rs:6:12
|
||||||
|
|
|
||||||
|
LL | if (foo)
|
||||||
|
| ^^^^^
|
||||||
help: try placing this code inside a block
|
help: try placing this code inside a block
|
||||||
|
|
|
|
||||||
LL | { bar; }
|
LL | { bar; }
|
||||||
|
|
38
src/test/ui/parser/bad-if-statements.rs
Normal file
38
src/test/ui/parser/bad-if-statements.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
fn a() {
|
||||||
|
if {}
|
||||||
|
//~^ ERROR missing condition for `if` expression
|
||||||
|
}
|
||||||
|
|
||||||
|
fn b() {
|
||||||
|
if true && {}
|
||||||
|
//~^ ERROR this `if` expression is missing a block after the condition
|
||||||
|
}
|
||||||
|
|
||||||
|
fn c() {
|
||||||
|
let x = {};
|
||||||
|
if true x
|
||||||
|
//~^ ERROR expected `{`, found `x`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn a2() {
|
||||||
|
if {} else {}
|
||||||
|
//~^ ERROR missing condition for `if` expression
|
||||||
|
}
|
||||||
|
|
||||||
|
fn b2() {
|
||||||
|
if true && {} else {}
|
||||||
|
//~^ ERROR this `if` expression is missing a block after the condition
|
||||||
|
}
|
||||||
|
|
||||||
|
fn c2() {
|
||||||
|
let x = {};
|
||||||
|
if true x else {}
|
||||||
|
//~^ ERROR expected `{`, found `x`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn d() {
|
||||||
|
if true else {}
|
||||||
|
//~^ ERROR this `if` expression is missing a block after the condition
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
86
src/test/ui/parser/bad-if-statements.stderr
Normal file
86
src/test/ui/parser/bad-if-statements.stderr
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
error: missing condition for `if` expression
|
||||||
|
--> $DIR/bad-if-statements.rs:2:7
|
||||||
|
|
|
||||||
|
LL | if {}
|
||||||
|
| ^- if this block is the condition of the `if` expression, then it must be followed by another block
|
||||||
|
| |
|
||||||
|
| expected condition here
|
||||||
|
|
||||||
|
error: this `if` expression is missing a block after the condition
|
||||||
|
--> $DIR/bad-if-statements.rs:7:5
|
||||||
|
|
|
||||||
|
LL | if true && {}
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
help: this binary operation is possibly unfinished
|
||||||
|
--> $DIR/bad-if-statements.rs:7:8
|
||||||
|
|
|
||||||
|
LL | if true && {}
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: expected `{`, found `x`
|
||||||
|
--> $DIR/bad-if-statements.rs:13:13
|
||||||
|
|
|
||||||
|
LL | if true x
|
||||||
|
| ^ expected `{`
|
||||||
|
|
|
||||||
|
note: the `if` expression is missing a block after this condition
|
||||||
|
--> $DIR/bad-if-statements.rs:13:8
|
||||||
|
|
|
||||||
|
LL | if true x
|
||||||
|
| ^^^^
|
||||||
|
help: try placing this code inside a block
|
||||||
|
|
|
||||||
|
LL | if true { x }
|
||||||
|
| + +
|
||||||
|
|
||||||
|
error: missing condition for `if` expression
|
||||||
|
--> $DIR/bad-if-statements.rs:18:7
|
||||||
|
|
|
||||||
|
LL | if {} else {}
|
||||||
|
| ^- if this block is the condition of the `if` expression, then it must be followed by another block
|
||||||
|
| |
|
||||||
|
| expected condition here
|
||||||
|
|
||||||
|
error: this `if` expression is missing a block after the condition
|
||||||
|
--> $DIR/bad-if-statements.rs:23:5
|
||||||
|
|
|
||||||
|
LL | if true && {} else {}
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
help: this binary operation is possibly unfinished
|
||||||
|
--> $DIR/bad-if-statements.rs:23:8
|
||||||
|
|
|
||||||
|
LL | if true && {} else {}
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: expected `{`, found `x`
|
||||||
|
--> $DIR/bad-if-statements.rs:29:13
|
||||||
|
|
|
||||||
|
LL | if true x else {}
|
||||||
|
| ^ expected `{`
|
||||||
|
|
|
||||||
|
note: the `if` expression is missing a block after this condition
|
||||||
|
--> $DIR/bad-if-statements.rs:29:8
|
||||||
|
|
|
||||||
|
LL | if true x else {}
|
||||||
|
| ^^^^
|
||||||
|
help: try placing this code inside a block
|
||||||
|
|
|
||||||
|
LL | if true { x } else {}
|
||||||
|
| + +
|
||||||
|
|
||||||
|
error: this `if` expression is missing a block after the condition
|
||||||
|
--> $DIR/bad-if-statements.rs:34:5
|
||||||
|
|
|
||||||
|
LL | if true else {}
|
||||||
|
| ^^
|
||||||
|
|
|
||||||
|
help: add a block here
|
||||||
|
--> $DIR/bad-if-statements.rs:34:12
|
||||||
|
|
|
||||||
|
LL | if true else {}
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
8
src/test/ui/parser/if-block-unreachable-expr.rs
Normal file
8
src/test/ui/parser/if-block-unreachable-expr.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
// This regressed from 1.20 -> 1.21 -- the condition is unreachable,
|
||||||
|
// but it's still an expression, and should parse fine.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if { if true { return; } else { return; }; } {}
|
||||||
|
}
|
|
@ -2,9 +2,13 @@ error: expected `{`, found `)`
|
||||||
--> $DIR/issue-61858.rs:2:15
|
--> $DIR/issue-61858.rs:2:15
|
||||||
|
|
|
|
||||||
LL | (if foobar)
|
LL | (if foobar)
|
||||||
| -- ^ expected `{`
|
| ^ expected `{`
|
||||||
| |
|
|
|
||||||
| this `if` expression has a condition, but no block
|
note: the `if` expression is missing a block after this condition
|
||||||
|
--> $DIR/issue-61858.rs:2:9
|
||||||
|
|
|
||||||
|
LL | (if foobar)
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
macro_rules! x {
|
macro_rules! x {
|
||||||
($($c:tt)*) => {
|
($($c:tt)*) => {
|
||||||
$($c)ö* {} //~ ERROR missing condition for `if` expression
|
$($c)ö* {}
|
||||||
}; //~| ERROR mismatched types
|
//~^ ERROR missing condition for `if` expression
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -2,19 +2,9 @@ error: missing condition for `if` expression
|
||||||
--> $DIR/issue-68091-unicode-ident-after-if.rs:3:14
|
--> $DIR/issue-68091-unicode-ident-after-if.rs:3:14
|
||||||
|
|
|
|
||||||
LL | $($c)ö* {}
|
LL | $($c)ö* {}
|
||||||
| ^ expected if condition here
|
| ^ - if this block is the condition of the `if` expression, then it must be followed by another block
|
||||||
|
| |
|
||||||
|
| expected condition here
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to previous error
|
||||||
--> $DIR/issue-68091-unicode-ident-after-if.rs:3:17
|
|
||||||
|
|
|
||||||
LL | $($c)ö* {}
|
|
||||||
| ^^ expected `bool`, found `()`
|
|
||||||
...
|
|
||||||
LL | x!(if);
|
|
||||||
| ------ in this macro invocation
|
|
||||||
|
|
|
||||||
= note: this error originates in the macro `x` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let value = if true && {
|
let value = if true && {
|
||||||
//~^ ERROR: this `if` expression has a condition, but no block
|
//~^ ERROR: this `if` expression is missing a block after the condition
|
||||||
//~| HELP: maybe you forgot the right operand of the condition?
|
//~| HELP: this binary operation is possibly unfinished
|
||||||
3
|
3
|
||||||
//~^ ERROR: mismatched types [E0308]
|
|
||||||
} else { 4 };
|
} else { 4 };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,14 @@
|
||||||
error: this `if` expression has a condition, but no block
|
error: this `if` expression is missing a block after the condition
|
||||||
--> $DIR/issue-91421.rs:4:17
|
--> $DIR/issue-91421.rs:4:17
|
||||||
|
|
|
|
||||||
LL | let value = if true && {
|
LL | let value = if true && {
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
help: maybe you forgot the right operand of the condition?
|
help: this binary operation is possibly unfinished
|
||||||
--> $DIR/issue-91421.rs:4:25
|
--> $DIR/issue-91421.rs:4:20
|
||||||
|
|
|
|
||||||
LL | let value = if true && {
|
LL | let value = if true && {
|
||||||
| ^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to previous error
|
||||||
--> $DIR/issue-91421.rs:7:9
|
|
||||||
|
|
|
||||||
LL | 3
|
|
||||||
| ^ expected `bool`, found integer
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
if true {
|
if true {
|
||||||
} else if { //~ ERROR missing condition
|
} else if {
|
||||||
//~^ ERROR mismatched types
|
//~^ ERROR missing condition for `if` expression
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo() {
|
fn foo() {
|
||||||
if true {
|
if true {
|
||||||
} else if { //~ ERROR missing condition
|
} else if {
|
||||||
//~^ ERROR mismatched types
|
//~^ ERROR missing condition for `if` expression
|
||||||
}
|
}
|
||||||
bar();
|
bar();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,32 +2,17 @@ error: missing condition for `if` expression
|
||||||
--> $DIR/issue-13483.rs:3:14
|
--> $DIR/issue-13483.rs:3:14
|
||||||
|
|
|
|
||||||
LL | } else if {
|
LL | } else if {
|
||||||
| ^ expected if condition here
|
| ^- if this block is the condition of the `if` expression, then it must be followed by another block
|
||||||
|
| |
|
||||||
|
| expected condition here
|
||||||
|
|
||||||
error: missing condition for `if` expression
|
error: missing condition for `if` expression
|
||||||
--> $DIR/issue-13483.rs:11:14
|
--> $DIR/issue-13483.rs:11:14
|
||||||
|
|
|
|
||||||
LL | } else if {
|
LL | } else if {
|
||||||
| ^ expected if condition here
|
| ^- if this block is the condition of the `if` expression, then it must be followed by another block
|
||||||
|
| |
|
||||||
|
| expected condition here
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 2 previous errors
|
||||||
--> $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`.
|
|
||||||
|
|
|
@ -2,9 +2,13 @@ error: expected `{`, found keyword `in`
|
||||||
--> $DIR/issue-51602.rs:2:10
|
--> $DIR/issue-51602.rs:2:10
|
||||||
|
|
|
|
||||||
LL | if i in 1..10 {
|
LL | if i in 1..10 {
|
||||||
| -- ^^ expected `{`
|
| ^^ expected `{`
|
||||||
| |
|
|
|
||||||
| this `if` expression has a condition, but no block
|
note: the `if` expression is missing a block after this condition
|
||||||
|
--> $DIR/issue-51602.rs:2:8
|
||||||
|
|
|
||||||
|
LL | if i in 1..10 {
|
||||||
|
| ^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,13 @@ error: expected `{`, found `macro_rules`
|
||||||
--> $DIR/issue-62554.rs:6:23
|
--> $DIR/issue-62554.rs:6:23
|
||||||
|
|
|
|
||||||
LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
|
LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
|
||||||
| -- ^^^^^^^^^^^ expected `{`
|
| ^^^^^^^^^^^ expected `{`
|
||||||
| |
|
|
||||||
| this `if` expression has a condition, but no block
|
|
||||||
|
|
|
|
||||||
|
note: the `if` expression is missing a block after this condition
|
||||||
|
--> $DIR/issue-62554.rs:6:20
|
||||||
|
|
|
||||||
|
LL | fn foo(u: u8) { if u8 macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 {
|
||||||
|
| ^^
|
||||||
help: try placing this code inside a block
|
help: try placing this code inside a block
|
||||||
|
|
|
|
||||||
LL | fn foo(u: u8) { if u8 { macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { }
|
LL | fn foo(u: u8) { if u8 { macro_rules! u8 { (u6) => { fn uuuuuuuuuuu() { use s loo mod u8 { }
|
||||||
|
|
|
@ -21,15 +21,15 @@ fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(n) = opt else {
|
if let Some(n) = opt else {
|
||||||
//~^ ERROR missing condition for `if` expression
|
//~^ ERROR this `if` expression is missing a block after the condition
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if let Some(n) = opt && n == 1 else {
|
if let Some(n) = opt && n == 1 else {
|
||||||
//~^ ERROR missing condition for `if` expression
|
//~^ ERROR this `if` expression is missing a block after the condition
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if let Some(n) = opt && let another = n else {
|
if let Some(n) = opt && let another = n else {
|
||||||
//~^ ERROR missing condition for `if` expression
|
//~^ ERROR this `if` expression is missing a block after the condition
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,23 +20,41 @@ help: wrap the expression in parentheses
|
||||||
LL | let Some(n) = (opt && let another = n) else {
|
LL | let Some(n) = (opt && let another = n) else {
|
||||||
| + +
|
| + +
|
||||||
|
|
||||||
error: missing condition for `if` expression
|
error: this `if` expression is missing a block after the condition
|
||||||
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:7
|
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:5
|
||||||
|
|
|
|
||||||
LL | if let Some(n) = opt else {
|
LL | if let Some(n) = opt else {
|
||||||
| ^ expected if condition here
|
| ^^
|
||||||
|
|
|
||||||
|
help: add a block here
|
||||||
|
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:25
|
||||||
|
|
|
||||||
|
LL | if let Some(n) = opt else {
|
||||||
|
| ^
|
||||||
|
|
||||||
error: missing condition for `if` expression
|
error: this `if` expression is missing a block after the condition
|
||||||
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:7
|
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:5
|
||||||
|
|
|
|
||||||
LL | if let Some(n) = opt && n == 1 else {
|
LL | if let Some(n) = opt && n == 1 else {
|
||||||
| ^ expected if condition here
|
| ^^
|
||||||
|
|
|
||||||
|
help: add a block here
|
||||||
|
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:35
|
||||||
|
|
|
||||||
|
LL | if let Some(n) = opt && n == 1 else {
|
||||||
|
| ^
|
||||||
|
|
||||||
error: missing condition for `if` expression
|
error: this `if` expression is missing a block after the condition
|
||||||
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:7
|
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:5
|
||||||
|
|
|
|
||||||
LL | if let Some(n) = opt && let another = n else {
|
LL | if let Some(n) = opt && let another = n else {
|
||||||
| ^ expected if condition here
|
| ^^
|
||||||
|
|
|
||||||
|
help: add a block here
|
||||||
|
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:44
|
||||||
|
|
|
||||||
|
LL | if let Some(n) = opt && let another = n else {
|
||||||
|
| ^
|
||||||
|
|
||||||
error: expected `{`, found keyword `else`
|
error: expected `{`, found keyword `else`
|
||||||
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:37:33
|
--> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:37:33
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue