Skip to content

Commit

Permalink
Address review comments
Browse files Browse the repository at this point in the history
- Add doc comment to new type
- Restore "only supported directly in conditions of `if` and `while` expressions" note
- Rename variant with clearer name
  • Loading branch information
matthewjasper committed Sep 13, 2023
1 parent b011a0a commit e324a59
Show file tree
Hide file tree
Showing 15 changed files with 362 additions and 4 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ parse_expected_else_block = expected `{"{"}`, found {$first_tok}
.suggestion = add an `if` if this is the condition of a chained `else if` statement
parse_expected_expression_found_let = expected expression, found `let` statement
.note = only supported directly in conditions of `if` and `while` expressions
.not_supported_or = `||` operators are not supported in let chain expressions
.not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ pub(crate) struct IfExpressionMissingCondition {

#[derive(Diagnostic)]
#[diag(parse_expected_expression_found_let)]
#[note]
pub(crate) struct ExpectedExpressionFoundLet {
#[primary_span]
pub span: Span,
Expand Down
17 changes: 13 additions & 4 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2461,7 +2461,7 @@ impl<'a> Parser<'a> {
let is_recovered = if !restrictions.contains(Restrictions::ALLOW_LET) {
Some(self.sess.emit_err(errors::ExpectedExpressionFoundLet {
span: self.token.span,
reason: ForbiddenLetReason::GenericForbidden,
reason: ForbiddenLetReason::OtherForbidden,
}))
} else {
None
Expand Down Expand Up @@ -3427,7 +3427,7 @@ impl<'a> Parser<'a> {
#[derive(Clone, Copy, Subdiagnostic)]
pub(crate) enum ForbiddenLetReason {
/// `let` is not valid and the source environment is not important
GenericForbidden,
OtherForbidden,
/// A let chain with the `||` operator
#[note(parse_not_supported_or)]
NotSupportedOr(#[primary_span] Span),
Expand All @@ -3439,6 +3439,15 @@ pub(crate) enum ForbiddenLetReason {
NotSupportedParentheses(#[primary_span] Span),
}

/// Visitor to check for invalid/unstable use of `ExprKind::Let` that can't
/// easily be caught in parsing. For example:
///
/// ```rust,ignore (example)
/// // Only know that the let isn't allowed once the `||` token is reached
/// if let Some(x) = y || true {}
/// // Only know that the let isn't allowed once the second `=` token is reached.
/// if let Some(x) = y && z = 1 {}
/// ```
struct CondChecker<'a> {
parser: &'a Parser<'a>,
forbid_let_reason: Option<ForbiddenLetReason>,
Expand Down Expand Up @@ -3495,14 +3504,14 @@ impl MutVisitor for CondChecker<'_> {
| ExprKind::Tup(_)
| ExprKind::Paren(_) => {
let forbid_let_reason = self.forbid_let_reason;
self.forbid_let_reason = Some(GenericForbidden);
self.forbid_let_reason = Some(OtherForbidden);
noop_visit_expr(e, self);
self.forbid_let_reason = forbid_let_reason;
}
ExprKind::Cast(ref mut op, _)
| ExprKind::Type(ref mut op, _) => {
let forbid_let_reason = self.forbid_let_reason;
self.forbid_let_reason = Some(GenericForbidden);
self.forbid_let_reason = Some(OtherForbidden);
self.visit_expr(op);
self.forbid_let_reason = forbid_let_reason;
}
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/expr/if/bad-if-let-suggestion.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ error: expected expression, found `let` statement
|
LL | if let x = 1 && i = 2 {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions

error[E0425]: cannot find value `i` in this scope
--> $DIR/bad-if-let-suggestion.rs:5:21
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/mir/issue-92893.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ error: expected expression, found `let` statement
|
LL | struct Bug<A = [(); (let a = (), 1).1]> {
| ^^^
|
= note: only supported directly in conditions of `if` and `while` expressions

error: aborting due to previous error

13 changes: 13 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ error: expected expression, found `let` statement
LL | () if (let 0 = 1) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/feature-gate.rs:10:16
|
Expand All @@ -16,6 +17,7 @@ error: expected expression, found `let` statement
LL | () if (((let 0 = 1))) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/feature-gate.rs:13:18
|
Expand All @@ -28,6 +30,7 @@ error: expected expression, found `let` statement
LL | () if (let 0 = 1) && true => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/feature-gate.rs:24:16
|
Expand All @@ -40,6 +43,7 @@ error: expected expression, found `let` statement
LL | () if true && (let 0 = 1) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/feature-gate.rs:27:24
|
Expand All @@ -52,6 +56,7 @@ error: expected expression, found `let` statement
LL | () if (let 0 = 1) && (let 0 = 1) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/feature-gate.rs:30:16
|
Expand All @@ -64,6 +69,7 @@ error: expected expression, found `let` statement
LL | () if (let 0 = 1) && (let 0 = 1) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/feature-gate.rs:30:31
|
Expand All @@ -76,6 +82,7 @@ error: expected expression, found `let` statement
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/feature-gate.rs:34:42
|
Expand All @@ -88,6 +95,7 @@ error: expected expression, found `let` statement
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/feature-gate.rs:34:42
|
Expand All @@ -100,6 +108,7 @@ error: expected expression, found `let` statement
LL | () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/feature-gate.rs:34:42
|
Expand All @@ -111,12 +120,16 @@ error: expected expression, found `let` statement
|
LL | use_expr!((let 0 = 1 && 0 == 0));
| ^^^
|
= note: only supported directly in conditions of `if` and `while` expressions

error: expected expression, found `let` statement
--> $DIR/feature-gate.rs:62:16
|
LL | use_expr!((let 0 = 1));
| ^^^
|
= note: only supported directly in conditions of `if` and `while` expressions

error: no rules expected the token `let`
--> $DIR/feature-gate.rs:70:15
Expand Down
1 change: 1 addition & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ LL | ($e:expr) => { let Some(x) = $e }
LL | () if m!(Some(5)) => {}
| ----------- in this macro invocation
|
= note: only supported directly in conditions of `if` and `while` expressions
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/rfcs/rfc-2294-if-let-guard/parens.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ error: expected expression, found `let` statement
LL | () if (let 0 = 1) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/parens.rs:10:16
|
Expand All @@ -16,6 +17,7 @@ error: expected expression, found `let` statement
LL | () if (((let 0 = 1))) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/parens.rs:12:18
|
Expand All @@ -28,6 +30,7 @@ error: expected expression, found `let` statement
LL | () if (let 0 = 1) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/parens.rs:20:16
|
Expand All @@ -40,6 +43,7 @@ error: expected expression, found `let` statement
LL | () if (((let 0 = 1))) => {}
| ^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> $DIR/parens.rs:22:18
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ error: expected expression, found `let` statement
LL | Ok(opt) if let Some(4) = opt || false => {}
| ^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `||` operators are not supported in let chain expressions
--> $DIR/ast-validate-guards.rs:5:38
|
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/rfcs/rfc-2497-if-let-chains/avoid-invalid-mir.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ error: expected expression, found `let` statement
|
LL | !let y = 42;
| ^^^
|
= note: only supported directly in conditions of `if` and `while` expressions

error: aborting due to previous error

Loading

0 comments on commit e324a59

Please sign in to comment.