about summary refs log tree commit diff
path: root/compiler/rustc_mir_build/src/builder/matches/mod.rs
AgeCommit message (Collapse)AuthorLines
2025-09-01Auto merge of #144783 - folkertdev:loop-match-diverging-loop, r=SparrowLiibors-1/+1
fix `#[loop_match]` on diverging loop tracking issue: https://github.com/rust-lang/rust/issues/132306 fixes https://github.com/rust-lang/rust/issues/144492 fixes https://github.com/rust-lang/rust/issues/144493 fixes https://github.com/rust-lang/rust/issues/144781 this generated invalid MIR before. issue https://github.com/rust-lang/rust/issues/143806 still has an issue where we assign `state = state` which is invalid in MIR. Fixing that problem is tricky, so I'd like to do that separately. r? `@bjorn3`
2025-08-14Apply suggestions from code reviewRalf Jung-2/+2
Co-authored-by: Boxy <rust@boxyuwu.dev>
2025-08-14shrink TestBranch::Constant and PatRangeBoundary::FiniteRalf Jung-3/+3
2025-08-14use ty::Value instead of manual pairs of types and valtreesRalf Jung-5/+4
2025-08-14pattern testing: store constants as valtreesRalf Jung-7/+8
2025-08-14PatKind: store constants as valtreesRalf Jung-1/+1
2025-08-10add place mention for `#[loop_match]` scrutineeFolkert de Vries-1/+1
2025-08-09Auto merge of #143376 - dianne:guard-scope, r=matthewjasperbors-37/+43
add a scope for `if let` guard temporaries and bindings This fixes my concern with `if let` guard drop order, namely that the guard's bindings and temporaries were being dropped after their arm's pattern's bindings, instead of before (https://github.com/rust-lang/rust/pull/141295#issuecomment-2968975596). The guard's bindings and temporaries now live in a new scope, which extends until (but not past) the end of the arm, guaranteeing they're dropped before the arm's pattern's bindings. This only introduces a new scope for match arms with guards. Perf results (https://github.com/rust-lang/rust/pull/143376#issuecomment-3034922617) seemed to indicate there wasn't a significant hit to introduce a new scope on all match arms, but guard patterns (rust-lang/rust#129967) will likely benefit from only adding new scopes when necessary (with some patterns requiring multiple nested scopes). Tracking issue for `if_let_guard`: rust-lang/rust#51114 Tests are adapted from examples by `@traviscross,` `@est31,` and myself on rust-lang/rust#141295.
2025-08-08Rollup merge of #144999 - Zalathar:remove-mcdc, r=oli-obkStuart Cook-8/+2
coverage: Remove all unstable support for MC/DC instrumentation Preliminary support for a partial implementation of “Modified Condition/Decision Coverage” instrumentation was added behind the unstable flag `-Zcoverage-options=mcdc` in 2024. These are the most substantial PRs involved: - rust-lang/rust#123409 - rust-lang/rust#126733 At the time, I accepted these PRs with relatively modest scrutiny, because I did not want to stand in the way of independent work on MC/DC instrumentation. My hope was that ongoing work by interested contributors would lead to the code becoming clearer and more maintainable over time. --- However, that MC/DC code has proven itself to be a major burden on overall maintenance of coverage instrumentation, and a major obstacle to other planned improvements, such as internal changes needed for proper support of macro expansion regions. I have also become reluctant to accept any further MC/DC-related changes that would increase this burden. That tension has resulted in an unhappy impasse. On one hand, the present MC/DC implementation is not yet complete, and shows little sign of being complete at an acceptable level of code quality in the foreseeable future. On the other hand, the continued existence of this partial MC/DC implementation is imposing serious maintenance burdens on every other aspect of coverage instrumentation, and is preventing some of the very improvements that would make it easier to accept expanded MC/DC support in the future. While I know this will be disappointing to some, I think the healthy way forward is accept that I made the wrong call in accepting the current implementation, and to remove it entirely from the compiler.
2025-08-07only introduce a guard scope for arms with guardsdianne-4/+6
2025-08-07add a scope for `if let` guard temporaries and bindingsdianne-37/+41
This ensures `if let` guard temporaries and bindings are dropped before the match arm's pattern's bindings.
2025-08-07Rollup merge of #143764 - dianne:primary-binding-drop-order, ↵Stuart Cook-36/+97
r=Nadrieril,traviscross lower pattern bindings in the order they're written and base drop order on primary bindings' order To fix rust-lang/rust#142163, this PR does two things: - Makes match arms base their drop order on the first sub-branch instead of the last sub-branch. Together with the second change, this makes bindings' drop order correspond to the relative order of when each binding first appears (i.e. the order of the "primary" bindings). - Lowers pattern bindings in the order they're written (still treating the right-hand side of a ``@`` as coming before the binding on the left). In each sub-branch of a match arm, this is the order that would be obtained if the or-alternatives chosen in that sub-branch were inlined into the arm's pattern. This both affects drop order (making bindings in or-patterns not be dropped first) and fixes the issue in [this test](https://github.com/rust-lang/rust/blob/2a023bf80a6fbd6a06d5460a34eb247b986286ed/tests/ui/pattern/bindings-after-at/bind-by-copy-or-pat.rs) from rust-lang/rust#121716. My approach to the second point is admittedly a bit trickier than may be necessary. To avoid passing around a counter when building `FlatPat`s, I've instead added just enough information to recover the original structure of the pattern's bindings from a `MatchTreeSubBranch`'s path through the `Candidate` tree. Some alternatives: - We could use a counter, then sort bindings by their ordinals when making `MatchTreeSubBranch`es. - I'd like to experiment with always merging sub-candidates and removing `test_remaining_match_pairs_after_or`; that would require lowering bindings and guards in a different way. That makes it a bigger change too, though, so I figure it might be simplest to start here. - For a very big change, we could track which or-alternatives succeed at runtime to base drop order on the binding order in the particular alternatives matched. This is a breaking change. It will need a crater run, language team sign-off, and likely updates to the Reference. This will conflict with rust-lang/rust#143376 and probably also rust-lang/rust#143028, so they shouldn't be merged at the same time. r? `@matthewjasper` or `@Nadrieril`
2025-08-07Rollup merge of #143028 - dianne:let-else-storage, r=oli-obk,traviscrossStuart Cook-44/+8
emit `StorageLive` and schedule `StorageDead` for `let`-`else`'s bindings after matching This PR removes special handling of `let`-`else`, so that `StorageLive`s are emitted and `StorageDead`s are scheduled only after pattern-matching has succeeded. This means `StorageDead`s will no longer appear for all of its bindings on the `else` branch (because they're not live yet) and its drops&`StorageDead`s will happen together like they do elsewhere, rather than having all drops first, then all `StorageDead`s. This fixes rust-lang/rust#142056, and is therefore a breaking change. I believe it'll need a crater run and a T-lang nomination/fcp thereafter. Specifically, this makes drop-checking slightly more restrictive for `let`-`else` to match the behavior of other variable binding forms. An alternative approach could be to change the relative order of drops and `StorageDead`s for other binding forms to make drop-checking more permissive, but making that consistent would be a significantly more involved change. r? mir cc `````@dingxiangfei2009````` `````@rustbot````` label +T-lang +needs-crater
2025-08-06lower bindings in the order they're writtendianne-8/+74
2025-08-06base drop order on the first sub-branchdianne-9/+3
2025-08-06don't schedule unnecessary drops when lowering or-patternsdianne-28/+29
This avoids scheduling drops and immediately unscheduling them. Drops for guard bindings/temporaries are still scheduled and unscheduled as before.
2025-08-06coverage: Remove all unstable support for MC/DC instrumentationZalathar-8/+2
2025-07-01loop match: handle opaque patternsFolkert de Vries-2/+4
fixes issue 143203
2025-06-29mir: Add a `new` method to `statement`dianqk-8/+8
Avoid introducing a large number of changes when adding optional initialization fields.
2025-06-25emit `StorageLive` and schedule `StorageDead` for `let`-`else` after matchingdianne-44/+8
2025-06-23Add `#[loop_match]` for improved DFA codegenbjorn3-9/+135
Co-authored-by: Folkert de Vries <folkert@folkertdev.nl>
2025-03-28Add `{ast,hir,thir}::PatKind::Missing` variants.Nicholas Nethercote-0/+1
"Missing" patterns are possible in bare fn types (`fn f(u32)`) and similar places. Currently these are represented in the AST with `ast::PatKind::Ident` with no `by_ref`, no `mut`, an empty ident, and no sub-pattern. This flows through to `{hir,thir}::PatKind::Binding` for HIR and THIR. This is a bit nasty. It's very non-obvious, and easy to forget to check for the exceptional empty identifier case. This commit adds a new variant, `PatKind::Missing`, to do it properly. The process I followed: - Add a `Missing` variant to `{ast,hir,thir}::PatKind`. - Chang `parse_param_general` to produce `ast::PatKind::Missing` instead of `ast::PatKind::Missing`. - Look through `kw::Empty` occurrences to find functions where an existing empty ident check needs replacing with a `PatKind::Missing` check: `print_param`, `check_trait_item`, `is_named_param`. - Add a `PatKind::Missing => unreachable!(),` arm to every exhaustive match identified by the compiler. - Find which arms are actually reachable by running the test suite, changing them to something appropriate, usually by looking at what would happen to a `PatKind::Ident`/`PatKind::Binding` with no ref, no `mut`, an empty ident, and no subpattern. Quite a few of the `unreachable!()` arms were never reached. This makes sense because `PatKind::Missing` can't happen in every pattern, only in places like bare fn tys and trait fn decls. I also tried an alternative approach: modifying `ast::Param::pat` to hold an `Option<P<Pat>>` instead of a `P<Pat>`, but that quickly turned into a very large and painful change. Adding `PatKind::Missing` is much easier.
2025-03-26Rollup merge of #138959 - meithecatte:matchpair-place-option, r=ZalatharStuart Cook-2/+10
Revert "Make MatchPairTree::place non-optional" Reverts a part of #137875. Fixes #138958. cc `@Zalathar`
2025-03-26Rollup merge of #138818 - khuey:138198, r=jieyouxuStuart Cook-16/+42
Don't produce debug information for compiler-introduced-vars when desugaring assignments. An assignment such as (a, b) = (b, c); desugars to the HIR { let (lhs, lhs) = (b, c); a = lhs; b = lhs; }; The repeated `lhs` leads to multiple Locals assigned to the same DILocalVariable. Rather than attempting to fix that, get rid of the debug info for these bindings that don't even exist in the program to begin with. Fixes #138198 r? `@jieyouxu`
2025-03-26MatchPairTree: update invariant commentMaja Kądziołka-2/+2
2025-03-26Revert "Make `MatchPairTree::place` non-optional"Maja Kądziołka-2/+10
This reverts commit e3e74bc89a958e36c658fa809d98b4dd66d53cf8. The comment that was used to justify the change was outdated.
2025-03-21match lowering cleanup: `non_scalar_compare` is only for `&str`dianne-2/+2
Since array and slice constants are now lowered to array and slice patterns, `non_scalar_compare` was only called for string comparisons. This specializes it to strings, renames it, and removes the unused array-unsizing logic. This also updates some outdated doc comments.
2025-03-21Don't produce debug information for compiler-introduced-vars when desugaring ↵Kyle Huey-16/+42
assignments. An assignment such as (a, b) = (b, c); desugars to the HIR { let (lhs, lhs) = (b, c); a = lhs; b = lhs; }; The repeated `lhs` leads to multiple Locals assigned to the same DILocalVariable. Rather than attempting to fix that, get rid of the debug info for these bindings that don't even exist in the program to begin with. Fixes #138198
2025-03-16Build `UserTypeProjections` lazily when visiting bindingsZalathar-30/+36
2025-03-16Split `visit_primary_bindings` into two variantsZalathar-23/+42
The existing method does some non-obvious extra work to collect user types and build user-type projections, which is specifically needed by `declare_bindings` and not by the other two callers.
2025-03-16Simplify handling of `visibility_scope` in `declare_bindings`Zalathar-6/+4
This avoids the need to unwrap an option after ensuring that it is some.
2025-03-05Make `MatchPairTree::place` non-optionalZalathar-10/+2
As the invariant indicated, this place could only be none for `TestCase::Irrefutable` nodes, which no longer exist.
2025-03-05Remove the separate simplify step for match-pair treesZalathar-10/+13
What remained of this simplification process has been integrated into construction of the match-pair trees.
2025-03-05Remove `TestCase::Irrefutable`Zalathar-14/+3
2025-03-05Populate pattern bindings/ascriptions while building `MatchPairTree`Zalathar-5/+3
2025-03-05Make `MatchPairTree::for_pattern` push its output node to a vectorZalathar-1/+2
2025-02-21Rollup merge of #137305 - nnethercote:rustc_middle-2, r=lcnrMatthias Krüger-1/+1
Tweaks in and around `rustc_middle` A bunch of tiny improvements I found while working on bigger things. r? ```@lcnr```
2025-02-21Rename `ClearCrossCrate::assert_crate_local`.Nicholas Nethercote-1/+1
As `unwrap_crate_local`, because it follows exactly the standard form of an `unwrap` function.
2025-02-20Don't store a redundant span in user-type projectionsZalathar-2/+1
This span is already present in the corresponding `CanonicalUserTypeAnnotation`, and can be retrieved via the annotation's ID.
2025-02-20Avoid a useless clone of `UserTypeProjection`Zalathar-5/+2
2025-02-08Rustfmtbjorn3-45/+66
2025-02-03Slightly simplify the signature of `lower_match_arms`Zalathar-10/+8
This does mean that we have to resolve the list of arm IDs twice, but it's unclear whether that even matters, whereas the cleaner signature is a nice improvement.
2025-02-03Remove some non-trivial `box` patternsZalathar-12/+8
These particular patterns make it harder to experiment with alternate representations for THIR patterns and subpatterns.
2025-02-03Remove `'pat` lifetime from some match-lowering data structuresZalathar-59/+55
By storing `PatRange` in an Arc, and copying a few fields out of `Pat`, we can greatly simplify the lifetimes involved in match lowering.
2025-01-22modify commentShunpoco-1/+1
Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
2025-01-22address review: modify matches/mod.rsShunpoco-4/+9
The candidate shouldn't have false_edge_start_block if it has sub candidates. In remove_never_subcandidates(), the false_edge_start_block from the first sub candidte is assigned to a value and the value is later used if all sub candidates are removed and candidate doesn't have false_edge_start_block. In merge_trivial_subcandidates, I leave the if block which assign a false_edge_start_block into the candidate as before I put this commit since compile panics. Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
2025-01-12Fix ICE-133117Shunpoco-4/+4
If all subcandidates have never-pattern, we should assign false_edge_start_block to the parent candidate if it doesn't have. merge_trivial_subcandidates does so, but if the candidate has guard it returns before the assignment. Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
2025-01-12Fix ICE-133063Shunpoco-3/+5
If all subcandidates have never-pattern, the parent candidate should have otherwise_block because some methods expect the candidate has the block. Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
2024-12-18Re-export more `rustc_span::symbol` things from `rustc_span`.Nicholas Nethercote-2/+1
`rustc_span::symbol` defines some things that are re-exported from `rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some closely related things such as `Ident` and `kw`. So you can do `use rustc_span::{Symbol, sym}` but you have to do `use rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good reason. This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`, and changes many `rustc_span::symbol::` qualifiers in `compiler/` to `rustc_span::`. This is a 200+ net line of code reduction, mostly because many files with two `use rustc_span` items can be reduced to one.
2024-12-17Rename `rustc_mir_build::build` to `builder`Zalathar-0/+2813