Skip to content

Rollup of 18 pull requests#152825

Merged
rust-bors[bot] merged 135 commits intorust-lang:mainfrom
JonathanBrouwer:rollup-0YvwE70
Feb 19, 2026
Merged

Rollup of 18 pull requests#152825
rust-bors[bot] merged 135 commits intorust-lang:mainfrom
JonathanBrouwer:rollup-0YvwE70

Conversation

@JonathanBrouwer
Copy link
Contributor

Successful merges:

r? @ghost

Create a similar rollup

BoxyUwU and others added 30 commits December 23, 2025 13:54
MGCA: Support struct expressions without intermediary anon consts

r? oli-obk

tracking issue: rust-lang#132980

Fixes rust-lang#127972
Fixes rust-lang#137888
Fixes rust-lang#140275

due to delaying a bug instead of ICEing in HIR ty lowering.

### High level goal

Under `feature(min_generic_const_args)` this PR adds another kind of const argument. A struct/variant construction const arg kind. We represent the values of the fields as themselves being const arguments which allows for uses of generic parameters subject to the existing restrictions present in `min_generic_const_args`:
```rust
fn foo<const N: Option<u32>>() {}

trait Trait {
    #[type_const]
    const ASSOC: usize;
}

fn bar<T: Trait, const N: u32>() {
    // the initializer of `_0` is a `N` which is a legal const argument
    // so this is ok.
    foo::<{ Some::<u32> { 0: N } }>();

    // this is allowed as mgca supports uses of assoc consts in the
    // type system. ie `<T as Trait>::ASSOC` is a legal const argument
    foo::<{ Some::<u32> { 0: <T as Trait>::ASSOC } }>();

    // this on the other hand is not allowed as `N + 1` is not a legal
    // const argument
    foo::<{ Some::<u32> { 0: N + 1 } }>();
}
```

This PR does not support uses of const ctors, e.g. `None`. And also does not support tuple constructors, e.g. `Some(N)`. I believe that it would not be difficult to add support for such functionality after this PR lands so have left it out deliberately.

We currently require that all generic parameters on the type being constructed be explicitly specified. I haven't really looked into why that is but it doesn't seem desirable to me as it should be legal to write `Some { ... }` in a const argument inside of a body and have that desugar to `Some::<_> { ... }`. Regardless this can definitely be a follow-up PR and I assume this is some underlying consistency with the way that elided args are handled with type paths elsewhere.

This PRs implementation of supporting struct expressions is somewhat incomplete. We don't handle `Foo { ..expr }` at all and aren't handling privacy/stability. The printing of `ConstArgKind::Struct` HIR nodes doesn't really exist either :')

I've tried to keep the implementation here somewhat deliberately incomplete as I think a number of these issues are actually quite small and self contained after this PR lands and I'm hoping it could be a good set of issues to mentor newer contributors on 🤔 I just wanted the "bare minimum" required to actually demonstrate that the previous changes are "necessary".

### `ValTree` now recurse through `ty::Const`

In order to actually represent struct/variant construction in `ty::Const` without going through an anon const we would need to introduce some new `ConstKind` variant. Let's say some hypothetical `ConstKind::ADT(Ty<'tcx>, List<Const<'tcx>>)`.

This variant would represent things the same way that `ValTree` does with the first element representing the `VariantIdx` of the enum (if its an enum), and then followed by a list of field values in definition order.

This *could* work but there are a few reasons why it's suboptimal.

First it would mean we have a second kind of `Const` that can be normalized. Right now we only have `ConstKind::Unevaluated` which possibly needs normalization. Similarly with `TyKind` we *only* have `TyKind::Alias`. If we introduced `ConstKind::ADT` it would need to be normalized to a `ConstKind::Value` eventually. This feels to me like it has the potential to cause bugs in the long run where only `ConstKind::Unevaluated` is handled by some code paths.

Secondly it would make type equality/inference be kind of... weird... It's desirable for `Some { 0: ?x } eq Some { 0: 1_u32 }` to result in `?x=1_u32`.  I can't see a way for this to work with this `ConstKind::ADT` design under the current architecture for how we represent types/consts and generally do equality operations.

We would need to wholly special case these two variants in type equality and have a custom recursive walker separate from the existing architecture for doing type equality. It would also be somewhat unique in that it's a non-rigid `ty::Const` (it can be normalized more later on in type inference) while also having somewhat "structural" equality behaviour.

Lastly, it's worth noting that its not *actually* `ConstKind::ADT` that we want. It's desirable to extend this setup to also support tuples and arrays, or even references if we wind up supporting those in const generics. Therefore this isn't really `ConstKind::ADT` but a more general `ConstKind::ShallowValue` or something to that effect. It represents at least one "layer" of a types value :')

Instead of doing this implementation choice we instead change `ValTree::Branch`:
```rust
enum ValTree<'tcx> {
    Leaf(ScalarInt),
    // Before this PR:
    Branch(Box<[ValTree<'tcx>]>),
    // After this PR
    Branch(Box<[Const<'tcx>]>),
}
```

The representation for so called "shallow values" is now the same as the representation for the *entire* full value. The desired inference/type equality behaviour just falls right out of this. We also don't wind up with these shallow values actually being non-rigid. And `ValTree` *already* supports references/tuples/arrays so we can handle those just fine.

I think in the future it might be worth considering inlining `ValTree` into `ty::ConstKind`. E.g:
```rust
enum ConstKind {
    Scalar(Ty<'tcx>, ScalarInt),
    ShallowValue(Ty<'tcx>, List<Const<'tcx>>),
    Unevaluated(UnevaluatedConst<'tcx>),
    ...
}
```

This would imply that the usage of `ValTree`s in patterns would now be using `ty::Const` but they already kind of are anyway and I think that's probably okay in the long run. It also would mean that the set of things we *could* represent in const patterns is greater which may be desirable in the long run for supporting things such as const patterns of const generic parameters.

Regardless, this PR doesn't actually inline `ValTree` into `ty::ConstKind`, it only changes `Branch` to recurse through `Const`. This change could be split out of this PR if desired.

I'm not sure if there'll be a perf impact from this change. It's somewhat plausible as now all const pattern values that have nesting will be interning a lot more `Ty`s. We shall see :>

### Forbidding generic parameters under mgca

Under mgca we now allow all const arguments to resolve paths to generic parameters. We then *later* actually validate that the const arg should be allowed to access generic parameters if it did wind up resolving to any.

This winds up just being a lot simpler to implement than trying to make name resolution "keep track" of whether we're inside of a non-anon-const const arg and then encounter a `const { ... }` indicating we should now stop allowing resolving to generic parameters.

It's also somewhat in line with what we'll need for a `feature(generic_const_args)` where we'll want to decide whether an anon const should have any generic parameters based off syntactically whether any generic parameters were used. Though that design is entirely hypothetical at this point :)

### Followup Work

- Make HIR ty lowering check whether lowering generic parameters is supported and if not lower to an error type/const. Should make the code cleaner, fix some other bugs, and maybe(?) recover perf since we'll be accessing less queries which I think is part of the perf regression of this PR
- Make the ValTree setup less scuffed. We should find a new name for `ConstKind::Value` and the `Val` part of `ValTree` and `ty::Value` as they no longer correspond to a fully normalized structure. It may also be worth looking into inlining `ValTreeKind` into `ConstKind` or atleast into `ty::Value` or sth 🤔
- Support tuple constructors and const constructors not just struct expressions.
- Reduce code duplication between HIR ty lowering's handling of struct expressions, and HIR typeck's handling of struct expressions
- Try fix perf rust-lang#149114 (comment). Maybe this will clear up once we clean up `ValTree` a bit and stop doing double interning and whatnot
For some reason git-subtree incorrectly synced those changes.
The next Cranelift release will support for CallConv::Cold as it was
already effectively equivalent to the default calling convention.
This saves about 10MB on the dist size and about 240MB on the build dir
size.
…e_diagnostic` throughout the codebase

This PR was mostly made by search&replacing
…fJung

`c_variadic`: impl `va_copy` and `va_end` as Rust intrinsics

tracking issue: rust-lang#44930

Implement `va_copy` as (the rust equivalent of) `memcpy`, which is the behavior of all current LLVM targets. By providing our own implementation, we can guarantee its behavior. These guarantees are important for implementing c-variadics in e.g. const-eval.

Discussed in [#t-compiler/const-eval > c-variadics in const-eval](https://rust-lang.zulipchat.com/#narrow/channel/146212-t-compiler.2Fconst-eval/topic/c-variadics.20in.20const-eval/with/565509704).

I've also updated the comment for `Drop` a bit. The background here is that the C standard requires that `va_end` is used in the same function (and really, in the same scope) as the corresponding `va_start` or `va_copy`. That is because historically `va_start` would start a scope, which `va_end` would then close. e.g.

https://softwarepreservation.computerhistory.org/c_plus_plus/cfront/release_3.0.3/source/incl-master/proto-headers/stdarg.sol

```c
#define         va_start(ap, parmN)     {\
        va_buf  _va;\
        _vastart(ap = (va_list)_va, (char *)&parmN + sizeof parmN)
#define         va_end(ap)      }
#define         va_arg(ap, mode)        *((mode *)_vaarg(ap, sizeof (mode)))
```

The C standard still has to consider such implementations, but for Rust they are irrelevant. Hence we can use `Clone` for `va_copy` and `Drop` for `va_end`.
* Fix CI disk space issue for abi-cafe tests

Port disk space cleanup script from rust-lang/rust to free space on
GitHub Actions runners before running abi-cafe tests.

* ci: update free-disk-space.sh to match rust-lang/rust@d29e478

* ci: set RUNNER_ENVIRONMENT=github-hosted for free-disk-space script

* Revert indentation change

---------

Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com>
This is the conceptual opposite of the rust-cold calling convention and
is particularly useful in combination with the new `explicit_tail_calls`
feature.

For relatively tight loops implemented with tail calling (`become`) each
of the function with the regular calling convention is still responsible
for restoring the initial value of the preserved registers. So it is not
unusual to end up with a situation where each step in the tail call loop
is spilling and reloading registers, along the lines of:

    foo:
        push r12
        ; do things
        pop r12
        jmp next_step

This adds up quickly, especially when most of the clobberable registers
are already used to pass arguments or other uses.

I was thinking of making the name of this ABI a little less LLVM-derived
and more like a conceptual inverse of `rust-cold`, but could not come
with a great name (`rust-cold` is itself not a great name: cold in what
context? from which perspective? is it supposed to mean that the
function is rarely called?)
…bilee

add `simd_splat` intrinsic

Add `simd_splat` which lowers to the LLVM canonical splat sequence.

```llvm
insertelement <N x elem> poison, elem %x, i32 0
shufflevector <N x elem> v0, <N x elem> poison, <N x i32> zeroinitializer
```

Right now we try to fake it using one of

```rust
fn splat(x: u32) -> u32x8 {
    u32x8::from_array([x; 8])
}
```

or (in `stdarch`)

```rust
fn splat(value: $elem_type) -> $name {
    #[derive(Copy, Clone)]
    #[repr(simd)]
    struct JustOne([$elem_type; 1]);
    let one = JustOne([value]);
    // SAFETY: 0 is always in-bounds because we're shuffling
    // a simd type with exactly one element.
    unsafe { simd_shuffle!(one, one, [0; $len]) }
}
```

Both of these can confuse the LLVM optimizer, producing sub-par code. Some examples:

- rust-lang#60637
- rust-lang#137407
- rust-lang#122623
- rust-lang#97804

---

As far as I can tell there is no way to provide a fallback implementation for this intrinsic, because there is no `const` way of evaluating the number of elements (there might be issues beyond that, too). So, I added implementations for all 4 backends.

Both GCC and const-eval appear to have some issues with simd vectors containing pointers. I have a workaround for GCC, but haven't yet been able to make const-eval work. See the comments below.

Currently this just adds the intrinsic, it does not actually use it anywhere yet.
…ochenkov

abi: add a rust-preserve-none calling convention

This is the conceptual opposite of the rust-cold calling convention and is particularly useful in combination with the new `explicit_tail_calls` feature.

For relatively tight loops implemented with tail calling (`become`) each of the function with the regular calling convention is still responsible for restoring the initial value of the preserved registers. So it is not unusual to end up with a situation where each step in the tail call loop is spilling and reloading registers, along the lines of:

    foo:
        push r12
        ; do things
        pop r12
        jmp next_step

This adds up quickly, especially when most of the clobberable registers are already used to pass arguments or other uses.

I was thinking of making the name of this ABI a little less LLVM-derived and more like a conceptual inverse of `rust-cold`, but could not come with a great name (`rust-cold` is itself not a great name: cold in what context? from which perspective? is it supposed to mean that the function is rarely called?)
rust-bors bot pushed a commit that referenced this pull request Feb 18, 2026
Rollup of 18 pull requests


try-job: dist-x86_64-linux-alt
@rust-bors
Copy link
Contributor

rust-bors bot commented Feb 18, 2026

☀️ Try build successful (CI)
Build commit: 7fd8c9e (7fd8c9ed1dfbd6e924f91e73c7867c6e4db6cef2, parent: c043085801b7a884054add21a94882216df5971c)

@rust-bors

This comment has been minimized.

rust-bors bot pushed a commit that referenced this pull request Feb 19, 2026
…uwer

Rollup of 18 pull requests

Successful merges:

 - #152799 (Subtree sync for rustc_codegen_cranelift)
 - #152814 (stdarch subtree update)
 - #151059 (x86: support passing `u128`/`i128` to inline assembly)
 - #152097 (Suggest local variables for captured format args)
 - #152734 (Respect the `--ci` flag in more places in bootstrap)
 - #151703 (Fix ICE in transmutability error reporting when type aliases are normalized)
 - #152173 (Reflection TypeKind::FnPtr)
 - #152564 (Remove unnecessary closure.)
 - #152628 (tests: rustc_public: Check const allocation for all variables (1 of 11 was missing))
 - #152658 (compiletest: normalize stderr before SVG rendering)
 - #152766 (std::r#try! - avoid link to nightly docs)
 - #152780 (Remove some clones in deriving)
 - #152787 (Add a mir-opt test for alignment check generation [zero changes outside tests])
 - #152790 (Fix incorrect target in aarch64-unknown-linux-gnu docs)
 - #152792 (Fix an ICE while checking param env shadowing on an erroneous trait impl)
 - #152793 (Do no add -no-pie on Windows)
 - #152803 (Avoid delayed-bug ICE for malformed diagnostic attrs)
 - #152806 (interpret: fix comment typo)
@rust-bors rust-bors bot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Feb 19, 2026
@rust-bors
Copy link
Contributor

rust-bors bot commented Feb 19, 2026

💔 Test for 84f8463 failed: CI. Failed job:

@JonathanBrouwer
Copy link
Contributor Author

@bors retry
Spurious :c

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 19, 2026
@rust-bors

This comment has been minimized.

@ShoyuVanilla
Copy link
Member

Looks like stage2 rust-analyzer test is hanging for aarch64-apple 🤔
https://github.com/rust-lang/rust/actions/runs/22168331843/job/64100517455

@JonathanBrouwer
Copy link
Contributor Author

Is it actually hanging or just slow? Would like to keep it running until it times out

@ShoyuVanilla
Copy link
Member

ShoyuVanilla commented Feb 19, 2026

It shouldn't take that long. In rust-lang/rust-analyzer, it is finished <= 10 minutes on average

@rust-bors rust-bors bot added merged-by-bors This PR was explicitly merged by bors. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Feb 19, 2026
@rust-bors
Copy link
Contributor

rust-bors bot commented Feb 19, 2026

☀️ Test successful - CI
Approved by: JonathanBrouwer
Duration: 5h 37m 19s
Pushing fbd6934 to main...

@rust-bors rust-bors bot merged commit fbd6934 into rust-lang:main Feb 19, 2026
13 checks passed
@rustbot rustbot added this to the 1.95.0 milestone Feb 19, 2026
@ShoyuVanilla
Copy link
Member

What? 😄

@JonathanBrouwer
Copy link
Contributor Author

Yeah CI is magic, this has happened before :P
This kind of stuff is very unpredictable

@github-actions
Copy link
Contributor

What is this? This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.

Comparing e0cb264 (parent) -> fbd6934 (this PR)

Test differences

Show 60 test diffs

Stage 1

  • mem::fn_ptr::test_abi: [missing] -> pass (J0)
  • mem::fn_ptr::test_fn_ptrs: [missing] -> pass (J0)
  • mem::fn_ptr::test_inputs: [missing] -> pass (J0)
  • mem::fn_ptr::test_output: [missing] -> pass (J0)
  • mem::fn_ptr::test_ref: [missing] -> pass (J0)
  • mem::fn_ptr::test_unsafe: [missing] -> pass (J0)
  • mem::fn_ptr::test_variadic: [missing] -> pass (J0)
  • [mir-opt] tests/mir-opt/alignment_checks.rs: [missing] -> ignore (only executed when the pointer width is 64bit) (J1)
  • [ui] tests/ui/asm/x86_64/bad-reg.rs: pass -> [missing] (J1)
  • [ui] tests/ui/asm/x86_64/bad-reg.rs#experimental_reg: [missing] -> pass (J1)
  • [ui] tests/ui/asm/x86_64/bad-reg.rs#stable: [missing] -> pass (J1)
  • [ui] tests/ui/associated-types/param-env-shadowing-suggestion-no-ice-on-missing-assoc-value.rs: [missing] -> pass (J1)
  • [ui] tests/ui/diagnostic_namespace/do_not_recommend/malformed-diagnostic-attributes-if-expression.rs: [missing] -> pass (J1)
  • [ui] tests/ui/transmutability/type-alias-normalization.rs: [missing] -> pass (J1)

Stage 2

  • [mir-opt] tests/mir-opt/alignment_checks.rs: [missing] -> pass (J2)
  • mem::fn_ptr::test_abi: [missing] -> pass (J3)
  • mem::fn_ptr::test_fn_ptrs: [missing] -> pass (J3)
  • mem::fn_ptr::test_inputs: [missing] -> pass (J3)
  • mem::fn_ptr::test_output: [missing] -> pass (J3)
  • mem::fn_ptr::test_ref: [missing] -> pass (J3)
  • mem::fn_ptr::test_unsafe: [missing] -> pass (J3)
  • mem::fn_ptr::test_variadic: [missing] -> pass (J3)
  • [ui] tests/ui/associated-types/param-env-shadowing-suggestion-no-ice-on-missing-assoc-value.rs: [missing] -> pass (J4)
  • [ui] tests/ui/diagnostic_namespace/do_not_recommend/malformed-diagnostic-attributes-if-expression.rs: [missing] -> pass (J4)
  • [ui] tests/ui/transmutability/type-alias-normalization.rs: [missing] -> pass (J4)
  • [ui] tests/ui/asm/x86_64/bad-reg.rs: pass -> [missing] (J5)
  • [ui] tests/ui/asm/x86_64/bad-reg.rs#experimental_reg: [missing] -> pass (J5)
  • [ui] tests/ui/asm/x86_64/bad-reg.rs#stable: [missing] -> pass (J5)
  • [ui] tests/ui/asm/x86_64/bad-reg.rs: ignore (only executed when the architecture is x86_64) -> [missing] (J6)
  • [ui] tests/ui/asm/x86_64/bad-reg.rs#experimental_reg: [missing] -> ignore (only executed when the architecture is x86_64) (J6)
  • [ui] tests/ui/asm/x86_64/bad-reg.rs#stable: [missing] -> ignore (only executed when the architecture is x86_64) (J6)
  • [mir-opt] tests/mir-opt/alignment_checks.rs: [missing] -> ignore (only executed when the pointer width is 64bit) (J7)

Additionally, 28 doctest diffs were found. These are ignored, as they are noisy.

Job group index

Test dashboard

Run

cargo run --manifest-path src/ci/citool/Cargo.toml -- \
    test-dashboard fbd6934114e905d3cc61adbbd7e4a355eac5d0d7 --output-dir test-dashboard

And then open test-dashboard/index.html in your browser to see an overview of all executed tests.

Job duration changes

  1. dist-aarch64-apple: 1h 49m -> 2h 38m (+44.6%)
  2. aarch64-apple: 4h 5m -> 5h 28m (+33.7%)
  3. dist-x86_64-apple: 2h 39m -> 2h 5m (-21.8%)
  4. tidy: 2m 58s -> 2m 23s (-20.0%)
  5. pr-check-1: 33m 17s -> 27m 29s (-17.4%)
  6. i686-gnu-nopt-1: 2h 20m -> 1h 59m (-15.0%)
  7. i686-gnu-2: 1h 44m -> 1h 29m (-14.8%)
  8. x86_64-rust-for-linux: 52m 36s -> 45m 8s (-14.2%)
  9. dist-apple-various: 1h 48m -> 2h 3m (+13.6%)
  10. test-various: 2h 7m -> 1h 52m (-12.5%)
How to interpret the job duration changes?

Job durations can vary a lot, based on the actual runner instance
that executed the job, system noise, invalidated caches, etc. The table above is provided
mostly for t-infra members, for simpler debugging of potential CI slow-downs.

@rust-timer
Copy link
Collaborator

📌 Perf builds for each rolled up PR:

PR# Message Perf Build Sha
#150436 c_variadic: impl va_copy and va_end as Rust intrinsics ❌ conflicts merging '0b71ff60f8' into previous master ❌
#151059 x86: support passing u128/i128 to inline assembly 293e6bef51c378ddfa489f0ed15f97ec46599bc6 (link)
#151346 add simd_splat intrinsic ❌ conflicts merging 'ef9002c3d7' into previous master ❌
#151703 Fix ICE in transmutability error reporting when type aliase… 179e8366a6c9df6bc4fcf3b64e69d7e1500b3506 (link)
#152097 Suggest local variables for captured format args e66e1c4dedd86efea18ae8e6afb5e3c0e5c7218a (link)
#152173 Reflection TypeKind::FnPtr 1ea2890bbea8647293a29d0daff9eaefeb8a905b (link)
#152469 Remove unused features ❌ conflicts merging '81cb2a9d6d' into previous master ❌
#152512 core: Implement feature float_exact_integer_constants ❌ conflicts merging 'd54a023c69' into previous master ❌
#152564 Remove unnecessary closure. d3270925cb97bb89ab2bb06ef2b7b33c73e94ae2 (link)
#152573 move escape_symbol_name to cg_ssa ❌ conflicts merging '15831ddb75' into previous master ❌
#152628 tests: rustc_public: Check const allocation for all variabl… 48782f41a5e3c87087c0c0e148238b5a5698c278 (link)
#152658 compiletest: normalize stderr before SVG rendering fdf745f328234ee1d8715e4791314bdcfd1554fb (link)
#152734 Respect the --ci flag in more places in bootstrap 7579bdb274d60b85ac243da6a744bb248b9a6e7a (link)
#152766 std::r#try! - avoid link to nightly docs 174af087a4aa670c5d55f56f9d5738188cd4a38c (link)
#152780 Remove some clones in deriving b16e4b6c13587cef94bdccd0b65e83a72410f2b7 (link)
#152787 Add a mir-opt test for alignment check generation [zero cha… 69802a6abf4892346e327f2256d30d35c0eb0081 (link)
#152790 Fix incorrect target in aarch64-unknown-linux-gnu docs 7155c83117b3f87ab6f112521353f01ea98b6dca (link)
#152792 Fix an ICE while checking param env shadowing on an erroneo… 1b5ce9f02d845aae64255f5c6d00906beddcfda3 (link)
#152793 Do no add -no-pie on Windows 08de500bcc774129899a68b55da5f10ebb79b2e6 (link)
#152799 Subtree sync for rustc_codegen_cranelift 59ee46652a1323f8403fb0f98622f10ee9ad467e (link)
#152803 Avoid delayed-bug ICE for malformed diagnostic attrs 009cc547ea8e1011a4e18f31c9c5bcf1b78bb86b (link)
#152806 interpret: fix comment typo e4e77b29af5fb29c18d6939cfac6a9012715f678 (link)
#152814 stdarch subtree update 01b94bc2dc994688c05c11614f4b88db97088c59 (link)

previous master: e0cb264b81

In the case of a perf regression, run the following command for each PR you suspect might be the cause: @rust-timer build $SHA

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (fbd6934): comparison URL.

Overall result: ❌✅ regressions and improvements - please read the text below

Our benchmarks found a performance regression caused by this PR.
This might be an actual regression, but it can also be just noise.

Next Steps:

  • If the regression was expected or you think it can be justified,
    please write a comment with sufficient written justification, and add
    @rustbot label: +perf-regression-triaged to it, to mark the regression as triaged.
  • If you think that you know of a way to resolve the regression, try to create
    a new PR with a fix for the regression.
  • If you do not understand the regression or you think that it is just noise,
    you can ask the @rust-lang/wg-compiler-performance working group for help (members of this group
    were already notified of this PR).

@rustbot label: +perf-regression
cc @rust-lang/wg-compiler-performance

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.2% [0.2%, 0.2%] 1
Improvements ✅
(primary)
-0.2% [-0.3%, -0.2%] 5
Improvements ✅
(secondary)
-0.3% [-0.6%, -0.1%] 5
All ❌✅ (primary) -0.2% [-0.3%, -0.2%] 5

Max RSS (memory usage)

Results (secondary -1.3%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-1.3% [-1.3%, -1.3%] 1
All ❌✅ (primary) - - 0

Cycles

Results (primary 2.9%, secondary 3.3%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
2.9% [2.9%, 2.9%] 1
Regressions ❌
(secondary)
3.3% [2.5%, 4.1%] 4
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 2.9% [2.9%, 2.9%] 1

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 487.064s -> 481.318s (-1.18%)
Artifact size: 397.85 MiB -> 397.87 MiB (0.00%)

@rustbot rustbot added the perf-regression Performance regression. label Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) A-compiletest Area: The compiletest test runner A-test-infra-minicore Area: `minicore` test auxiliary and `//@ add-core-stubs` A-testsuite Area: The testsuite used to check the correctness of rustc merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. rollup A PR which is a rollup T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Comments