diff options
| author | Cameron Steffen <cam.steffen94@gmail.com> | 2021-07-30 17:12:11 -0500 |
|---|---|---|
| committer | Cameron Steffen <cam.steffen94@gmail.com> | 2021-08-30 20:18:42 -0500 |
| commit | 29bc94ff0de00d79aa10c47603701592e1d3e340 (patch) | |
| tree | ed0f44897097c71bc2085629289a6ba8cfa4375e /compiler/rustc_parse | |
| parent | 2f4e86b9ef457ff7b465e73e3aaabfcaa1d9d8e1 (diff) | |
| download | rust-29bc94ff0de00d79aa10c47603701592e1d3e340.tar.gz rust-29bc94ff0de00d79aa10c47603701592e1d3e340.zip | |
Handle let-else initializer edge case errors
Diffstat (limited to 'compiler/rustc_parse')
| -rw-r--r-- | compiler/rustc_parse/src/parser/stmt.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index d083c379f77..068bd36af55 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -298,6 +298,8 @@ impl<'a> Parser<'a> { Some(init) => { if self.eat_keyword(kw::Else) { let els = self.parse_block()?; + self.check_let_else_init_bool_expr(&init); + self.check_let_else_init_trailing_brace(&init); LocalKind::InitElse(init, els) } else { LocalKind::Init(init) @@ -308,6 +310,50 @@ impl<'a> Parser<'a> { Ok(P(ast::Local { ty, pat, kind, id: DUMMY_NODE_ID, span: lo.to(hi), attrs, tokens: None })) } + fn check_let_else_init_bool_expr(&self, init: &ast::Expr) { + if let ast::ExprKind::Binary(op, ..) = init.kind { + if op.node.lazy() { + let suggs = vec![ + (init.span.shrink_to_lo(), "(".to_string()), + (init.span.shrink_to_hi(), ")".to_string()), + ]; + self.struct_span_err( + init.span, + &format!( + "a `{}` expression cannot be directly assigned in `let...else`", + op.node.to_string() + ), + ) + .multipart_suggestion( + "wrap the expression in parenthesis", + suggs, + Applicability::MachineApplicable, + ) + .emit(); + } + } + } + + fn check_let_else_init_trailing_brace(&self, init: &ast::Expr) { + if let Some(trailing) = classify::expr_trailing_brace(init) { + let err_span = trailing.span.with_lo(trailing.span.hi() - BytePos(1)); + let suggs = vec![ + (trailing.span.shrink_to_lo(), "(".to_string()), + (trailing.span.shrink_to_hi(), ")".to_string()), + ]; + self.struct_span_err( + err_span, + "right curly brace `}` before `else` in a `let...else` statement not allowed", + ) + .multipart_suggestion( + "try wrapping the expression in parenthesis", + suggs, + Applicability::MachineApplicable, + ) + .emit(); + } + } + /// Parses the RHS of a local variable declaration (e.g., `= 14;`). fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<P<Expr>>> { let eq_consumed = match self.token.kind { |
