Skip to content
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

fix ICE when parsing lifetime as function argument #93595

Merged
merged 2 commits into from
Feb 12, 2022

Conversation

compiler-errors
Copy link
Member

@compiler-errors compiler-errors commented Feb 2, 2022

I don't really like this, but we basically need to emit an error instead of just delaying an bug, because there are too many places in the AST that aren't covered by my previous PRs...

cc: #93282 (comment)

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Feb 2, 2022
@rust-highfive
Copy link
Collaborator

r? @jackh726

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 2, 2022
Copy link
Member

@jackh726 jackh726 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't quite seem right :)

I would have expected that the "recovery" here is just to fall back to generics with a lifetime.

@jackh726 jackh726 added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 12, 2022
@compiler-errors
Copy link
Member Author

I would have expected that the "recovery" here is just to fall back to generics with a lifetime.

@jackh726, this fix is actually for when we parse lifetimes in the expression position. This happens when we have a lifetime token as the first token when parsing a loop expression.

So the deal is that we delayed a bug in the code, but none of the paths that I've previously added which do recovery for bad generics apply to something like:

fn main() {
  function('a,
        // ^^- here

@compiler-errors
Copy link
Member Author

compiler-errors commented Feb 12, 2022

Not sure how to fix this other than emitting a sometimes-unhelpful error. This error existed in the past, before I added the delay-span-bug that I reverted here.

For context: #92876 (specifically this)

"let ".to_string(),
Applicability::MachineApplicable,
);
// Check if our lhs is a child of the condition of a while loop
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this definitely got included from another PR of mine. I'll revert this!

Revert spurious changes included in PR
@jackh726
Copy link
Member

For the function arg case, I could see this as acceptable (given that you actually can use a labeled expr as an argument - or at least I would expect that to work). For the generics though, I'm a bit surprised we get to parse_labeled_expr in the first place. Maybe consts could have a labeled expr as a value (but I would expect those to have to be enclosed in {}). This can probably be conditional on if we're enclosed in () vs {}

@compiler-errors
Copy link
Member Author

compiler-errors commented Feb 12, 2022

Well in the case we have an expr x < 'a, we need to parse that 'a as an expression (just the loop label), and then we parse the whole thing as a comparison operator. This is important for the recovery in the case we do have a bad turbofish. But in the case we don't have a bad turbofish, we need to emit an error.

We can't just raise a PResult::Err when we see a bare 'a in expr position, because we have no way of distinguishing that the error is one we can recover as turbofish generics.

It's just because the recovery is split over too many layers, since that < looks like an expression until much later, when we see >, and we try to recover the chained comparison operator error.

@compiler-errors
Copy link
Member Author

compiler-errors commented Feb 12, 2022

I think that explanation of mine is a bit complicated. To put it in a different way:

We don't start recovering a bad turbofish until after we have parsed the bad label expression. If we continue to delay a bug in the label parsing code like we're doing now, we must be absolutely certain we're going to emit another bug later on all codepaths we took to get here, in order to prevent an ICE (sorry, you definitely know this already, just want to spell out my thought process clearly).

It turns out this doesn't always work out, since we cannot bubble up the information that we've parsed a naked lifetime label token through the various layers of parse_expr, since we just return an expression (and doing so would be a very heavy change). We can't bubble down the expectation that we might be currently parsing something that looks like a bad turbofish either, because we already parsed the < of the turbofish as a regular operator expression.

This example, which ICEs, might help demonstrate something that locally looks like a bad turbofish, but which parses (incorrectly) today, since we only delay a bug when we parse that bad lifetime 'a.

fn f(_a1: bool, _a2: bool) {
    let a = 1i32;
    let b = 1i32;
    f(a < 'a, b > (1))
}

This PR just adds emitting an error back to the label parsing code, which I supressed in previous PR. I'd rather us possibly emit two errors, where one is redundant, and emit zero and ICE on certain pathological cases.

@jackh726
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Feb 12, 2022

📌 Commit 5be9e79 has been approved by jackh726

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 12, 2022
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Feb 12, 2022
…, r=jackh726

fix ICE when parsing lifetime as function argument

I don't really like this, but we basically need to emit an error instead of just delaying an bug, because there are too many places in the AST that aren't covered by my previous PRs...

cc: rust-lang#93282 (comment)
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 12, 2022
…askrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#91908 (Add 2 tests)
 - rust-lang#93595 (fix ICE when parsing lifetime as function argument)
 - rust-lang#93757 (Add some known GAT bugs as tests)
 - rust-lang#93759 (Pretty print ItemKind::Use in rustfmt style)
 - rust-lang#93897 (linkchecker: fix panic on directory symlinks)
 - rust-lang#93898 (tidy: Extend error code check)
 - rust-lang#93928 (Add missing release notes for rust-lang#85200)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 602898a into rust-lang:master Feb 12, 2022
@rustbot rustbot added this to the 1.60.0 milestone Feb 12, 2022
@compiler-errors compiler-errors deleted the ice-on-lifetime-arg branch April 7, 2022 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants