Skip to content

Commit

Permalink
fixup! Recover more expressions in patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
ShE3py committed Jul 15, 2024
1 parent 8513f07 commit d2ca561
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 34 deletions.
29 changes: 20 additions & 9 deletions compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ impl<'a> Parser<'a> {
/// 0..=1 + 2
/// ^^^^^
/// ```
/// Only the end bound is spanned in this case, and this function have no idea if there were a `..=` before `pat_span`, hence the parameter.
/// Only the end bound is spanned in this case, and this function has no idea if there was a `..=` before `pat_span`, hence the parameter.
///
/// This function returns `Some` if a trailing expression was recovered, and said expression's span.
#[must_use = "the pattern must be discarded as `PatKind::Err` if this function returns Some"]
Expand All @@ -360,23 +360,34 @@ impl<'a> Parser<'a> {
return None;
}

// Returns `true` iff `token` is a `x.y` float.
let is_two_tuple_indexes = |that: &Self, token: &Token| -> bool {
// Returns `true` iff `token` is an unsuffixed integer.
let is_one_tuple_index = |_: &Self, token: &Token| -> bool {
use token::{Lit, LitKind};

let token::Literal(Lit { kind: LitKind::Float, symbol, suffix: None }) = token.kind
else {
return false;
};
matches!(
token.kind,
token::Literal(Lit { kind: LitKind::Integer, symbol: _, suffix: None })
)
};

// Returns `true` iff `token` is an unsuffixed `x.y` float.
let is_two_tuple_indexes = |this: &Self, token: &Token| -> bool {
use token::{Lit, LitKind};

matches!(that.break_up_float(symbol, token.span), DestructuredFloat::MiddleDot(..))
if let token::Literal(Lit { kind: LitKind::Float, symbol, suffix: None }) = token.kind
&& let DestructuredFloat::MiddleDot(..) = this.break_up_float(symbol, token.span)
{
true
} else {
false
}
};

// Check for `.hello` or `.0`.
let has_dot_expr = self.check_noexpect(&token::Dot) // `.`
&& self.look_ahead(1, |tok| {
tok.is_ident() // `hello`
|| tok.is_integer_lit() // `0`
|| is_one_tuple_index(&self, &tok) // `0`
|| is_two_tuple_indexes(&self, &tok) // `0.0`
});

Expand Down
17 changes: 17 additions & 0 deletions tests/ui/parser/recover/recover-pat-exprs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,23 @@ fn field_access() {
{ let x.0e0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
{ let x.-0.0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
{ let x.-0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`

{ let x.0u32; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
{ let x.0.0_f64; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
}

// ArrayExpression
fn array_indexing() {
match 0 {
x[0] => (), //~ error: expected a pattern, found an expression
x[..] => (), //~ error: expected a pattern, found an expression
}

{ let x[0, 1, 2]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
{ let x[0; 20]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
{ let x[]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
{ let (x[]); } //~ error: expected one of `)`, `,`, `@`, or `|`, found `[`
//~^ missing `,`
}

// MethodCallExpression, CallExpression, ErrorPropagationExpression
Expand Down
132 changes: 107 additions & 25 deletions tests/ui/parser/recover/recover-pat-exprs.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,90 @@ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
LL | { let x.-0; }
| ^ expected one of `:`, `;`, `=`, `@`, or `|`

error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
--> $DIR/recover-pat-exprs.rs:16:12
|
LL | { let x.0u32; }
| ^ expected one of `:`, `;`, `=`, `@`, or `|`

error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
--> $DIR/recover-pat-exprs.rs:17:12
|
LL | { let x.0.0_f64; }
| ^ expected one of `:`, `;`, `=`, `@`, or `|`

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:23:9
|
LL | x[0] => (),
| ^^^^ arbitrary expressions are not allowed in patterns
|
help: check the value in an arm guard
|
LL | val if val == x[0] => (),
| ~~~ ++++++++++++++
help: extract the expression into a `const` and refer to it
|
LL + const VAL: _ = x[0];
LL ~ match 0 {
LL ~ VAL => (),
|
help: wrap the expression in a inline const (requires `#![feature(inline_const_pat)]`)
|
LL | const { x[0] } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:20:9
--> $DIR/recover-pat-exprs.rs:24:9
|
LL | x[..] => (),
| ^^^^^ arbitrary expressions are not allowed in patterns
|
help: check the value in an arm guard
|
LL | val if val == x[..] => (),
| ~~~ +++++++++++++++
help: extract the expression into a `const` and refer to it
|
LL + const VAL: _ = x[..];
LL ~ match 0 {
LL | x[0] => (),
LL ~ VAL => (),
|
help: wrap the expression in a inline const (requires `#![feature(inline_const_pat)]`)
|
LL | const { x[..] } => (),
| +++++++ +

error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
--> $DIR/recover-pat-exprs.rs:27:12
|
LL | { let x[0, 1, 2]; }
| ^ expected one of `:`, `;`, `=`, `@`, or `|`

error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
--> $DIR/recover-pat-exprs.rs:28:12
|
LL | { let x[0; 20]; }
| ^ expected one of `:`, `;`, `=`, `@`, or `|`

error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
--> $DIR/recover-pat-exprs.rs:29:12
|
LL | { let x[]; }
| ^ expected one of `:`, `;`, `=`, `@`, or `|`

error: expected one of `)`, `,`, `@`, or `|`, found `[`
--> $DIR/recover-pat-exprs.rs:30:13
|
LL | { let (x[]); }
| ^
| |
| expected one of `)`, `,`, `@`, or `|`
| help: missing `,`

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:37:9
|
LL | x.f() => (),
| ^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -155,7 +237,7 @@ LL | const { x.f() } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:21:9
--> $DIR/recover-pat-exprs.rs:38:9
|
LL | x._f() => (),
| ^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -177,7 +259,7 @@ LL | const { x._f() } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:22:9
--> $DIR/recover-pat-exprs.rs:39:9
|
LL | x? => (),
| ^^ arbitrary expressions are not allowed in patterns
Expand All @@ -200,7 +282,7 @@ LL | const { x? } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:23:9
--> $DIR/recover-pat-exprs.rs:40:9
|
LL | ().f() => (),
| ^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -224,7 +306,7 @@ LL | const { ().f() } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:24:9
--> $DIR/recover-pat-exprs.rs:41:9
|
LL | (0, x)?.f() => (),
| ^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -248,7 +330,7 @@ LL | const { (0, x)?.f() } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:25:9
--> $DIR/recover-pat-exprs.rs:42:9
|
LL | x.f().g() => (),
| ^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -272,7 +354,7 @@ LL | const { x.f().g() } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:26:9
--> $DIR/recover-pat-exprs.rs:43:9
|
LL | 0.f()?.g()?? => (),
| ^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -296,7 +378,7 @@ LL | const { 0.f()?.g()?? } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:33:9
--> $DIR/recover-pat-exprs.rs:50:9
|
LL | x as usize => (),
| ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -317,7 +399,7 @@ LL | const { x as usize } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:34:9
--> $DIR/recover-pat-exprs.rs:51:9
|
LL | 0 as usize => (),
| ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -339,7 +421,7 @@ LL | const { 0 as usize } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:35:9
--> $DIR/recover-pat-exprs.rs:52:9
|
LL | x.f().0.4 as f32 => (),
| ^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -362,7 +444,7 @@ LL | const { x.f().0.4 as f32 } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:42:9
--> $DIR/recover-pat-exprs.rs:59:9
|
LL | 1 + 1 => (),
| ^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -383,7 +465,7 @@ LL | const { 1 + 1 } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:43:9
--> $DIR/recover-pat-exprs.rs:60:9
|
LL | (1 + 2) * 3 => (),
| ^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -405,7 +487,7 @@ LL | const { (1 + 2) * 3 } => (),
| +++++++ +

error: left-hand side of `@` must be a binding
--> $DIR/recover-pat-exprs.rs:56:9
--> $DIR/recover-pat-exprs.rs:73:9
|
LL | x.sqrt() @ .. => (),
| --------^^^--
Expand All @@ -416,13 +498,13 @@ LL | x.sqrt() @ .. => (),
= note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`

error: expected one of `)`, `,`, or `|`, found `+`
--> $DIR/recover-pat-exprs.rs:70:12
--> $DIR/recover-pat-exprs.rs:87:12
|
LL | (_ + 1) => (),
| ^ expected one of `)`, `,`, or `|`

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:54:9
--> $DIR/recover-pat-exprs.rs:71:9
|
LL | u8::MAX.abs() => (),
| ^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -443,7 +525,7 @@ LL | const { u8::MAX.abs() } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:59:17
--> $DIR/recover-pat-exprs.rs:76:17
|
LL | z @ w @ v.u() => (),
| ^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -467,7 +549,7 @@ LL | z @ w @ const { v.u() } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:61:9
--> $DIR/recover-pat-exprs.rs:78:9
|
LL | y.ilog(3) => (),
| ^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -491,7 +573,7 @@ LL | const { y.ilog(3) } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:63:9
--> $DIR/recover-pat-exprs.rs:80:9
|
LL | n + 1 => (),
| ^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -515,7 +597,7 @@ LL | const { n + 1 } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:65:10
--> $DIR/recover-pat-exprs.rs:82:10
|
LL | ("".f() + 14 * 8) => (),
| ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -539,7 +621,7 @@ LL | (const { "".f() + 14 * 8 }) => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:68:9
--> $DIR/recover-pat-exprs.rs:85:9
|
LL | f?() => (),
| ^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -563,7 +645,7 @@ LL | const { f?() } => (),
| +++++++ +

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:74:9
--> $DIR/recover-pat-exprs.rs:91:9
|
LL | let 1 + 1 = 2;
| ^^^^^ arbitrary expressions are not allowed in patterns
Expand All @@ -575,7 +657,7 @@ LL + 1 + 1 = 2;
|

error: expected one of `)`, `,`, `@`, or `|`, found `*`
--> $DIR/recover-pat-exprs.rs:77:28
--> $DIR/recover-pat-exprs.rs:94:28
|
LL | let b = matches!(x, (x * x | x.f()) | x[0]);
| ^ expected one of `)`, `,`, `@`, or `|`
Expand All @@ -584,16 +666,16 @@ LL | let b = matches!(x, (x * x | x.f()) | x[0]);
= note: while parsing argument for this `pat` macro fragment

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:48:5
--> $DIR/recover-pat-exprs.rs:65:5
|
LL | 1 + 2 * PI.cos() => 2,
| ^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns

error: expected a pattern, found an expression
--> $DIR/recover-pat-exprs.rs:56:9
--> $DIR/recover-pat-exprs.rs:73:9
|
LL | x.sqrt() @ .. => (),
| ^^^^^^^^ arbitrary expressions are not allowed in patterns

error: aborting due to 32 previous errors
error: aborting due to 40 previous errors

0 comments on commit d2ca561

Please sign in to comment.