about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
AgeCommit message (Collapse)AuthorLines
2025-06-29mir: Add a `new` method to `statement`dianqk-269/+235
Avoid introducing a large number of changes when adding optional initialization fields.
2025-06-28Auto merge of #142625 - cjgillot:inline-nocycle, r=oli-obkbors-128/+152
Only compute recursive callees once. Inlining MIR in a cyclic call graph may create query cycles, which are ICEs. The current implementation `mir_callgraph_reachable(inlining_candidate, being_optimized)` checks if calling `inlining_candidate` may cycle back to `being_optimized` that we are currently inlining into. This PR replaces this device with query `mir_callgraph_cyclic(being_optimized)` which searches the call graph for all cycles going back to `being_optimized`, and returns the set of functions involved in those cycles. This is a tradeoff: - in the current implementation, we perform more walks, but shallower; - in this new implementation, we perform fewer walks, but exhaust the graph. I'd have liked to compute this using some kind of SCC, but generic parameters make resolution path-dependent, so usual graph algorithms do not apply.
2025-06-28Auto merge of #141759 - 1c3t3a:discriminants-query, r=saethlinbors-0/+503
Insert checks for enum discriminants when debug assertions are enabled Similar to the existing null-pointer and alignment checks, this checks for valid enum discriminants on creation of enums through unsafe transmutes. Essentially this sanitizes patterns like the following: ```rust let val: MyEnum = unsafe { std::mem::transmute<u32, MyEnum>(42) }; ``` An extension of this check will be done in a follow-up that explicitly sanitizes for extern enum values that come into Rust from e.g. C/C++. This check is similar to Miri's capabilities of checking for valid construction of enum values. This PR is inspired by saethlin@'s PR https://github.com/rust-lang/rust/pull/104862. Thank you so much for keeping this code up and the detailed comments! I also pair-programmed large parts of this together with vabr-g@. r? `@saethlin`
2025-06-27Rollup merge of #143046 - RalfJung:zst-unsafe-cell, r=lcnr,oli-obkMatthias Krüger-1/+1
const validation: properly ignore zero-sized UnsafeCell Fixes https://github.com/rust-lang/rust/issues/142948 r? `@oli-obk`
2025-06-27Add InterpCx::layout_of with tracing, shadowing LayoutOfStypox-3/+1
2025-06-27Insert checks for enum discriminants when debug assertions are enabledBastian Kersting-0/+503
Similar to the existing nullpointer and alignment checks, this checks for valid enum discriminants on creation of enums through unsafe transmutes. Essentially this sanitizes patterns like the following: ```rust let val: MyEnum = unsafe { std::mem::transmute<u32, MyEnum>(42) }; ``` An extension of this check will be done in a follow-up that explicitly sanitizes for extern enum values that come into Rust from e.g. C/C++. This check is similar to Miri's capabilities of checking for valid construction of enum values. This PR is inspired by saethlin@'s PR https://github.com/rust-lang/rust/pull/104862. Thank you so much for keeping this code up and the detailed comments! I also pair-programmed large parts of this together with vabr-g@.
2025-06-26make size_and_align_of_mplace work on all projectableRalf Jung-1/+1
2025-06-25Rollup merge of #142724 - xizheyin:avoid_overwrite_args, r=oli-obkJana Dönszelmann-0/+4
Add runtime check to avoid overwrite arg in `Diag` ## Origin PR description At first, I set up a `debug_assert` check for the arg method to make sure that `args` in `Diag` aren't easily overwritten, and I added the `remove_arg()` method, so that if you do need to overwrite an arg, then you can explicitly call `remove_arg()` to remove it first, then call `arg()` to overwrite it. For the code before the rust-lang/rust#142015 change, it won't compile because it will report an error ``` arg `instance`already exists. ``` This PR also modifies all diagnostics that fail the check to pass the check. There are two cases of check failure: 1. ~~Between *the parent diagnostic and the subdiagnostic*, or *between the subdiagnostics* have the same field between them. In this case, I renamed the conflicting fields.~~ 2. ~~For subdiagnostics stored in `Vec`, the rendering may iteratively write the same arg over and over again. In this case, I changed the auto-generation with `derive(SubDiagnostic)` to manually implementing `SubDiagnostic` and manually rendered it with `eagerly_translate()`, similar to https://github.com/rust-lang/rust/issues/142031#issuecomment-2984812090, and after rendering it I manually deleted useless arg with the newly added `remove_arg` method.~~ ## Final Decision After trying and discussing, we made a final decision. For `#[derive(Subdiagnostic)]`, This PR made two changes: 1. After the subdiagnostic is rendered, remove all args of this subdiagnostic, which allows for usage like `Vec<Subdiag>`. 2. Store `diag.args` before setting arguments, so that you can restore the contents of the main diagnostic after deleting the arguments after subdiagnostic is rendered, to avoid deleting the main diagnostic's arg when they have the same name args.
2025-06-25Add runtime check to avoid overwrite arg easily in diag and store and ↵xizheyin-0/+4
restore snapshot when set subdiag arg Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
2025-06-23Only store the LocalDefId instead of the whole instance.Camille GILLOT-5/+10
2025-06-22Only compute recursive callees once.Camille GILLOT-128/+147
2025-06-22Leave from CopyProp early when there are no replacementsTomasz Miąsko-8/+10
2025-06-22Auto merge of #142675 - tmiasko:preserve-cache, r=oli-obkbors-1/+1
Preserve caches in a call to shrink_to_fit A small follow up to rust-lang/rust#142542.
2025-06-21Auto merge of #142546 - cjgillot:reachable-jump, r=compiler-errorsbors-1/+1
Only traverse reachable blocks in JumpThreading. Fixes https://github.com/rust-lang/rust/issues/131451 We only compute loop headers for reachable blocks. We shouldn't try to perform an opt on unreachable blocks anyway.
2025-06-20Rollup merge of #142571 - cjgillot:borrowed-classes, r=oli-obkTrevor Gross-27/+30
Reason about borrowed classes in CopyProp. Fixes https://github.com/rust-lang/rust/issues/141122 The current implementation of `CopyProp` avoids unifying two borrowed locals, as this would change the result of address comparison. However, the implementation was inconsistent with the general algorithm, which identifies equivalence classes of locals and then replaces all locals by a single representative of their equivalence class. This PR fixes it by forbidding the unification of two *classes* if any of those contain a borrowed local.
2025-06-18Rollup merge of #135656 - joshtriplett:hint-mostly-unused, r=saethlinUrgau-0/+7
Add `-Z hint-mostly-unused` to tell rustc that most of a crate will go unused This hint allows the compiler to optimize its operation based on this assumption, in order to compile faster. This is a hint, and does not guarantee any particular behavior. This option can substantially speed up compilation if applied to a large dependency where the majority of the dependency does not get used. This flag may slow down compilation in other cases. Currently, this option makes the compiler defer as much code generation as possible from functions in the crate, until later crates invoke those functions. Functions that never get invoked will never have code generated for them. For instance, if a crate provides thousands of functions, but only a few of them will get called, this flag will result in the compiler only doing code generation for the called functions. (This uses the same mechanisms as cross-crate inlining of functions.) This does not affect `extern` functions, or functions marked as `#[inline(never)]`. This option has already existed in nightly as `-Zcross-crate-inline-threshold=always` for some time, and has gotten testing in that form. However, this option is still unstable, to give an opportunity for wider testing in this form. Some performance numbers, based on a crate with many dependencies having just *one* large dependency set to `-Z hint-mostly-unused` (using Cargo's `profile-rustflags` option): A release build went from 4m07s to 2m04s. A non-release build went from 2m26s to 1m28s.
2025-06-18Preserve caches in a call to shrink_to_fitTomasz Miąsko-1/+1
2025-06-17Rollup merge of #142542 - cjgillot:invalidate-simplify-cfg, r=SparrowLiiJubilee-3/+16
Manually invalidate caches in SimplifyCfg. The current `SimplifyCfg` pass unconditionally invalidates CFG caches. This is unfortunate if there are no modifications that require this invalidation.
2025-06-16Reason about borrowed classes in CopyProp.Camille GILLOT-27/+30
2025-06-16Add comment.Camille GILLOT-0/+3
2025-06-15Rollup merge of #142347 - azhogin:azhogin/async-drop-storage-live-dead-fix, ↵León Orell Valerian Liehr-5/+30
r=oli-obk Async drop - fix for StorageLive/StorageDead codegen for pinned future Fixes: rust-lang/rust#140429, Fixes: rust-lang/rust#140531, Fixes: rust-lang/rust#141761, Fixes: rust-lang/rust#141409. StorageLive/StorageDead codegen is corrected for pinned async drop future.
2025-06-15Only traverse reachable blocks in JumpThreading.Camille GILLOT-1/+1
2025-06-15Manually invalidate caches in SimplifyCfg.Camille GILLOT-3/+13
2025-06-14Rollup merge of #141811 - mejrs:bye_locals, r=compiler-errorsMatthias Krüger-12/+3
Unimplement unsized_locals Implements https://github.com/rust-lang/compiler-team/issues/630 Tracking issue here: https://github.com/rust-lang/rust/issues/111942 Note that this just removes the feature, not the implementation, and does not touch `unsized_fn_params`. This is because it is required to support `Box<dyn FnOnce()>: FnOnce()`. There may be more that should be removed (possibly in follow up prs) - the `forget_unsized` function and `forget` intrinsic. - the `unsized_locals` test directory; I've just fixed up the tests for now - various codegen support for unsized values and allocas cc ``@JakobDegen`` ``@oli-obk`` ``@Noratrieb`` ``@programmerjake`` ``@bjorn3`` ``@rustbot`` label F-unsized_locals Fixes rust-lang/rust#79409
2025-06-14Async drop - fix for StorageLive/StorageDead codegen for pinned async drop ↵Andrew Zhogin-5/+30
future
2025-06-13Unimplement unsized_localsmejrs-12/+3
2025-06-12intrinsics: rename min_align_of to align_ofRalf Jung-2/+2
2025-06-11Auto merge of #141763 - lcnr:fixme-gamer, r=BoxyUwUbors-1/+1
`FIXME(-Znext-solver)` triage r? `@BoxyUwU`
2025-06-10Auto merge of #142299 - fmease:rollup-u86s80a, r=fmeasebors-29/+19
Rollup of 16 pull requests Successful merges: - rust-lang/rust#134442 (Specify the behavior of `file!`) - rust-lang/rust#140372 (Exhaustively handle parsed attributes in CheckAttr) - rust-lang/rust#140766 (Stabilize keylocker) - rust-lang/rust#141642 (Note the version and PR of removed features when using it) - rust-lang/rust#141818 (Don't create .msi installer for gnullvm hosts) - rust-lang/rust#141909 (Add central execution context to bootstrap) - rust-lang/rust#141992 (use `#[naked]` for `__rust_probestack`) - rust-lang/rust#142101 (core::ptr: deduplicate more method docs) - rust-lang/rust#142102 (docs: Small clarification on the usage of read_to_string and read_to_end trait methods) - rust-lang/rust#142124 (Allow transmute casts in pre-runtime-MIR) - rust-lang/rust#142240 (deduplicate the rest of AST walker functions) - rust-lang/rust#142258 (platform-support.md: Mention specific Linux kernel version or later) - rust-lang/rust#142262 (Mark `core::slice::memchr` as `#[doc(hidden)]`) - rust-lang/rust#142271 (compiler: fn ptrs should hit different lints based on ABI) - rust-lang/rust#142275 (rustdoc: Refractor `clean_ty_generics`) - rust-lang/rust#142288 (const_eval: fix some outdated comments) r? `@ghost` `@rustbot` modify labels: rollup
2025-06-10Rollup merge of #142124 - oli-obk:transmute-cast, r=scottmcmLeón Orell Valerian Liehr-29/+19
Allow transmute casts in pre-runtime-MIR r? ``@scottmcm`` cc ``@BoxyUwU`` turns out in https://github.com/rust-lang/rust/pull/138393 I erroneously used transmute casts in https://github.com/rust-lang/rust/blob/fd3da4bebdff63b7529483ff7025986ef16bf463/compiler/rustc_mir_build/src/builder/matches/test.rs#L209 I don't think they have any issues using them before runtime, we just checked for them because we didn't have code exercising those code paths
2025-06-10Auto merge of #141485 - dianqk:early_otherwise_branch_loop, r=oli-obkbors-29/+3
mir-opt: Do not create storage marks in EarlyOtherwiseBranch Fixes #141212. The first commit add `StorageDead` by creating new indirect BB that makes CFG more complicated, but I think it's better to just not create storage marks. r? mir-opt
2025-06-08Remove all unused feature gates from the compilerbjorn3-3/+0
2025-06-06Add `-Z hint-mostly-unused` to tell rustc that most of a crate will go unusedJosh Triplett-0/+7
This hint allows the compiler to optimize its operation based on this assumption, in order to compile faster. This is a hint, and does not guarantee any particular behavior. This option can substantially speed up compilation if applied to a large dependency where the majority of the dependency does not get used. This flag may slow down compilation in other cases. Currently, this option makes the compiler defer as much code generation as possible from functions in the crate, until later crates invoke those functions. Functions that never get invoked will never have code generated for them. For instance, if a crate provides thousands of functions, but only a few of them will get called, this flag will result in the compiler only doing code generation for the called functions. (This uses the same mechanisms as cross-crate inlining of functions.) This does not affect `extern` functions, or functions marked as `#[inline(never)]`. Some performance numbers, based on a crate with many dependencies having just *one* large dependency set to `-Z hint-mostly-unused` (using Cargo's `profile-rustflags` option): A release build went from 4m07s to 2m04s. A non-release build went from 2m26s to 1m28s.
2025-06-06Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obkGuillaume Gomez-7/+10
Update `InterpCx::project_field` to take `FieldIdx` As suggested by Ralf in https://github.com/rust-lang/rust/pull/142005#discussion_r2125839015
2025-06-06Allow transmute casts in pre-runtime-MIROli Scherer-29/+19
2025-06-05Update `InterpCx::project_field` to take `FieldIdx`Scott McMurray-7/+10
As suggested by Ralf in 142005.
2025-06-05Replace some `Option<Span>` with `Span` and use DUMMY_SP instead of NoneOli Scherer-49/+50
2025-06-04Rollup merge of #141932 - azhogin:azhogin/async-drop-inside-asyncgen-fix, ↵Matthias Krüger-6/+28
r=oli-obk Fix for async drop inside async gen fn Return value (for yield) is corrected for async drop inside async gen function. In CFG, when internal async drop future is polled and returned `Poll<()>::Pending`, then async gen resume function returns `Poll<(OptRet)>::Pending`. Fixes rust-lang/rust#140530
2025-06-04Fix for async drop inside async gen fnAndrew Zhogin-6/+28
2025-06-03`FIXME(-Znext-solver)` triagelcnr-1/+1
Co-authored-by: Michael Goulet <michael@errs.io>
2025-06-03Rollup merge of #141677 - ↵Matthias Krüger-2/+14
azhogin:azhogin/async-drop-unexpected-type-instead-of-drop-fn-fix, r=oli-obk Async drop - type instead of async drop fn, fixes #140484 Fixes: rust-lang/rust#140484 Fixes: rust-lang/rust#140500 Fixes ICE, when type is provided in AsyncDrop trait instead of `async fn drop()`. Fixes ICE, when async drop fn has wrong signature.
2025-06-01Async drop - type instead of async drop fn and incorrect drop signature ↵Andrew Zhogin-2/+14
don't ICE now
2025-05-31Auto merge of #139118 - scottmcm:slice-get-unchecked-intrinsic, r=workingjubileebors-0/+46
`slice.get(i)` should use a slice projection in MIR, like `slice[i]` does `slice[i]` is built-in magic, so ends up being quite different from `slice.get(i)` in MIR, even though they're both doing nearly identical operations -- checking the length of the slice then getting a ref/ptr to the element if it's in-bounds. This PR adds a `slice_get_unchecked` intrinsic for `impl SliceIndex for usize` to use to fix that, so it no longer needs to do a bunch of lines of pointer math and instead just gets the obvious single statement. (This is *not* used for the range versions, since `slice[i..]` and `slice[..k]` can't use the mir Slice projection as they're using fenceposts, not indices.) I originally tried to do this with some kind of GVN pattern, but realized that I'm pretty sure it's not legal to optimize `BinOp::Offset` to `PlaceElem::Index` without an extremely complicated condition. Basically, the problem is that the `Index` projection on a dereferenced slice pointer *cares about the metadata*, since it's UB to `PlaceElem::Index` outside the range described by the metadata. But then you cast the fat pointer to a thin pointer then offset it, that *ignores* the slice length metadata, so it's possible to write things that are legal with `Offset` but would be UB if translated in the obvious way to `Index`. Checking (or even determining) the necessary conditions for that would be complicated and error-prone, whereas this intrinsic-based approach is quite straight-forward. Zero backend changes, because it just lowers to MIR, so it's already supported naturally by CTFE/Miri/cg_llvm/cg_clif.
2025-05-30Rollup merge of #141494 - dianqk:match-br-non-int, r=wesleywiserJubilee-2/+4
mir-opt: Do not transform non-int type in match_branches Fixes #141378. r? mir-opt
2025-05-30`slice.get(i)` should use a slice projection in MIR, like `slice[i]` doesScott McMurray-0/+46
2025-05-27Rollup merge of #141551 - compiler-errors:hir-lints, r=BoxyUwUTrevor Gross-244/+0
Make two transmute-related MIR lints into HIR lint Make `PTR_TO_INTEGER_TRANSMUTE_IN_CONSTS` (rust-lang/rust#130540) and `UNNECESSARY_TRANSMUTES` (rust-lang/rust#136083) into "normal" HIR-based lints. Funny enough this came up in the review of the latter (https://github.com/rust-lang/rust/pull/136083#issuecomment-2614301413), but I guess it just was overlooked. But anywyas, there's no reason for these to be MIR lints; in fact, it makes the suggestions for them a bit more complicated than necessary. Note that there's probably a few more simplifications and improvements to be done here. Follow-ups can be done in a separate PR, especially if they're about the messaging and suggestions themselves, which I didn't write.
2025-05-27Rollup merge of #141252 - dianqk:gvn-repeat-index, r=saethlinTrevor Gross-1/+7
gvn: bail out unavoidable non-ssa locals in repeat Fixes #141251. We cannot transform `*elem` to `array[idx1]` in the following code, as `idx1` has already been modified. ```rust mir! { let array; let elem; { array = [*val; 5]; elem = &array[idx1]; idx1 = idx2; RET = *elem; Return() } } ``` Perhaps I could transform it to `array[0]`, but I prefer the conservative approach. r? mir-opt
2025-05-27coverage: Revert "unused local file IDs" due to empty function namesZalathar-36/+2
This reverts commit 3b22c21dd8c30f499051fe7a758ca0e5d81eb638, reversing changes made to 5f292eea6d63abbd26f1e6e00a0b8cf21d828d7d.
2025-05-27Rollup merge of #141513 - nia-e:allocbytes-extend, r=RalfJung许杰友 Jieyou Xu (Joe)-0/+1
interpret: add allocation parameters to `AllocBytes` Necessary for a better implementation of [rust-lang/miri#4343](https://github.com/rust-lang/miri/pull/4343). Also included here is the code from that PR, adapted to this new interface for the sake of example and so that CI can run on them; the Miri changes can be reverted and merged separately, though. r? `@RalfJung`
2025-05-27Rollup merge of #141431 - compiler-errors:open-drop, r=oli-obk许杰友 Jieyou Xu (Joe)-0/+17
Emit dummy open drop for unsafe binder Fixes rust-lang/rust#141394 We can't taint the body in wfcheck when we have a `T: Copy` bound failure, so we end up binding MIR here. Emit a dummy open drop so that drop elaboration doesn't fail. r? oli-obk