about summary refs log tree commit diff
path: root/compiler/rustc_mir_build/src/builder
AgeCommit message (Collapse)AuthorLines
2025-10-02Auto merge of #147055 - beepster4096:subtype_is_not_a_projection, r=lcnrbors-2/+1
Turn ProjectionElem::Subtype into CastKind::Subtype I noticed that drop elaboration can't, in general, handle `ProjectionElem::SubType`. It creates a disjoint move path that overlaps with other move paths. (`Subslice` does too, and I'm working on a different PR to make that special case less fragile.) If its skipped and treated as the same move path as its parent then `MovePath.place` has multiple possible projections. (It would probably make sense to remove all `Subtype` projections for the canonical place but it doesn't make sense to have this special case for a problem that doesn't actually occur in real MIR.) The only reason this doesn't break is that `Subtype` is always the sole projection of the local its applied to. For the same reason, it works fine as a `CastKind` so I figured that makes more sense than documenting and validating this hidden invariant. cc rust-lang/rust#112651, rust-lang/rust#133258 r? Icnr (bc you've been the main person dealing with `Subtype` it looks like)
2025-09-26fix doc comments to be more standardMarijn Schouten-5/+1
2025-09-26ProjectionElem::Subtype -> CastKind::Subtypebeepster4096-2/+1
2025-09-25mark THIR use as candidate for constness checkDing Xiang Fei-1/+4
2025-09-25do not materialise X in [X; 0] when X is unsizing a constDing Xiang Fei-1/+20
2025-09-16Remove Rvalue::Len.Camille Gillot-3/+8
2025-09-01Auto merge of #144783 - folkertdev:loop-match-diverging-loop, r=SparrowLiibors-4/+6
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-09-01Introduce `MirDumper` and `MirWriter`.Nicholas Nethercote-14/+4
MIR dumping is a mess. There are lots of functions and entry points, e.g. `dump_mir`, `dump_mir_with_options`, `dump_polonius_mir`, `dump_mir_to_writer`. Also, it's crucial that `create_dump_file` is never called without `dump_enabled` first being checked, but there is no mechanism for ensuring this and it's hard to tell if it is satisfied on all paths. (`dump_enabled` is checked twice on some paths, however!) This commit introduces `MirWriter`, which controls the MIR writing, and encapsulates the `extra_data` closure and `options`. Two existing functions are now methods of this type. It sets reasonable defaults, allowing the removal of many `|_, _| Ok(())` closures. The commit also introduces `MirDumper`, which is layered on top of `MirWriter`, and which manages the creation of the dump files, encapsulating pass names, disambiguators, etc. Four existing functions are now methods of this type. - `MirDumper::new` will only succeed if dumps are enabled, and will return `None` otherwise, which makes it impossible to dump when you shouldn't. - It also sets reasonable defaults for various things like disambiguators, which means you no longer need to specify them in many cases. When they do need to be specified, it's now done via setter methods. - It avoids some repetition. E.g. `dump_nll_mir` previously specifed the pass name `"nll"` four times and the disambiguator `&0` three times; now it specifies them just once, to put them in the `MirDumper`. - For Polonius, the `extra_data` closure can now be specified earlier, which avoids having to pass some arguments through some functions.
2025-09-01Avoid unnecessary `mut`-ness for various closures.Nicholas Nethercote-1/+1
2025-08-21Rollup merge of #144780 - bjorn3:mir_build_debug, r=matthewjasperJacob Pratt-0/+37
Add a method to dump MIR in the middle of MIR building This makes it easier to debug issues with MIR building by inserting dump_for_debugging calls around the suspected code responsible for the bad MIR.
2025-08-18Rollup merge of #145206 - scrabsha:push-uxovoqzrxnlx, r=jdonszelmannStuart Cook-37/+37
Port `#[custom_mir(..)]` to the new attribute system r? ``````````@jdonszelmann``````````
2025-08-15Port `#[custom_mir(..)]` to the new attribute systemSasha Pourcelot-37/+37
2025-08-14Apply suggestions from code reviewRalf Jung-3/+3
Co-authored-by: Boxy <rust@boxyuwu.dev>
2025-08-14avoid unnecessary type sanity checksRalf Jung-2/+2
2025-08-14shrink TestBranch::Constant and PatRangeBoundary::FiniteRalf Jung-6/+8
2025-08-14use ty::Value instead of manual pairs of types and valtreesRalf Jung-26/+20
2025-08-14pattern testing: store constants as valtreesRalf Jung-47/+43
2025-08-14PatKind: store constants as valtreesRalf Jung-5/+9
2025-08-13Also dump coverage infobjorn3-2/+17
2025-08-13Add a method to dump MIR in the middle of MIR buildingbjorn3-0/+22
This makes it easier to debug issues with MIR building by inserting dump_for_debugging calls around the suspected code responsible for the bad MIR.
2025-08-10add place mention for `#[loop_match]` scrutineeFolkert de Vries-3/+5
2025-08-09Auto merge of #143376 - dianne:guard-scope, r=matthewjasperbors-45/+72
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-359/+7
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/+20
2025-08-07add a scope for `if let` guard temporaries and bindingsdianne-45/+56
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-43/+118
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-55/+9
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-15/+95
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-359/+7
2025-08-04fix `#[loop_match]` on diverging loopFolkert de Vries-1/+1
this generated invalid MIR before
2025-08-02Rollup merge of #144478 - joshtriplett:doc-code-formatting-prep, r=AmanieuSamuel Tardieu-1/+3
Improve formatting of doc code blocks We don't currently apply automatic formatting to doc comment code blocks. As a result, it has built up various idiosyncracies, which make such automatic formatting difficult. Some of those idiosyncracies also make things harder for human readers or other tools. This PR makes a few improvements to doc code formatting, in the hopes of making future automatic formatting easier, as well as in many cases providing net readability improvements. I would suggest reading each commit separately, as each commit contains one class of changes.
2025-07-26Rollup merge of #143585 - folkertdev:loop-match-suggest-const-block, r=oli-obkTrevor Gross-3/+26
`loop_match`: suggest extracting to a `const` item tracking issue: https://github.com/rust-lang/rust/issues/132306 fixes https://github.com/rust-lang/rust/issues/143310 fixes https://github.com/rust-lang/rust/issues/143936
2025-07-25Improve and regularize comment placement in doc codeJosh Triplett-1/+3
Because doc code does not get automatically formatted, some doc code has creative placements of comments that automatic formatting can't handle. Reformat those comments to make the resulting code support standard Rust formatting without breaking; this is generally an improvement to readability as well. Some comments are not indented to the prevailing indent, and are instead aligned under some bit of code. Indent them to the prevailing indent, and put spaces *inside* the comments to align them with code. Some comments span several lines of code (which aren't the line the comment is about) and expect alignment. Reformat them into one comment not broken up by unrelated intervening code. Some comments are placed on the same line as an opening brace, placing them effectively inside the subsequent block, such that formatting would typically format them like a line of that block. Move those comments to attach them to what they apply to. Some comments are placed on the same line as a one-line braced block, effectively attaching them to the closing brace, even though they're about the code inside the block. Reformat to make sure the comment will stay on the same line as the code it's commenting.
2025-07-26`loop_match`: suggest extracting to a `const` itemFolkert de Vries-3/+26
if the expression cannot be evaluated in a straightforward way
2025-07-24Auto merge of #144389 - scottmcm:no-more-mir-cast-assume, r=davidtwcobors-78/+2
MIR-build: No longer emit assumes in enum-as casting This just uses the `valid_range` from the backend, so it's duplicating the range metadata that now we include on parameters and loads, and thus no longer seems to be useful -- notably there's no codegen test failures from removing it. (Because it's using data from the same source as the backend annotations, it doesn't do anything to mitigate things like rust-lang/rust#144388 where the range in the layout is more permissive than the actual possible discriminants. A variant of this that actually checked the discriminants more specifically might be useful, so could potentially be added in future, but I don't think the *current* checks are actually providing value.) r? mir Randomly turns out that this Fixes https://github.com/rust-lang/rust/issues/121097
2025-07-24MIR-build: No longer emit assumes in enum-as castingScott McMurray-78/+2
This just uses the `valid_range` from the backend, so it's duplicating the range metadata that now we include on parameters and loads.
2025-07-23Remove useless lifetime parameter.Camille GILLOT-22/+4
2025-07-23Give an AllocId to ConstValue::Slice.Camille GILLOT-13/+28
2025-07-09Auto merge of #143472 - dianne:deref-pat-column-check, r=Nadrierilbors-0/+1
`rustc_pattern_analysis`: always check that deref patterns don't match on the same place as normal constructors In rust-lang/rust#140106, deref pattern validation was tied to the `deref_patterns` feature to temporarily avoid affecting perf. However: - As of rust-lang/rust#143414, box patterns are represented as deref patterns in `rustc_pattern_analysis`. Since they can be used by enabling `box_patterns` instead of `deref_patterns`, it was possible for them to skip validation, resulting in an ICE. This fixes that and adds a regression test. - External tooling (e.g. rust-analyzer) will also need to validate matches containing deref patterns, which was not possible. This fixes that by making `compute_match_usefulness` validate deref patterns by default. In order to avoid doing an extra pass for anything with patterns, the second commit makes `RustcPatCtxt` keep track of whether it encounters a deref pattern, so that it only does the check if so. This is purely for performance. If the perf impact of the first commit is negligible and the complexity cost introduced by the second commit is significant, it may be worth dropping the latter. r? `@Nadrieril`
2025-07-07`loop_match`: fix 'no terminator on block'Folkert de Vries-1/+3
2025-07-05Remove yields_in_scope from the scope tree.Camille GILLOT-3/+0
2025-07-04only check for mixed deref/normal constructors when neededdianne-0/+1
2025-07-01loop match: handle opaque patternsFolkert de Vries-2/+4
fixes issue 143203
2025-07-01loop match: run exhaustiveness checkFolkert de Vries-4/+8
2025-07-01Auto merge of #141875 - nnethercote:ByteSymbol, r=petrochenkovbors-11/+12
Introduce `ByteSymbol` It's like `Symbol` but for byte strings. The interner is now used for both `Symbol` and `ByteSymbol`. E.g. if you intern `"dog"` and `b"dog"` you'll get a `Symbol` and a `ByteSymbol` with the same index and the characters will only be stored once. The motivation for this is to eliminate the `Arc`s in `ast::LitKind`, to make `ast::LitKind` impl `Copy`, and to avoid the need to arena-allocate `ast::LitKind` in HIR. The latter change reduces peak memory by a non-trivial amount on literal-heavy benchmarks such as `deep-vector` and `tuple-stress`. `Encoder`, `Decoder`, `SpanEncoder`, and `SpanDecoder` all get some changes so that they can handle normal strings and byte strings.
2025-06-30Introduce `ByteSymbol`.Nicholas Nethercote-11/+12
It's like `Symbol` but for byte strings. The interner is now used for both `Symbol` and `ByteSymbol`. E.g. if you intern `"dog"` and `b"dog"` you'll get a `Symbol` and a `ByteSymbol` with the same index and the characters will only be stored once. The motivation for this is to eliminate the `Arc`s in `ast::LitKind`, to make `ast::LitKind` impl `Copy`, and to avoid the need to arena-allocate `ast::LitKind` in HIR. The latter change reduces peak memory by a non-trivial amount on literal-heavy benchmarks such as `deep-vector` and `tuple-stress`. `Encoder`, `Decoder`, `SpanEncoder`, and `SpanDecoder` all get some changes so that they can handle normal strings and byte strings. This change does slow down compilation of programs that use `include_bytes!` on large files, because the contents of those files are now interned (hashed). This makes `include_bytes!` more similar to `include_str!`, though `include_bytes!` contents still aren't escaped, and hashing is still much cheaper than escaping.
2025-06-29mir: Add a `new` method to `statement`dianqk-55/+50
Avoid introducing a large number of changes when adding optional initialization fields.
2025-06-25emit `StorageLive` and schedule `StorageDead` for `let`-`else` after matchingdianne-55/+9