or-patterns: Push PatKind/PatternKind::Or at top level to HIR & HAIR#64508
or-patterns: Push PatKind/PatternKind::Or at top level to HIR & HAIR#64508bors merged 22 commits intorust-lang:masterfrom
PatKind/PatternKind::Or at top level to HIR & HAIR#64508Conversation
…ngs_named_same_as_variants`.
| for p in &arm.pats { | ||
| self.constrain_bindings_in_pat(p); | ||
| } | ||
| self.constrain_bindings_in_pat(&arm.pat); |
There was a problem hiding this comment.
Not sure what appropriate tests for diffs in this module would be.
Pacify `tidy`. It's also more correct in this context.
src/librustc/hir/pat_util.rs
Outdated
| /// `match foo() { Some(a) => (), None => () }`. | ||
| /// | ||
| /// When encountering an or-pattern `p_0 | ... | p_n` only `p_0` will be visited. | ||
| pub fn each_binding_or_first<F>(&self, c: &mut F) |
There was a problem hiding this comment.
| pub fn each_binding_or_first<F>(&self, c: &mut F) | |
| pub fn each_binding_or_first<F>(&self, f: &mut F) |
There was a problem hiding this comment.
Is calling each_binding_or_first recursively going to have the right behaviour for nested Or patterns? Shouldn't it pick the first pattern only at the top level? (In which case, you can use each_binding instead and just check the top level at the call site.)
There was a problem hiding this comment.
(Using c for callback as f is used for FieldPat; could switch to g for the callback instead.)
(We discussed this a bit privately on Discord; The existing commentary in define_bindings_in_pat states that we only consider the first pattern since any later patterns must have the same bindings (and the first pattern is considered to have the authoritative set of ids). This suggests that we should do the same in nested positions as there should be no intrinsic semantic difference between Some(a @ 1) | Some(a @ 2) and Some(a @ (1 | 2)). That said, I don't really know why we only consider the first pattern and if we just use .each_binding(...) uniformly for top/nested then the UI tests pass at least.)
There was a problem hiding this comment.
It's actually due to @nikomatsakis here: e47d2f6#diff-97c8d3b79a36724da452cf176a6a42b5R661-R663.
There was a problem hiding this comment.
I don't even understand what the question is here. :)
There was a problem hiding this comment.
@nikomatsakis So your comment to a call of .define_bindings_in_pat(...) in liveness.rs regarding ExprKind::Match(...) => states that:
// only consider the first pattern; any later patterns must have
// the same bindings, and we also consider the first pattern to be
// the "authoritative" set of ids
let arm_succ =
self.define_bindings_in_arm_pats(arm.pats.first().map(|p| &**p),
guard_succ);Now, I don't exactly understand why this is, but my intuition says that if we want to extend this logic to nested or-patterns, e.g. Some(A(x) | B(x)) then we should do the same think there. That is, in any PatKind::Or(pats) we will just visit pats[0] and not pats[1..]. That's what the code in this PR does now.
There was a problem hiding this comment.
Well, so here's the problem. Presently we use the id of the AST node for a pattern binding as the variable's id -- but when you have e.g. Foo(x) | Bar(x), you wind up with two id's for x! Clearly all the alternatives must have the same set of bindings (i.e., they must all define x), so yeah I dimly recall deciding that we would just use the id's from the first set of patterns to define the variables, and then check the remaining patterns against that first set.
I think another viable approach would be to use some kind of fresh identifiers for the variables (not the id from the pattern node) and then be able to "resolve" each pattern node to that. Or perhaps to have a table of "redirects" where for most bindings the redirect is the identity, but for | patterns they point to the bindings from the first set.
In any case I think you are correct that if we are moving | patterns further down, and we want to try and use the same strategy, then we only want to take the left-most branches (but check the other branches for consistency).
There was a problem hiding this comment.
Thanks for the elaboration!
Clearly all the alternatives must have the same set of bindings (i.e., they must all define
x), so yeah I dimly recall deciding that we would just use the id's from the first set of patterns to define the variables, and then check the remaining patterns against that first set.
(but check the other branches for consistency).
Yea, that's what we do; I recently tweaked this logic in resolve here:
rust/src/librustc_resolve/late.rs
Lines 1121 to 1475 in 9b9d2af
I think another viable approach would be to use some kind of fresh identifiers for the variables (not the id from the pattern node) and then be able to "resolve" each pattern node to that. Or perhaps to have a table of "redirects" where for most bindings the redirect is the identity, but for
|patterns they point to the bindings from the first set.
Sounds interesting (but should be done in a follow-up if so). cc @petrochenkov may be interested.
varkor
left a comment
There was a problem hiding this comment.
Looks good overall. I want to check whether https://github.com/rust-lang/rust/pull/64508/files#r324706033 is intentional or not, though.
src/librustc/hir/pat_util.rs
Outdated
| /// `match foo() { Some(a) => (), None => () }`. | ||
| /// | ||
| /// When encountering an or-pattern `p_0 | ... | p_n` only `p_0` will be visited. | ||
| pub fn each_binding_or_first<F>(&self, c: &mut F) |
There was a problem hiding this comment.
Is calling each_binding_or_first recursively going to have the right behaviour for nested Or patterns? Shouldn't it pick the first pattern only at the top level? (In which case, you can use each_binding instead and just check the top level at the call site.)
Also tweak walkers on `Pat`.
|
@matthewjasper @varkor Tweaked |
|
@bors r+ |
|
📌 Commit 0918dc4 has been approved by |
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
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
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Triage: Blocking on toolstate breakage-ban being lifted in a few days. |
|
@bors retry can break toolstate again. |
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
Rollup of 6 pull requests Successful merges: - #62975 (Almost fully deprecate hir::map::Map.hir_to_node_id) - #64386 (use `sign` variable in abs and wrapping_abs methods) - #64508 (or-patterns: Push `PatKind/PatternKind::Or` at top level to HIR & HAIR) - #64738 (Add const-eval support for SIMD types, insert, and extract) - #64759 (Refactor mbe a tiny bit) - #64764 (Master is now 1.40 ) Failed merges: r? @ghost
Following up on work in #64111, #63693, and #61708, in this PR:
We change
hair::Arm.patterns: Vec<Pattern<'_>>intohir::Arm.pattern: Pattern<'_>.fn hair::Arm::top_pats_hackis introduced as a temporary crutch in MIR building to avoid more changes.We change
hir::Arm.pats: HirVec<P<Pat>>intohir::Arm.pat: P<Pat>.The hacks in
rustc::hir::loweringare removed since the representation hack is no longer necessary.In some places,
fn hir::Arm::top_pats_hackis 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_nis redefined as a "reference pattern" infn is_non_ref_patfor now. This is done so that reference types are not eagerly stripped from theexpected: Ty<'tcx>.Liveness is adjusted wrt. the
unused_variablesandunused_assignmentslints to handle top/inner levels uniformly and the handling offnparameters,letlocals, andmatcharms 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 WIP: Initial implementation of or-pattern handling in MIR #63688.AST borrowck (
construct.rs) is not adjusted as AST borrowck will be removed soon.r? @matthewjasper
cc @dlrobertson @varkor @oli-obk