-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Further improve diagnostics for expressions in pattern position #121697
Comments
cc @ShE3py, @WaffleLapkin |
I know that this is quite a wall of text and I don't expect anyone to read it. I've tagged you, ShE3py, since you might be interested in working on some of the things I listed here. Otherwise this issue just serves as a public TODO list for me. |
Okay, I've somehow resurrected.
It might be worth to emit both diagnostics (e.g. “unexpected field access // try introducing a
Likewise. Especially since some scripts e.g. Arabic doesn't have cases (the check should've been something like
Note to self: this was inlined into rust/compiler/rustc_parse/src/parser/expr.rs Lines 1122 to 1155 in 0824b30
I don't mind reading, and I often find myself writing walls of text, albeit in French, and my English isn't so good as to write pavés in it while retaining the same meaning. @rustbot claim |
Further improve diagnostics for expressions in pattern position Follow-up of rust-lang#118625, see rust-lang#121697. ```rs fn main() { match 'b' { y.0.0.1.z().f()? as u32 => {}, } } ``` Before: ``` error: expected one of `=>`, ``@`,` `if`, or `|`, found `.` --> src/main.rs:3:10 | 3 | y.0.0.1.z().f()? as u32 => {}, | ^ expected one of `=>`, ``@`,` `if`, or `|` ``` After: ``` error: expected a pattern, found an expression --> src/main.rs:3:9 | 3 | y.0.0.1.z().f()? as u32 => {}, | ^^^^^^^^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns | help: consider moving the expression to a match arm guard | 3 | val if val == y.0.0.1.z().f()? as u32 => {}, | ~~~ +++++++++++++++++++++++++++++++++ help: consider extracting the expression into a `const` | 2 + const VAL: /* Type */ = y.0.0.1.z().f()? as u32; 3 ~ match 'b' { 4 ~ VAL => {}, | help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`) | 3 | const { y.0.0.1.z().f()? as u32 } => {}, | +++++++ + ``` --- r? fmease `@rustbot` label +A-diagnostics +A-parser +A-patterns +C-enhancement
I've had this on my TODO list for a while but never had the time to write a PR for it. Therefore I'm just going to open an issue for it instead.
Since PR #118625 we try to reparse something in pattern position as an expression under certain conditions and provide a smarter diagnostic of the form “expected a pattern, found an expression // arbitrary expressions are not allowed in patterns” which is already amazing.
However, the current heuristic has a few limitations I'd like to see addressed which should be relatively simple to implement:
$literal.$ident
and so forth) but only things that look like method calls (e.g.,0.f()
). I argue we should also detect expressions likex.f
ands.0
. This would've prevented #104996 from getting opened! (addressed in #123877).
-“herald” check.Span
to make sure that there's no whitespace/comment before & after the.
to avoid overzealously emitting this diagnostic when the user accidentally typoed a comma as a dot (as in(x. y)
←(x, y)
) which isn't too farfetched given the keys are right next to each other on most keyboards (just need to checksp0.hi == sp1.lo
). Of course, this would rule out multi-line method / field chains but that should be rare. We could (as a follow-up) check if the would-be expression is “appropriately” indented (by utilizingSourceMap
methods) to address that, too. (NOTE: this isn't implemented yet, unclear if we actually want this)x.Foo()
to be a method call). If you disagree, we should at least also consider_
to be a valid start of a field or method name (x._foo()
doesn't get recognized at the time of writing).x.0.1
without accidentally flaggingx.0e4
as an expression (x.0.1
gets lexed as [Ident, Dot, FloatLit]). Seeparse_expr_tuple_field_access_float
for prior art.as
to be a “herald” next to.
to recover0 as usize
etc. in pattern position (addressed in #123877).f().g()
andetc. meaning more method calls / field accesses where the “basis” is a more complex expression. Rephrased: Recognize more “(0).f()
$expr.$ident
” over just “$lit_or_ident.$ident
” (the latter is the status quo, roughly, if I'm not mistaken).(0).f()
was addressed in #123877.const
and refer to that” (addressed in #123877).const {}
block (featureinline_const_pat
). We could provide the suggestion ifself.sess.unstable_features.is_nightly_build()
holds but I don't know if others like the idea of that. Note that we cannot check if featureinline_const_pat
is enabled from inside the parserand diagnostic stashing/stealing doesn't help here either since we want to “stash” a subdiagnostic (a structured suggestion)not true actually, should be possible to impl (addressed in #123877.The text was updated successfully, but these errors were encountered: