parent
8ad7bc3f42
commit
9b5a974bd5
@ -222,7 +222,6 @@ pub fn can_continue_expr_unambiguously(&self) -> bool {
|
||||
Greater | // `{ 42 } > 3`
|
||||
GreaterEqual | // `{ 42 } >= 3`
|
||||
AssignOp(_) | // `{ 42 } +=`
|
||||
LAnd | // `{ 42 } &&foo`
|
||||
As | // `{ 42 } as usize`
|
||||
// Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect
|
||||
// NotEqual | // `{ 42 } != { 42 } struct literals parser recovery.
|
||||
|
@ -295,11 +295,18 @@ fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool {
|
||||
// want to keep their span info to improve diagnostics in these cases in a later stage.
|
||||
(true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3`
|
||||
(true, Some(AssocOp::Subtract)) | // `{ 42 } -5`
|
||||
(true, Some(AssocOp::LAnd)) | // `{ 42 } &&x` (#61475)
|
||||
(true, Some(AssocOp::Add)) // `{ 42 } + 42
|
||||
// If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
|
||||
// `if x { a } else { b } && if y { c } else { d }`
|
||||
if !self.look_ahead(1, |t| t.is_reserved_ident()) => {
|
||||
if !self.look_ahead(1, |t| t.is_used_keyword()) => {
|
||||
// These cases are ambiguous and can't be identified in the parser alone.
|
||||
let sp = self.sess.source_map().start_point(self.token.span);
|
||||
self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
|
||||
false
|
||||
}
|
||||
(true, Some(AssocOp::LAnd)) => {
|
||||
// `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`. Separated from the
|
||||
// above due to #74233.
|
||||
// These cases are ambiguous and can't be identified in the parser alone.
|
||||
let sp = self.sess.source_map().start_point(self.token.span);
|
||||
self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
|
||||
|
@ -34,6 +34,7 @@ pub fn emit_coerce_suggestions(
|
||||
}
|
||||
self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty);
|
||||
self.suggest_missing_await(err, expr, expected, expr_ty);
|
||||
self.suggest_missing_parentheses(err, expr);
|
||||
self.note_need_for_fn_pointer(err, expected, expr_ty);
|
||||
}
|
||||
|
||||
|
@ -5403,6 +5403,14 @@ fn suggest_missing_await(
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_missing_parentheses(&self, err: &mut DiagnosticBuilder<'_>, expr: &hir::Expr<'_>) {
|
||||
let sp = self.tcx.sess.source_map().start_point(expr.span);
|
||||
if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) {
|
||||
// `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`
|
||||
self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp, None);
|
||||
}
|
||||
}
|
||||
|
||||
fn note_need_for_fn_pointer(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
|
10
src/test/ui/parser/expr-as-stmt-2.rs
Normal file
10
src/test/ui/parser/expr-as-stmt-2.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// This is not autofixable because we give extra suggestions to end the first expression with `;`.
|
||||
fn foo(a: Option<u32>, b: Option<u32>) -> bool {
|
||||
if let Some(x) = a { true } else { false }
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
&& //~ ERROR mismatched types
|
||||
if let Some(y) = a { true } else { false }
|
||||
}
|
||||
|
||||
fn main() {}
|
33
src/test/ui/parser/expr-as-stmt-2.stderr
Normal file
33
src/test/ui/parser/expr-as-stmt-2.stderr
Normal file
@ -0,0 +1,33 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/expr-as-stmt-2.rs:3:26
|
||||
|
|
||||
LL | if let Some(x) = a { true } else { false }
|
||||
| ---------------------^^^^------------------ help: consider using a semicolon here
|
||||
| | |
|
||||
| | expected `()`, found `bool`
|
||||
| expected this to be `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/expr-as-stmt-2.rs:3:40
|
||||
|
|
||||
LL | if let Some(x) = a { true } else { false }
|
||||
| -----------------------------------^^^^^--- help: consider using a semicolon here
|
||||
| | |
|
||||
| | expected `()`, found `bool`
|
||||
| expected this to be `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/expr-as-stmt-2.rs:6:5
|
||||
|
|
||||
LL | fn foo(a: Option<u32>, b: Option<u32>) -> bool {
|
||||
| ---- expected `bool` because of return type
|
||||
LL | if let Some(x) = a { true } else { false }
|
||||
| ------------------------------------------ help: parentheses are required to parse this as an expression: `(if let Some(x) = a { true } else { false })`
|
||||
...
|
||||
LL | / &&
|
||||
LL | | if let Some(y) = a { true } else { false }
|
||||
| |______________________________________________^ expected `bool`, found `&&bool`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -25,12 +25,6 @@ fn baz() -> i32 {
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn qux(a: Option<u32>, b: Option<u32>) -> bool {
|
||||
(if let Some(x) = a { true } else { false })
|
||||
&& //~ ERROR expected expression
|
||||
if let Some(y) = a { true } else { false }
|
||||
}
|
||||
|
||||
fn moo(x: u32) -> bool {
|
||||
(match x {
|
||||
_ => 1,
|
||||
|
@ -25,12 +25,6 @@ fn baz() -> i32 {
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn qux(a: Option<u32>, b: Option<u32>) -> bool {
|
||||
if let Some(x) = a { true } else { false }
|
||||
&& //~ ERROR expected expression
|
||||
if let Some(y) = a { true } else { false }
|
||||
}
|
||||
|
||||
fn moo(x: u32) -> bool {
|
||||
match x {
|
||||
_ => 1,
|
||||
|
@ -22,16 +22,8 @@ LL | { 42 } + foo;
|
||||
| |
|
||||
| help: parentheses are required to parse this as an expression: `({ 42 })`
|
||||
|
||||
error: expected expression, found `&&`
|
||||
--> $DIR/expr-as-stmt.rs:30:5
|
||||
|
|
||||
LL | if let Some(x) = a { true } else { false }
|
||||
| ------------------------------------------ help: parentheses are required to parse this as an expression: `(if let Some(x) = a { true } else { false })`
|
||||
LL | &&
|
||||
| ^^ expected expression
|
||||
|
||||
error: expected expression, found `>`
|
||||
--> $DIR/expr-as-stmt.rs:37:7
|
||||
--> $DIR/expr-as-stmt.rs:31:7
|
||||
|
|
||||
LL | } > 0
|
||||
| ^ expected expression
|
||||
@ -75,7 +67,7 @@ LL | { 3 } * 3
|
||||
| |
|
||||
| help: parentheses are required to parse this as an expression: `({ 3 })`
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0614.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
Loading…
Reference in New Issue
Block a user