Skip to content

Rollup of 5 perf-sensitive pull requests - #165107

Merged
rust-bors[bot] merged 30 commits into
rust-lang:mainfrom
JonathanBrouwer:rollup-51xMab4
Oct 29, 2026
Merged

rust-bors[bot] merged 30 commits into
rust-lang:mainfrom
JonathanBrouwer:rollup-51xMab4

Conversation

@JonathanBrouwer

Copy link
Copy Markdown
Member

Successful merges:

r? @ghost

Create a similar rollup

panstromek and others added 30 commits October 26, 2026 07:24
…large structs

This improves compile time for crates that derive Debug for large structs (e.g., ripgrep). It also reduces metadata size for some of those.
This avoids one more string and makes the derive code slightly nicer as we don't have to track whether we're on last item
We do this by changing the variable to a closure and only call it when it's needed
In `instantiate_and_apply_query_response`, instantiate the two
instantiatable parts of the response separately. This requires adding a
new method `instantiate_value` to `SolverDelegate` (r-a will need
updating separately) and making a function of the same name in
`rustc_infer` public.

Do a similar thing for `State` in `instantiate_canonical_state`.

This is equivalent behaviour that will enable further changes in
subsequent commits.
Both `unify_query_var_values` call sites are preceded by a call to
`instantiate_value` on the `var_values`. If instantiation changes any of
the elements we end up interning an entirely new list, through
`fold_list`.

This commit changes things so that `unify_query_var_values` does
instantiation on individual elements as it iterates, and avoids having
to intern an entire list. This changes the caching behaviour in some
cases, but overall it's a perf win.
This avoids a lot of calls to `instantiate_value`.
`Response` has `is_identity` and `is_identity_modulo_regions` methods.
These are reasonably hot and traverse the response's `var_values` in
very similar ways. This commit merges these two methods into a single
method that returns a new three-value enum `IsIdentity`. It also
pre-computes that `IsIdentity` for each response and stores it in the
new `Response::var_values_is_identity` field.

This is a perf win because it avoids repeated traversals.
If the response is an identity, and there are no external constraints,
and the response var kinds match the canonical goal var kinds, this
function is a no-op.
It provides a more principled and type-safe way to extract and process
parts of a `Canonical` value.
They are like `TokenStream` and `TokenTree`, but with the additional
`AttrTokenTree::AttrsTarget` variant that stores the attributes and
tokens for an attribute target.

This duplication is annoying, and also leads to some inefficiencies
when we have to produce an `AttrTokenStream` only to then convert it to
a `TokenStream`.

The new `LazyAttrTokenStreamInner::to_token_stream_with` takes a
`configure` closure. This closure is passed through various layers down
to `make_token_trees`, where it controls cfg expansion. Callers that
don't do expansion pass a trivial `keep_all` closure.
`try_configure_tokens` passes a non-trivial `configure` closure.

Overall this change makes the code shorter and slightly improves compile
times. One minor behavioural change on an error case: if parse recovery
finishes with an unmatched opening delimiter, `make_token_trees` drops
the caller's preceding trees; the old code kept them. This is obscure
and no existing tests hit it.

The next commit will rename `LazyAttrTokenStream` to `LazyTokenStream`.
It's a separate commit because it is uninteresting churn.
By removing the `Attr`, which is no longer necessary.
In `check_expr_lit`, if we have an integer literal and the expected type
is an integer type var, we currently create a new type var that is later
unified with the expected one. This commit changes it to just reuse the
existing expected one. This avoids lots of unnecessary integer type var
creation and unification. (And likewise for float type vars.)

This is a big win on `deep-vector`, but it doesn't help with other
benchmarks, unfortunately.

Only one ui test is changed, for the better:

- Previously it printed `{integer}` because there were two distinct
  integer variables. Now there is one and the types-are-equal error
  message elision occurs and it is shown as `_`. (Same as what you'd see
  if the call was `test(&mut 7i32, &7i32)` with known types.)

- There is now also a useful `help` subdiagnostic.

Given how simple the change is, I think it's worthwhile.
New solver opts for `diesel` (part 2)

A sequel to rust-lang#163981. Details in individual commits.

Local measurements:
```
solver         icounts (B)
------         -----------
old            37.9
new (orig)     49.6 (1.31x)
new (this PR)  45.4 (1.20x)
```
Also some small improvements on a range of other benchmarks.

r? @lcnr
…ethercote

perf: emit field names as a concatenated string in derive(Debug) for structs

Similar idea as rust-lang#162535 and previous attempts.

Again, I also noticed that no test fails when I mess up the string, so I added a test case.
Avoid stdlib's `impl Hash for Discriminant` for stable hashing

Of all the different ways we currently leak compiler/stdlib details into stable hashes, relying on `Discriminant::hash` seems high on the list of ones that could cause actual problems in the future.

This PR therefore removes `impl StableHash for Discriminant`, and replaces it with an explicit negative impl as a roadblock to anyone who might unknowingly try to reintroduce the problem.

To make this work, `#[derive(StableHash)]` now invents its own fake discriminant based on the syntactic ordering of enum variants. That should keep the hash values consistent across compiler stages.

In places where we were hashing Discriminant manually, this PR introduces explicit “tag” enums as seen in rust-lang#164458.

---

This change necessarily perturbs the hashes included in legacy-symbol-mangling symbols, as demonstrated in the re-blessed tests. This should be fine, as I believe the exact hash values are considered unstable anyway and have changed in the past.
…type-vars, r=BoxyUwU

Avoid unnecessary numeric type vars

In `check_expr_lit`, if we have an integer literal and the expected type is an integer type var, we currently create a new type var that is later unified with the expected one. This commit changes it to just reuse the existing expected one. This avoids lots of unnecessary integer type var creation and unification. (And likewise for float type vars.)

This is a big win on `deep-vector`, but it doesn't help with other benchmarks, unfortunately.

Only one ui test is changed, for the better:

- Previously it printed `{integer}` because there were two distinct integer variables. Now there is one and the types-are-equal error message elision occurs and it is shown as `_`. (Same as what you'd see if the call was `test(&mut 7i32, &7i32)` with known types.)

- There is now also a useful `help` subdiagnostic.

Given how simple the change is, I think it's worthwhile.

r? @BoxyUwU
…petrochenkov

Remove `AttrTokenStream` and `AttrTokenTree`

These are very similar to `TokenStream` and `TokenTree`, which has annoyed me for a long time. This PR removes them, making the code simpler and a tiny bit faster. Details in individual commits.

r? @petrochenkov
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. 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. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Oct 28, 2026
@JonathanBrouwer

Copy link
Copy Markdown
Member Author

@bors r+ p=1 force

@rust-bors

rust-bors Bot commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 885f13d has been approved by JonathanBrouwer

It is now in the queue for this repository.

@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 Oct 28, 2026
@JonathanBrouwer JonathanBrouwer changed the title Rollup of 5 pull requests Rollup of 5 perf-sensitive pull requests Oct 28, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Oct 29, 2026
…uwer

Rollup of 5 perf-sensitive pull requests

Successful merges:

 - #164234 (New solver opts for `diesel` (part 2))
 - #164726 (perf: emit field names as a concatenated string in derive(Debug) for structs)
 - #164953 (Avoid stdlib's `impl Hash for Discriminant` for stable hashing)
 - #164965 (Avoid unnecessary numeric type vars)
 - #165022 (Remove `AttrTokenStream` and `AttrTokenTree`)
@JonathanBrouwer

Copy link
Copy Markdown
Member Author

@bors yield

@rust-bors

rust-bors Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Auto build was cancelled. Cancelled workflows:

The next pull request likely to be tested is #165095.

@rust-bors

This comment has been minimized.

@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 Oct 29, 2026
@rust-bors

rust-bors Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

☀️ Test successful - CI
Approved by: JonathanBrouwer
Duration: 3h 16m 57s
Pushing 96a18bf to main...

@github-actions

Copy link
Copy Markdown
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 ce37c4f (parent) -> 96a18bf (this PR)

Test differences

Show 34 test diffs

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

Test dashboard

Run

cargo run --manifest-path src/ci/citool/Cargo.toml -- \
    test-dashboard 96a18bf5ffa2b24f9cf3d1c731a9eb121c1acad9 --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. test-i686-gnu-nopt-2: 1h 20m -> 2h 27m (+83.5%)
  2. test-aarch64-gnu: 1h 19m -> 2h 18m (+74.7%)
  3. dist-sparcv9-solaris: 1h 6m -> 1h 42m (+54.7%)
  4. dist-powerpc64le-linux-gnu: 1h 9m -> 1h 46m (+53.0%)
  5. dist-powerpc-linux: 1h 2m -> 1h 35m (+53.0%)
  6. dist-x86_64-llvm-mingw: 2h 10m -> 1h 22m (-36.6%)
  7. dist-x86_64-illumos: 1h 5m -> 1h 28m (+34.7%)
  8. test-x86_64-gnu-nopt: 2h 33m -> 1h 40m (-34.6%)
  9. dist-i686-linux: 1h 53m -> 1h 14m (-34.5%)
  10. dist-riscv64-linux-gnu: 1h 14m -> 1h 39m (+34.0%)
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-bors

rust-bors Bot commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

📌 Perf builds for each rolled up PR:

PR# Message Perf Build Sha
#164234 New solver opts for diesel (part 2) b09da0c0d57bc165d4cea14d145e8bdcb7868426
(link)
#164726 perf: emit field names as a concatenated string in derive(D… fba03b9a303c2d6b3c051025ec609c4413713a74
(link)
#164953 Avoid stdlib's impl Hash for Discriminant for stable hash… e2eb557e074eda84bc943fdecfbf192bc4fc9566
(link)
#164965 Avoid unnecessary numeric type vars 28ca19205d04e6fa38c9262f43f03891f801c570
(link)
#165022 Remove AttrTokenStream and AttrTokenTree 3449b8a29190e3e60c974e7b80de20162fcab04a
(link)

parent commit: ce37c4ff83

In the case of a perf regression, run the following command with the SHAs of each PR you suspect might be the cause: @rust-timer triage $SHA $SHA $SHA..., or run @rust-timer triage all to benchmark all rollup members.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (96a18bf): comparison URL.

Overall result: ❌✅ regressions and improvements - please read:

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.1% [0.1%, 0.1%] 1
Regressions ❌
(secondary)
0.3% [0.1%, 0.7%] 18
Improvements ✅
(primary)
-0.4% [-1.4%, -0.1%] 116
Improvements ✅
(secondary)
-3.1% [-12.6%, -0.2%] 107
All ❌✅ (primary) -0.4% [-1.4%, 0.1%] 117

Max RSS (memory usage)

Results (primary 0.0%, secondary -5.1%)

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

mean range count
Regressions ❌
(primary)
1.0% [0.4%, 2.5%] 14
Regressions ❌
(secondary)
2.9% [2.9%, 2.9%] 1
Improvements ✅
(primary)
-1.8% [-4.3%, -0.5%] 8
Improvements ✅
(secondary)
-5.5% [-11.7%, -1.0%] 20
All ❌✅ (primary) 0.0% [-4.3%, 2.5%] 22

Cycles

Results (primary 0.5%, secondary -5.9%)

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

mean range count
Regressions ❌
(primary)
1.2% [0.4%, 4.4%] 12
Regressions ❌
(secondary)
8.4% [2.7%, 12.4%] 4
Improvements ✅
(primary)
-1.1% [-2.1%, -0.4%] 5
Improvements ✅
(secondary)
-7.4% [-14.9%, -1.4%] 37
All ❌✅ (primary) 0.5% [-2.1%, 4.4%] 17

Binary size

Results (primary -0.7%, secondary 0.2%)

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.2% [0.2%, 0.2%] 1
Improvements ✅
(primary)
-0.7% [-1.5%, -0.1%] 16
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -0.7% [-1.5%, -0.1%] 16

Bootstrap: 490.291s -> 487.353s (-0.60%)
Artifact size: 406.63 MiB -> 406.68 MiB (0.01%)

@rustbot rustbot added the perf-regression Performance regression. label Oct 29, 2026
@panstromek

Copy link
Copy Markdown
Contributor

@rust-timer triage all

@rust-timer

Copy link
Copy Markdown
Collaborator
Running triage with 49 benchmarks

Triage only executes the benchmarks on rollup members, that were changed significantly on the rollup.
For this rollup, these benchmarks are:

  • await-call-tree
  • bitmaps-3.2.1
  • bitmaps-3.2.1-new-solver
  • cargo-0.87.1
  • coercions
  • cranelift-codegen-0.119.0
  • ctfe-stress-5
  • deep-vector
  • deeply-nested-multi
  • deeply-nested-multi-new-solver
  • derive
  • diesel-2.2.10
  • diesel-2.2.10-new-solver
  • enum-stress
  • eza-0.21.2
  • helloworld
  • html5ever-0.31.0-new-solver
  • hyper-1.6.0
  • image-0.25.6
  • include-blob
  • issue-46449
  • issue-58319
  • issue-88862
  • libc-0.2.172
  • many-assoc-items
  • nalgebra-0.33.0
  • nalgebra-0.33.0-new-solver
  • projection-caching
  • regex-automata-0.4.8
  • regression-31157
  • ripgrep-14.1.1
  • ripgrep-14.1.1-nll
  • serde-1.0.219-new-solver
  • serde-1.0.219-nll
  • serde_derive-1.0.219
  • syn-2.0.101
  • syn-2.0.101-new-solver
  • token-stream-stress
  • tokio-1.53.1
  • tt-muncher
  • tuple-stress
  • typenum-1.18.0
  • typenum-1.18.0-new-solver
  • ucd
  • unicode-normalization-0.1.24
  • unify-linearly
  • wf-projection-stress-65510
  • wg-grammar
  • wg-grammar-new-solver

#164234 b09da0c New solver opts for diesel (part 2)

Queued b09da0c with parent ce37c4f, future comparison URL.
There is currently 1 preceding artifact in the queue.
It will probably take at least ~1.3 hours until the benchmark run finishes.


#164726 fba03b9 perf: emit field names as a concatenated string in derive(Debug) for structs

Queued fba03b9 with parent ce37c4f, future comparison URL.
There are currently 2 preceding artifacts in the queue.
It will probably take at least ~2.0 hours until the benchmark run finishes.


#164953 e2eb557 Avoid stdlib's impl Hash for Discriminant for stable hashing

Queued e2eb557 with parent ce37c4f, future comparison URL.
There are currently 3 preceding artifacts in the queue.
It will probably take at least ~2.7 hours until the benchmark run finishes.


#164965 28ca192 Avoid unnecessary numeric type vars

Queued 28ca192 with parent ce37c4f, future comparison URL.
There are currently 4 preceding artifacts in the queue.
It will probably take at least ~3.3 hours until the benchmark run finishes.


#165022 3449b8a Remove AttrTokenStream and AttrTokenTree

Queued 3449b8a with parent ce37c4f, future comparison URL.
There are currently 5 preceding artifacts in the queue.
It will probably take at least ~4.0 hours until the benchmark run finishes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. rollup A PR which is a rollup 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. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants