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

never_patterns: Parse match arms with no body #118527

Merged
merged 7 commits into from Dec 8, 2023

Conversation

Nadrieril
Copy link
Member

@Nadrieril Nadrieril commented Dec 2, 2023

Never patterns are meant to signal unreachable cases, and thus don't take bodies:

let ptr: *const Option<!> = ...;
match *ptr {
    None => { foo(); }
    Some(!),
}

This PR makes rustc accept the above, and enforces that an arm has a body xor is a never pattern. This affects parsing of match arms even with the feature off, so this is delicate. (Plus this is my first non-trivial change to the parser).

The last commit is optional; it introduces a bit of churn to allow the new suggestions to be machine-applicable. There may be a better solution? I'm not sure. EDIT: I removed that commit

r? @compiler-errors

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 2, 2023
@rustbot

This comment was marked as outdated.

@Nadrieril
Copy link
Member Author

(only the last commit changes to the size of AST and/or HIR nodes)

@rust-log-analyzer

This comment has been minimized.

@Nadrieril
Copy link
Member Author

Ok giving up on that last commit, I'll find a better solution later

@rust-log-analyzer

This comment has been minimized.

Because a macro invocation can expand to a never pattern, we can't rule
out a `arm!(),` arm at parse time. Instead we detect that case at
expansion time, if the macro tries to output a pattern followed by `=>`.
Parsing now accepts a match arm without a body, so we must make sure to
only accept that if the pattern is a never pattern.
@rustbot
Copy link
Collaborator

rustbot commented Dec 3, 2023

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

Some changes occurred in src/tools/rustfmt

cc @rust-lang/rustfmt

@calebcartwright
Copy link
Member

@compiler-errors do you think this (or perhaps the associated tracking issue/rfc) would be worth t-style discussion?

@compiler-errors
Copy link
Member

@calebcartwright: I will I-style-nominate the tracking issue (if that doesn't exist, I'll add it).

@bors r+ rollup=never

@bors
Copy link
Contributor

bors commented Dec 8, 2023

📌 Commit 431cc4a has been approved by compiler-errors

It is now in the queue for this repository.

@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-review Status: Awaiting review from the assignee but also interested parties. labels Dec 8, 2023
@bors
Copy link
Contributor

bors commented Dec 8, 2023

⌛ Testing commit 431cc4a with merge 2b399b5...

@bors
Copy link
Contributor

bors commented Dec 8, 2023

☀️ Test successful - checks-actions
Approved by: compiler-errors
Pushing 2b399b5 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Dec 8, 2023
@bors bors merged commit 2b399b5 into rust-lang:master Dec 8, 2023
12 checks passed
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (2b399b5): comparison URL.

Overall result: ❌✅ regressions and improvements - ACTION NEEDED

Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please open an issue or create a new PR that fixes the regressions, add a comment linking to the newly created issue or PR, and then add the perf-regression-triaged label to this PR.

@rustbot label: +perf-regression
cc @rust-lang/wg-compiler-performance

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
0.1% [0.1%, 0.1%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.9% [-1.0%, -0.8%] 2
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.5% [-1.0%, 0.1%] 3

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
1.7% [1.7%, 1.7%] 1
Regressions ❌
(secondary)
3.0% [2.1%, 4.6%] 3
Improvements ✅
(primary)
-0.9% [-1.4%, -0.4%] 2
Improvements ✅
(secondary)
-3.8% [-3.8%, -3.8%] 1
All ❌✅ (primary) -0.0% [-1.4%, 1.7%] 3

Cycles

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
0.5% [0.5%, 0.5%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.1% [-2.1%, -2.1%] 1
All ❌✅ (primary) 0.5% [0.5%, 0.5%] 1

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 675.635s -> 674.909s (-0.11%)
Artifact size: 314.02 MiB -> 314.05 MiB (0.01%)

@rustbot rustbot added the perf-regression Performance regression. label Dec 8, 2023
@Nadrieril Nadrieril deleted the never_patterns_parse branch December 8, 2023 23:03
@Nadrieril Nadrieril added F-never_patterns `#![feature(never_patterns)]` and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Dec 9, 2023
@Mark-Simulacrum Mark-Simulacrum added the I-lang-nominated The issue / PR has been nominated for discussion during a lang team meeting. label Dec 12, 2023
@Mark-Simulacrum
Copy link
Member

This affects parsing of match arms even with the feature off, so this is delicate.

Is this change FCP'd or nightly-only? It sounds like this is adding new syntax to the language -- is there a lang sign-off on that somewhere?

(I'm surprised this landed without that).

@Mark-Simulacrum
Copy link
Member

Perf regression looks to be genuine but likely not worth investigating, limited to single primary incr-unchanged scenario.

@Mark-Simulacrum Mark-Simulacrum added the perf-regression-triaged The performance regression has been triaged. label Dec 12, 2023
@Nadrieril
Copy link
Member Author

It sounds like this is adding new syntax to the language -- is there a lang sign-off on that somewhere?

It's not adding syntax to stable rust. What's different is that now the parser accepts match arms with no body and they're rejected later, instead of them being rejected by the parser directly.

@petrochenkov
Copy link
Contributor

What's different is that now the parser accepts match arms with no body and they're rejected later, instead of them being rejected by the parser directly.

The difference is that

match *ptr {
    None => { foo(); }
    #[cfg(FALSE)]
    Some(!),
}

will compile on stable.

Any unstable syntax needs to be feature-gated at parser level using gated_spans.

@Nadrieril
Copy link
Member Author

Nadrieril commented Dec 12, 2023

Oh shoot yeah I didn't consider that. I knew there would be a subtlety. To be precise,

match *ptr {
    None => { foo(); }
    #[cfg(FALSE)]
    Some(!),
}

does not compile on stable because ! is correctly gated at parser level: https://github.com/rust-lang/rust/blob/master/tests/ui/feature-gates/feature-gate-never_patterns.rs

However this now compiles on stable:

match Some(0) {
    None => { foo(); }
    #[cfg(FALSE)]
    Some(_)
}

which is much worse.

@Nadrieril
Copy link
Member Author

I don't want to gate a token here though, I want to give a user a normal parse error. Is there a way in the parser to know which feature gates are active? This may not even make sense if we aren't done parsing though...

@Nadrieril
Copy link
Member Author

Fix is up: #118868

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Dec 12, 2023
…terns-parsing, r=petrochenkov

Correctly gate the parsing of match arms without body

rust-lang#118527 accidentally allowed the following to parse on stable:
```rust
match Some(0) {
    None => { foo(); }
    #[cfg(FALSE)]
    Some(_)
}
```

This fixes that oversight. The way I choose which error to emit is the best I could think of, I'm open if you know a better way.

r? `@petrochenkov` since you're the one who noticed
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Dec 12, 2023
Rollup merge of rust-lang#118868 - Nadrieril:correctly-gate-never_patterns-parsing, r=petrochenkov

Correctly gate the parsing of match arms without body

rust-lang#118527 accidentally allowed the following to parse on stable:
```rust
match Some(0) {
    None => { foo(); }
    #[cfg(FALSE)]
    Some(_)
}
```

This fixes that oversight. The way I choose which error to emit is the best I could think of, I'm open if you know a better way.

r? `@petrochenkov` since you're the one who noticed
flip1995 pushed a commit to flip1995/rust that referenced this pull request Dec 16, 2023
…mpiler-errors

never_patterns: Parse match arms with no body

Never patterns are meant to signal unreachable cases, and thus don't take bodies:
```rust
let ptr: *const Option<!> = ...;
match *ptr {
    None => { foo(); }
    Some(!),
}
```
This PR makes rustc accept the above, and enforces that an arm has a body xor is a never pattern. This affects parsing of match arms even with the feature off, so this is delicate. (Plus this is my first non-trivial change to the parser).

~~The last commit is optional; it introduces a bit of churn to allow the new suggestions to be machine-applicable. There may be a better solution? I'm not sure.~~ EDIT: I removed that commit

r? `@compiler-errors`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Dec 28, 2023
…nkov

Don't suggest writing a bodyless arm if the pattern can never be a never pattern

rust-lang#118527 enabled arms to be bodyless for never patterns ; this PR removes the `,` and `}` suggestions for patterns that could never be never patterns.
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Dec 28, 2023
Rollup merge of rust-lang#119380 - ShE3py:match-never-pat, r=petrochenkov

Don't suggest writing a bodyless arm if the pattern can never be a never pattern

rust-lang#118527 enabled arms to be bodyless for never patterns ; this PR removes the `,` and `}` suggestions for patterns that could never be never patterns.
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 30, 2023
…cjgillot

Don't drop a hir node after lowering

Fixes rust-lang#119271.

It seems that all hir nodes that get allocated an id must be placed within the hir on pain of ICEs. In rust-lang#118527 I dropped guards on never patterns since they're not useful, which caused the ICE.
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Dec 31, 2023
Don't drop a hir node after lowering

Fixes rust-lang/rust#119271.

It seems that all hir nodes that get allocated an id must be placed within the hir on pain of ICEs. In rust-lang/rust#118527 I dropped guards on never patterns since they're not useful, which caused the ICE.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-never_patterns `#![feature(never_patterns)]` I-lang-nominated The issue / PR has been nominated for discussion during a lang team meeting. merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. 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.

None yet

9 participants