Emit proper errors when on missing closure braces#88546
Merged
bors merged 1 commit intorust-lang:masterfrom Sep 11, 2021
Merged
Emit proper errors when on missing closure braces#88546bors merged 1 commit intorust-lang:masterfrom
bors merged 1 commit intorust-lang:masterfrom
Conversation
921a11b to
3bdda1c
Compare
estebank
reviewed
Sep 1, 2021
estebank
reviewed
Sep 1, 2021
estebank
reviewed
Sep 2, 2021
estebank
reviewed
Sep 2, 2021
Comment on lines
7
to
11
| error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>` | ||
| --> $DIR/ruby_style_closure.rs:2:22 | ||
| | | ||
| LL | let p = Some(45).and_then({ | ||
| | ^^^^^^^^ expected an `FnOnce<({integer},)>` closure, found `Option<_>` |
Contributor
There was a problem hiding this comment.
This should be pointing at the Some(x * 2) as well. (Not something to address in this PR)
This comment has been minimized.
This comment has been minimized.
estebank
approved these changes
Sep 3, 2021
Contributor
estebank
left a comment
There was a problem hiding this comment.
r=me after addressing the comments.
estebank
reviewed
Sep 3, 2021
estebank
reviewed
Sep 6, 2021
Comment on lines
+1741
to
+1767
| if self.token.kind == TokenKind::Semi && self.token_cursor.frame.delim == DelimToken::Paren | ||
| { | ||
| // It is likely that the closure body is a block but where the | ||
| // braces have been removed. We will recover and eat the next | ||
| // statements later in the parsing process. | ||
| body = self.mk_expr_err(body.span); | ||
| } |
Contributor
There was a problem hiding this comment.
I'm somewhat uneasy with this check, but having both Semi and Paren be true should only happen on malformed code.
Contributor
|
@bors r+ |
Collaborator
|
📌 Commit 99c46c0 has been approved by |
GuillaumeGomez
added a commit
to GuillaumeGomez/rust
that referenced
this pull request
Sep 9, 2021
…races, r=estebank
Emit proper errors when on missing closure braces
This commit focuses on emitting clean errors for the following syntax
error:
```
Some(42).map(|a|
dbg!(a);
a
);
```
Previous implementation tried to recover after parsing the closure body
(the `dbg` expression) by replacing the next `;` with a `,`, which made
the next expression belong to the next function argument. As such, the
following errors were emitted (among others):
- the semicolon token was not expected,
- a is not in scope,
- Option::map is supposed to take one argument, not two.
This commit allows us to gracefully handle this situation by adding
giving the parser the ability to remember when it has just parsed a
closure body inside a function call. When this happens, we can treat the
unexpected `;` specifically and try to parse as much statements as
possible in order to eat the whole block. When we can't parse statements
anymore, we generate a clean error indicating that the braces are
missing, and return an ExprKind::Err.
Closes rust-lang#88065.
r? `@estebank`
This commit focuses on emitting clean errors for the following syntax
error:
```
Some(42).map(|a|
dbg!(a);
a
);
```
Previous implementation tried to recover after parsing the closure body
(the `dbg` expression) by replacing the next `;` with a `,`, which made
the next expression belong to the next function argument. As such, the
following errors were emitted (among others):
- the semicolon token was not expected,
- a is not in scope,
- Option::map is supposed to take one argument, not two.
This commit allows us to gracefully handle this situation by adding
giving the parser the ability to remember when it has just parsed a
closure body inside a function call. When this happens, we can treat the
unexpected `;` specifically and try to parse as much statements as
possible in order to eat the whole block. When we can't parse statements
anymore, we generate a clean error indicating that the braces are
missing, and return an ExprKind::Err.
99c46c0 to
b21425d
Compare
Contributor
|
@bors r+ |
Collaborator
|
📌 Commit b21425d has been approved by |
Contributor
Author
|
Thanks for the approval and sorry for the noise I created. I'll do better next time :) |
bors
added a commit
to rust-lang-ci/rust
that referenced
this pull request
Sep 11, 2021
…arth Rollup of 15 pull requests Successful merges: - rust-lang#85200 (Ignore derived Clone and Debug implementations during dead code analysis) - rust-lang#86165 (Add proc_macro::Span::{before, after}.) - rust-lang#87088 (Fix stray notes when the source code is not available) - rust-lang#87441 (Emit suggestion when passing byte literal to format macro) - rust-lang#88546 (Emit proper errors when on missing closure braces) - rust-lang#88578 (fix(rustc): suggest `items` be borrowed in `for i in items[x..]`) - rust-lang#88632 (Fix issues with Markdown summary options) - rust-lang#88639 (rustdoc: Fix ICE with `doc(hidden)` on tuple variant fields) - rust-lang#88667 (Tweak `write_fmt` doc.) - rust-lang#88720 (Rustdoc coverage fields count) - rust-lang#88732 (RustWrapper: avoid deleted unclear attribute methods) - rust-lang#88742 (Fix table in docblocks) - rust-lang#88776 (Workaround blink/chromium grid layout limitation of 1000 rows) - rust-lang#88807 (Fix typo in docs for iterators) - rust-lang#88812 (Fix typo `option` -> `options`.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
bors
added a commit
to rust-lang-ci/rust
that referenced
this pull request
Sep 16, 2021
… r=nagisa
Point at argument instead of call for their obligations
When an obligation is introduced by a specific `fn` argument, point at
the argument instead of the `fn` call if the obligation fails to be
fulfilled.
Move the information about pointing at the call argument expression in
an unmet obligation span from the `FulfillmentError` to a new
`ObligationCauseCode`.
When giving an error about an obligation introduced by a function call
that an argument doesn't fulfill, and that argument is a block, add a
span_label pointing at the innermost tail expression.
Current output:
```
error[E0425]: cannot find value `x` in this scope
--> f10.rs:4:14
|
4 | Some(x * 2)
| ^ not found in this scope
error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>`
--> f10.rs:2:31
|
2 | let p = Some(45).and_then({
| ______________________--------_^
| | |
| | required by a bound introduced by this call
3 | | |x| println!("doubling {}", x);
4 | | Some(x * 2)
| | -----------
5 | | });
| |_____^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
|
= help: the trait `FnOnce<({integer},)>` is not implemented for `Option<_>`
```
Previous output:
```
error[E0425]: cannot find value `x` in this scope
--> f10.rs:4:14
|
4 | Some(x * 2)
| ^ not found in this scope
error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>`
--> f10.rs:2:22
|
2 | let p = Some(45).and_then({
| ^^^^^^^^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
|
= help: the trait `FnOnce<({integer},)>` is not implemented for `Option<_>`
```
Partially address rust-lang#27300. Will require rebasing on top of rust-lang#88546.
This was referenced Oct 19, 2022
Dylan-DPC
added a commit
to Dylan-DPC/rust
that referenced
this pull request
Oct 22, 2022
…-in-macro, r=fee1-dead Allow semicolon after closure within parentheses in macros rust-lang#88546 added some parsing logic that if we're parsing a closure, and we're within parentheses, and a semicolon follows, then we must be parsing something erroneous like: `f(|| a; b)`, so it replaces the closure body with an error expression. However, it's valid to parse those tokens if we're within a macro, as in rust-lang#103222. This is a bit unsatisfying fix. Is there a more robust way of checking that we're within a macro? I would also be open to removing this "_It is likely that the closure body is a block but where the braces have been removed_" check altogether at the expense of more verbose errors, since it seems very suspicious in the first place... Fixes rust-lang#103222.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This commit focuses on emitting clean errors for the following syntax
error:
Previous implementation tried to recover after parsing the closure body
(the
dbgexpression) by replacing the next;with a,, which madethe next expression belong to the next function argument. As such, the
following errors were emitted (among others):
This commit allows us to gracefully handle this situation by adding
giving the parser the ability to remember when it has just parsed a
closure body inside a function call. When this happens, we can treat the
unexpected
;specifically and try to parse as much statements aspossible in order to eat the whole block. When we can't parse statements
anymore, we generate a clean error indicating that the braces are
missing, and return an ExprKind::Err.
Closes #88065.
r? @estebank