-
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
WIP: Initial implementation of or-pattern handling in MIR #63688
Conversation
0a13430
to
1991dbd
Compare
@Centril thanks for the comments! Updated to take into account your feedback. Let me know if I missed something. |
ping @matthewjasper any thoughts on how I build the MIR for the or-pattern? |
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.
This seems like a reasonable first step. I think you might be better off using match_candidates
for Or
tests, since handling complex or patterns (e.g. (1, 1, _) | (_, 2, 2)
) would require duplication of most of the remaining match_candidates
code.
I've left a couple of comments for other things I noticed when looking through the changes.
src/librustc_mir/hair/pattern/mod.rs
Outdated
pub struct FieldPattern<'tcx> { | ||
pub field: Field, | ||
pub pattern: Pattern<'tcx>, | ||
} | ||
|
||
#[derive(Clone, Debug)] | ||
#[derive(Clone, Debug, PartialEq)] |
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 can't see where these PartialEq
impls are used. What is the intended meaning of ==
here?
// `SwitchInt` (an `enum`). | ||
// run-pass | ||
#![feature(or_patterns)] | ||
//~^ WARN the feature `or_patterns` is incomplete and may cause the compiler to crash |
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.
Can you allow
this warning for the tests here?
@matthewjasper I couldn't figure out a way to use
It may be that I overlooked something, so please let me know if there is another way to generate the correct candidates for an or-pattern, or if I am misunderstanding |
An or pattern would create a new set of candidates for just that pattern.
|
Ah I see... Yeah that could work. I'll try that out. |
This comment has been minimized.
This comment has been minimized.
@dlrobertson Now that #64111 landed, you might want to try tests with bindings as well if this PR would support that. See https://github.com/rust-lang/rust/pull/64111/files#diff-03c5a135508e329a1f3eae00e79f9ad4R42 for a relevant test. |
Awesome! Thanks... I think it should work more or less without much effort once I move to using a |
This comment has been minimized.
This comment has been minimized.
Working on figuring out where the best place to put the expansion of candidates is (Placing it with match pair simplification would cause exponential blow-up). And we currently don't assume that the list of candidates is grow-able, so I'm also working on correctly handling that. |
or-patterns: Push `PatKind/PatternKind::Or` at top level to HIR & HAIR Following up on work in rust-lang#64111, rust-lang#63693, and rust-lang#61708, in this PR: - We change `hair::Arm.patterns: Vec<Pattern<'_>>` into `hir::Arm.pattern: Pattern<'_>`. - `fn hair::Arm::top_pats_hack` is introduced as a temporary crutch in MIR building to avoid more changes. - We change `hir::Arm.pats: HirVec<P<Pat>>` into `hir::Arm.pat: P<Pat>`. - The hacks in `rustc::hir::lowering` are removed since the representation hack is no longer necessary. - In some places, `fn hir::Arm::top_pats_hack` is introduced to leave some things as future work. - Misc changes: HIR pretty printing is adjusted to behave uniformly wrt. top/inner levels, rvalue promotion is adjusted, regionck, and dead_code is also. - Type checking is adjusted to uniformly handle or-patterns at top/inner levels. To make things compile, `p_0 | ... | p_n` is redefined as a "reference pattern" in [`fn is_non_ref_pat`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/struct.FnCtxt.html#method.is_non_ref_pat) for now. This is done so that reference types are not eagerly stripped from the `expected: Ty<'tcx>`. - Liveness is adjusted wrt. the `unused_variables` and `unused_assignments` lints to handle top/inner levels uniformly and the handling of `fn` parameters, `let` locals, and `match` arms are unified in this respect. This is not tested for now as exhaustiveness checks are reachable and will ICE. - In `check_match`, checking `@` and by-move bindings is adjusted. However, exhaustiveness checking is not adjusted the moment and is handled by @dlrobertson in rust-lang#63688. - AST borrowck (`construct.rs`) is not adjusted as AST borrowck will be removed soon. r? @matthewjasper cc @dlrobertson @varkor @oli-obk
This comment has been minimized.
This comment has been minimized.
or-patterns: Push `PatKind/PatternKind::Or` at top level to HIR & HAIR Following up on work in #64111, #63693, and #61708, in this PR: - We change `hair::Arm.patterns: Vec<Pattern<'_>>` into `hir::Arm.pattern: Pattern<'_>`. - `fn hair::Arm::top_pats_hack` is introduced as a temporary crutch in MIR building to avoid more changes. - We change `hir::Arm.pats: HirVec<P<Pat>>` into `hir::Arm.pat: P<Pat>`. - The hacks in `rustc::hir::lowering` are removed since the representation hack is no longer necessary. - In some places, `fn hir::Arm::top_pats_hack` is introduced to leave some things as future work. - Misc changes: HIR pretty printing is adjusted to behave uniformly wrt. top/inner levels, rvalue promotion is adjusted, regionck, and dead_code is also. - Type checking is adjusted to uniformly handle or-patterns at top/inner levels. To make things compile, `p_0 | ... | p_n` is redefined as a "reference pattern" in [`fn is_non_ref_pat`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/struct.FnCtxt.html#method.is_non_ref_pat) for now. This is done so that reference types are not eagerly stripped from the `expected: Ty<'tcx>`. - Liveness is adjusted wrt. the `unused_variables` and `unused_assignments` lints to handle top/inner levels uniformly and the handling of `fn` parameters, `let` locals, and `match` arms are unified in this respect. This is not tested for now as exhaustiveness checks are reachable and will ICE. - In `check_match`, checking `@` and by-move bindings is adjusted. However, exhaustiveness checking is not adjusted the moment and is handled by @dlrobertson in #63688. - AST borrowck (`construct.rs`) is not adjusted as AST borrowck will be removed soon. r? @matthewjasper cc @dlrobertson @varkor @oli-obk
Still working on it. I've got single or patterns in a pattern working ( Also my current implementation is super hacky... Got a lot of cleanup to do. |
or-patterns: Push `PatKind/PatternKind::Or` at top level to HIR & HAIR Following up on work in rust-lang#64111, rust-lang#63693, and rust-lang#61708, in this PR: - We change `hair::Arm.patterns: Vec<Pattern<'_>>` into `hir::Arm.pattern: Pattern<'_>`. - `fn hair::Arm::top_pats_hack` is introduced as a temporary crutch in MIR building to avoid more changes. - We change `hir::Arm.pats: HirVec<P<Pat>>` into `hir::Arm.pat: P<Pat>`. - The hacks in `rustc::hir::lowering` are removed since the representation hack is no longer necessary. - In some places, `fn hir::Arm::top_pats_hack` is introduced to leave some things as future work. - Misc changes: HIR pretty printing is adjusted to behave uniformly wrt. top/inner levels, rvalue promotion is adjusted, regionck, and dead_code is also. - Type checking is adjusted to uniformly handle or-patterns at top/inner levels. To make things compile, `p_0 | ... | p_n` is redefined as a "reference pattern" in [`fn is_non_ref_pat`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/struct.FnCtxt.html#method.is_non_ref_pat) for now. This is done so that reference types are not eagerly stripped from the `expected: Ty<'tcx>`. - Liveness is adjusted wrt. the `unused_variables` and `unused_assignments` lints to handle top/inner levels uniformly and the handling of `fn` parameters, `let` locals, and `match` arms are unified in this respect. This is not tested for now as exhaustiveness checks are reachable and will ICE. - In `check_match`, checking `@` and by-move bindings is adjusted. However, exhaustiveness checking is not adjusted the moment and is handled by @dlrobertson in rust-lang#63688. - AST borrowck (`construct.rs`) is not adjusted as AST borrowck will be removed soon. r? @matthewjasper cc @dlrobertson @varkor @oli-obk
This comment has been minimized.
This comment has been minimized.
With #64508 merged, it should now be possible to unify the MIR building of or-patterns and link up exhaustiveness checking as well. |
This comment has been minimized.
This comment has been minimized.
Yeah, working on a complete overhaul of the PR. It's gonna take a bit. The conflicts will be resolved when I push up the changes from the overhaul. While the initial implementation works, a more complete implementation will not directly manipulate the CFG (what I'm working on). |
This comment has been minimized.
This comment has been minimized.
I was invited to work on the exhaustiveness checking part of this PR (and I'm very excited !). Is it possible to test the exhaustiveness part independently ? If not, how can we coordinate ? |
This comment has been minimized.
This comment has been minimized.
@Nadrieril I've made a Zulip thread for the work on or-patterns where we can coordinate. Wrt. testing, I believe we can implement exhaustiveness checking for or-patterns independently of MIR building. We can also add tests for cases where the matches are non-exhaustive as this should never reach MIR building. However, for the exhaustive cases this should result in ICEs because MIR building is reachable and I'm not sure if we can test for those in the current rustbuild infrastructure (although I recall @oli-obk saying something about ways to do it). What we could try is to insert a non-exhaustive match that is unrelated to or-patterns just as a canary to make MIR building unreachable. In any case, some incremental progress would be great. :) |
@Dylan-DPC posted an update in the Zulip thread. |
Search for tests using |
This comment has been minimized.
This comment has been minimized.
Handle or-patterns when building MIR by expanding the MatchPair into n Candidates.
Add some basic run-pass ui tests for or-patterns.
1991dbd
to
1bf639a
Compare
Updated... It largely consists of hacks and the current code was written in a manner to make debugging easier on me. Things that I know of that have yet to be implemented/fixed:
|
This comment has been minimized.
This comment has been minimized.
// FIXME(dlrobertson): This could use some cleaning up. | ||
if let PatKind::Or { ref pats } = *match_pair.pattern.kind { | ||
let match_pairs = mem::take(&mut candidates.first_mut().unwrap().match_pairs); | ||
let mut new_candidates = pats.iter().map(|pat| { |
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 was expecting these to be an entirely new set of candidates, containing only the match pairs that come from the or pattern. So this function would call match_candidates
3 times: once for the first candidate, once for the remaining candidates and once for the new candidates from the or pattern.
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.
This comment has been minimized.
This comment has been minimized.
awesome sounds good |
Building on #64508, #64111, #63693, and #61708, this PR adds:
ui
tests for or-patternsCC #54883
r? @matthewjasper