-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
refactor expr & stmt parsing + improve recovery #66994
Conversation
Looking at some more changes to |
This comment has been minimized.
This comment has been minimized.
LL | let a = #![allow(warnings)] (1, 2); | ||
| ^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item following them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have a style guide covering this yet, but this mix&match of lowercase led sentence followed by properly capitalized sentence is jarring to me. In other errors I've sidestepped the issue by issuing two notes or reworking the text to work as a single sentence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well it's pre-existing and I would prefer not to do anything about it here, but maybe you want to file an issue for this or something. :)
let a = #![allow(warnings)] (1, 2); | ||
//~^ ERROR an inner attribute is not permitted in this context | ||
|
||
let b = (#![allow(warnings)] 1, 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These other cases should also be emitting warnings, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well warnings are being allowed so that doesn't seem right. The point of this test is only parsing behavior tho, not the lint system.
src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr
Outdated
Show resolved
Hide resolved
--> $DIR/issue-54109-and_instead_of_ampersands.rs:20:15 | ||
| | ||
LL | let _ = a or b; | ||
| ^^ help: instead of `or`, use `||` to perform logical disjunction: `||` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"logical conjuction/disjunction" makes sense and is accurate, but it's not very friendly to most people, who will most likely need to do a double take to understand what it means (if we reword in a more terse manner as suggested above).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what a less jargon-y wording would be. At least "logical conjunction" is easy to google for.
src/test/ui/parser/issue-65257-invalid-var-decl-recovery.stderr
Outdated
Show resolved
Hide resolved
src/test/ui/parser/issue-65257-invalid-var-decl-recovery.stderr
Outdated
Show resolved
Hide resolved
src/librustc_parse/parser/stmt.rs
Outdated
@@ -426,11 +410,11 @@ impl<'a> Parser<'a> { | |||
} | |||
|
|||
/// Parses a statement, including the trailing semicolon. | |||
pub fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> { | |||
pub fn parse_full_stmt(&mut self) -> PResult<'a, Option<Stmt>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@petrochenkov you'll want to take a look at the changes in this file.
.span_label(self.token.span, msg) | ||
.emit(); | ||
// Continue as an expression in an effort to recover on `'label: non_block_expr`. | ||
self.parse_expr() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this use the snapshotting hack to to try and keep the error count down? There are cases where error recovery is too eager and we end up with wall of texts on a single typo :-/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be clear, this is fine as is, just something to consider when working on this code doing these kind of things. If an expression can't be parsed, at that point it is nicer to just give up and raise FatalError
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imo not worth it until more people complain :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if I'm the one complaining about the output I'm seeing? :^)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you tho? ;)
&format!("expected `;`, found {}", self.this_token_descr()) | ||
}).note({ | ||
"this was erroneously allowed and will become a hard error in a future release" | ||
}).emit(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where did this go? We can't suddenly start rejecting code, even if we were unconditionally warning on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was always intended to become an error eventually and has been a warning for 3 years, so I figured we can turn it into a hard error by now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM, make sure to run crater :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM, make sure to run crater :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll remove it from the PR for now so we don't have to wait for crater and so I don't have to rebase. I've filed #67098 as a reminder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, besides my prior comments
This comment has been minimized.
This comment has been minimized.
Rebased & dropped the legacy warning stuff for a future PR. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Rebased. :) |
LL | let _ = a and b; | ||
| ^^^ help: use `&&` to perform logical conjunction | ||
| | ||
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if the note calling out python and PHP here is a good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I debated this with myself a few times but in the end I thought that habits from python (PHP less so) would be the most likely source of using and
so it felt like relevant information for such users.
@bors r+ |
📌 Commit 621661f has been approved by |
🌲 The tree is currently closed for pull requests below priority 100, this pull request will be tested once the tree is reopened |
@bors p=199 |
refactor expr & stmt parsing + improve recovery Summary of important changes (best read commit-by-commit, ignoring whitespace changes): - `AttrVec` is introduces as an alias for `ThinVec<Attribute>` - `parse_expr_bottom` and `parse_stmt` are thoroughly refactored. - Extract diagnostics logic for `vec![...]` in a pattern context. - Recovery is added for `do catch { ... }` - Recovery is added for `'label: non_block_expr` - Recovery is added for `var $local`, `auto $local`, and `mut $local`. Fixes #65257. - Recovery is added for `e1 and e2` and `e1 or e2`. - ~~`macro_legacy_warnings` is turned into an error (has been a warning for 3 years!)~~ - Fixes #63396 by forward-porting #64105 which now works thanks to added recovery. - `ui-fulldeps/ast_stmt_expr_attr.rs` is turned into UI and pretty tests. - Recovery is fixed for `#[attr] if expr {}` r? @estebank
☀️ Test successful - checks-azure |
Refactor expression parsing thoroughly Based on rust-lang#66994 together with which this has refactored basically the entirety of `expr.rs`. r? @estebank
Summary of important changes (best read commit-by-commit, ignoring whitespace changes):
AttrVec
is introduces as an alias forThinVec<Attribute>
parse_expr_bottom
andparse_stmt
are thoroughly refactored.vec![...]
in a pattern context.do catch { ... }
'label: non_block_expr
var $local
,auto $local
, andmut $local
. Fixes Use 'mut' as alias for 'let mut' #65257.e1 and e2
ande1 or e2
.macro_legacy_warnings
is turned into an error (has been a warning for 3 years!)parse_bottom_expr
to use list parsing utility #63396 by forward-porting Clean upparse_bottom_expr
to use list parsing utility #64105 which now works thanks to added recovery.ui-fulldeps/ast_stmt_expr_attr.rs
is turned into UI and pretty tests.#[attr] if expr {}
r? @estebank