Skip to content

Eagerly normalize in generalize - #151746

Merged
rust-bors[bot] merged 12 commits into
rust-lang:mainfrom
jdonszelmann:eagerly-normalize-in-generalize
Mar 20, 2026
Merged

rust-bors[bot] merged 12 commits into
rust-lang:mainfrom
jdonszelmann:eagerly-normalize-in-generalize

Conversation

@jdonszelmann

@jdonszelmann jdonszelmann commented Jan 27, 2026

Copy link
Copy Markdown
Contributor

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Jan 27, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@lcnr

lcnr commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Jan 29, 2026
… r=<try>

Eagerly normalize in generalize
@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 29, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-bors

rust-bors Bot commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

💔 Test for 92bb985 failed: CI. Failed job:

@lcnr

lcnr commented Jan 30, 2026

Copy link
Copy Markdown
Contributor

collector error: Failed to profile 'serde-1.0.219-new-solver' with Eprintln, recorded: expected success, got exit status: 101

fun, we've got some jank in serde which we don't have in our ui test suite

@jdonszelmann
jdonszelmann force-pushed the eagerly-normalize-in-generalize branch from 5bd20bb to d0cdaae Compare February 2, 2026 18:38
@rust-log-analyzer

This comment has been minimized.

@jdonszelmann
jdonszelmann force-pushed the eagerly-normalize-in-generalize branch from d0cdaae to fb5d5cf Compare February 3, 2026 15:04
@rust-log-analyzer

This comment has been minimized.

@jdonszelmann
jdonszelmann force-pushed the eagerly-normalize-in-generalize branch from fb5d5cf to d96cab0 Compare February 3, 2026 15:51
@rust-log-analyzer

This comment has been minimized.

Comment thread compiler/rustc_trait_selection/src/solve.rs Outdated
@jdonszelmann
jdonszelmann force-pushed the eagerly-normalize-in-generalize branch from d96cab0 to 5611a89 Compare February 5, 2026 10:47
@jdonszelmann
jdonszelmann marked this pull request as ready for review February 5, 2026 10:47
@rustbot

rustbot commented Feb 5, 2026

Copy link
Copy Markdown
Collaborator

changes to the core type system

cc @lcnr

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 5, 2026
@jdonszelmann

Copy link
Copy Markdown
Contributor Author

@lcnr I think this fixes all issues we had. Only one test really regressed, some got a bunch better. Fixed the span on the one test we discussed.

@jdonszelmann
jdonszelmann force-pushed the eagerly-normalize-in-generalize branch from 5611a89 to 3f90d08 Compare February 5, 2026 10:50
@rust-log-analyzer

This comment has been minimized.

@jdonszelmann

Copy link
Copy Markdown
Contributor Author

@GuillaumeGomez is this another flaky test?

@jdonszelmann
jdonszelmann force-pushed the eagerly-normalize-in-generalize branch from 1adea68 to 60e068f Compare March 19, 2026 09:48

@lcnr lcnr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reflowing the comments :<

r=me after this nit

View changes since this review

Comment on lines +365 to +398
/// Treat aliases as potentially normalizable.
///
/// This is the default state that generalization starts in, unless we're treating aliases as rigid.
/// It also means we're not currently inside an alias, since then we change the state to
/// `IncompletelyRelateAliasArgs`
Default,
/// We enter this state when we're generalizing the arguments of a potentially normalizeable alias.
///
/// The behavior here is different between the old and the new solver:
///
/// In the old solver, the difference between this and `Default` is needed to
/// correctly handle `<T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0`.
/// That equality can hold by either normalizing the outer or the inner associated type.
/// In the old solver, we always structurally relate aliases,
/// however, when we encounter an occurs check failure, we propagate the failure to the outermost alias,
/// for which we then emit a Projection goal.
///
/// In the new solver, we rarely get into this state.
/// When we encounter aliases we instead attempt to normalize them, and treat them as rigid using `ShallowStructurallyRelate`.
/// Only when an alias is higher-ranked, we continue with similar logic to the old solver,
/// except now we also explicitly relate the type and consts in the arguments of aliases while in this mode.
///
/// FIXME: Because we relate the type and consts in the arguments of aliases while in this mode,
/// this is "incomplete".
IncompletelyRelateAliasArgs,
/// During generalization, when we encounter aliases,
/// we will first attempt to normalize them when we're using the next trait solver.
/// We can now treat the normalized alias as rigid, but only for "one layer", hence shallow.
/// New aliases encountered inside the arguments of the outer alias should once again be related as normal.
ShallowStructurallyRelateAliases,
/// Treat aliases as rigid when relating them.
///
/// This corresponds to `relation.structurally_relate_aliases()`.
StructurallyRelateAliases,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Treat aliases as potentially normalizable.
///
/// This is the default state that generalization starts in, unless we're treating aliases as rigid.
/// It also means we're not currently inside an alias, since then we change the state to
/// `IncompletelyRelateAliasArgs`
Default,
/// We enter this state when we're generalizing the arguments of a potentially normalizeable alias.
///
/// The behavior here is different between the old and the new solver:
///
/// In the old solver, the difference between this and `Default` is needed to
/// correctly handle `<T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0`.
/// That equality can hold by either normalizing the outer or the inner associated type.
/// In the old solver, we always structurally relate aliases,
/// however, when we encounter an occurs check failure, we propagate the failure to the outermost alias,
/// for which we then emit a Projection goal.
///
/// In the new solver, we rarely get into this state.
/// When we encounter aliases we instead attempt to normalize them, and treat them as rigid using `ShallowStructurallyRelate`.
/// Only when an alias is higher-ranked, we continue with similar logic to the old solver,
/// except now we also explicitly relate the type and consts in the arguments of aliases while in this mode.
///
/// FIXME: Because we relate the type and consts in the arguments of aliases while in this mode,
/// this is "incomplete".
IncompletelyRelateAliasArgs,
/// During generalization, when we encounter aliases,
/// we will first attempt to normalize them when we're using the next trait solver.
/// We can now treat the normalized alias as rigid, but only for "one layer", hence shallow.
/// New aliases encountered inside the arguments of the outer alias should once again be related as normal.
ShallowStructurallyRelateAliases,
/// Treat aliases as rigid when relating them.
///
/// This corresponds to `relation.structurally_relate_aliases()`.
StructurallyRelateAliases,
/// Treat aliases as potentially normalizable.
///
/// This is the default state that generalization starts in, unless we're
/// treating aliases as rigid. It also means we're not currently inside an
/// alias, since then we change the state to `IncompletelyRelateAliasArgs`.
Default,
/// We enter this state when we're generalizing the arguments of a
/// potentially normalizeable alias.
///
/// The behavior here is different between the old and the new solver:
///
/// In the old solver, the difference between this and `Default` is needed to
/// correctly handle `<T as Bar<<?0 as Foo>::Assoc>::Assoc == ?0`. That
/// equality can hold by either normalizing the outer or the inner
/// associated type. In the old solver, we always structurally relate
/// aliases. If we we encounter an occurs check failure, we propagate the
/// failure to the outermost alias, for which we then emit a `Projection`
/// goal instead.
///
/// In the new solver, we rarely get into this state.
/// When we encounter aliases we instead attempt to normalize them, and treat
/// them as rigid using `ShallowStructurallyRelate`. Only when an alias has
/// escaping bound variables do we continue with similar logic to the old
/// solver, except now we also explicitly relate the type and consts in the
/// arguments of aliases while in this mode.
///
/// FIXME: Because we relate the type and consts in the arguments of aliases
/// while in this mode, this is incomplete.
IncompletelyRelateAliasArgs,
/// During generalization, when we encounter aliases, we will first attempt
/// to normalize them when we're using the next trait solver. We can now
/// treat the normalized alias as rigid, but only for "one layer", hence
/// shallow. New aliases encountered inside the arguments of the outer alias
/// should once again be related as normal.
ShallowStructurallyRelateAliases,
/// Treat aliases as rigid when relating them.
///
/// This corresponds to `relation.structurally_relate_aliases()`.
StructurallyRelateAliases,

@jdonszelmann
jdonszelmann force-pushed the eagerly-normalize-in-generalize branch from 60e068f to d665c0b Compare March 20, 2026 13:02
@jdonszelmann

Copy link
Copy Markdown
Contributor Author

@bors r=lcnr

@rust-bors

rust-bors Bot commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

📌 Commit d665c0b has been approved by lcnr

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 Mar 20, 2026
@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 Mar 20, 2026
@rust-bors

rust-bors Bot commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

☀️ Test successful - CI
Approved by: lcnr
Duration: 3h 8m 32s
Pushing ac7f9ec to main...

@rust-bors
rust-bors Bot merged commit ac7f9ec into rust-lang:main Mar 20, 2026
12 checks passed
@rustbot rustbot added this to the 1.96.0 milestone Mar 20, 2026
@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 bfc05d6 (parent) -> ac7f9ec (this PR)

Test differences

Show 8 test diffs

Stage 1

  • [ui] tests/ui/traits/next-solver/generalize/eagely-normalizing-aliases.rs#next: [missing] -> pass (J1)
  • [ui] tests/ui/traits/next-solver/generalize/eagely-normalizing-aliases.rs#old: [missing] -> pass (J1)

Stage 2

  • [ui] tests/ui/traits/next-solver/generalize/eagely-normalizing-aliases.rs#next: [missing] -> pass (J0)
  • [ui] tests/ui/traits/next-solver/generalize/eagely-normalizing-aliases.rs#old: [missing] -> pass (J0)

Additionally, 4 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 ac7f9ec7da74d37fd28667c86bf117a39ba5b02a --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-llvm-mingw: 1h 51m -> 1h 28m (-20.3%)
  2. x86_64-gnu: 2h 10m -> 2h 25m (+11.9%)
  3. test-various: 1h 55m -> 2h 8m (+11.8%)
  4. x86_64-gnu-llvm-22-3: 1h 45m -> 1h 55m (+9.0%)
  5. optional-x86_64-gnu-parallel-frontend: 2h 29m -> 2h 42m (+8.8%)
  6. x86_64-gnu-llvm-21-3: 1h 57m -> 2h 7m (+8.4%)
  7. dist-x86_64-musl: 2h 19m -> 2h 7m (-8.2%)
  8. arm-android: 1h 47m -> 1h 39m (-8.2%)
  9. dist-powerpc64-linux-musl: 1h 40m -> 1h 32m (-7.8%)
  10. dist-x86_64-llvm-mingw: 1h 56m -> 1h 47m (-7.8%)
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
Copy Markdown
Collaborator

Finished benchmarking commit (ac7f9ec): 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.2% [0.2%, 0.3%] 7
Regressions ❌
(secondary)
0.3% [0.1%, 0.4%] 10
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.4% [-0.4%, -0.4%] 1
All ❌✅ (primary) 0.2% [0.2%, 0.3%] 7

Max RSS (memory usage)

Results (primary 0.7%, secondary -0.6%)

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

mean range count
Regressions ❌
(primary)
2.3% [2.3%, 2.3%] 1
Regressions ❌
(secondary)
1.1% [1.1%, 1.1%] 1
Improvements ✅
(primary)
-0.9% [-0.9%, -0.9%] 1
Improvements ✅
(secondary)
-1.5% [-1.7%, -1.2%] 2
All ❌✅ (primary) 0.7% [-0.9%, 2.3%] 2

Cycles

Results (secondary -1.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)
2.2% [2.2%, 2.2%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.8% [-3.6%, -2.1%] 2
All ❌✅ (primary) - - 0

Binary size

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

Bootstrap: 485.797s -> 485.09s (-0.15%)
Artifact size: 396.97 MiB -> 394.98 MiB (-0.50%)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this unwrap-errs here: #154173

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 23, 2026
…ize-in-generalize, r=lcnr

Revert eagerly normalize in generalize

r? @lcnr

Reverts rust-lang#151746

We'll likely pull eager normalization out of generalization

Fixes rust-lang#154173
Fixes rust-lang#154244
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 23, 2026
…ize-in-generalize, r=lcnr

Revert eagerly normalize in generalize

r? @lcnr

Reverts rust-lang#151746

We'll likely pull eager normalization out of generalization

Fixes rust-lang#154173
Fixes rust-lang#154244
@panstromek

Copy link
Copy Markdown
Contributor

perf triage:

Reverted in #154257 for other reasons.

@rustbot label: +perf-regression-triaged

@rustbot rustbot added the perf-regression-triaged The performance regression has been triaged. label Mar 24, 2026
@lqd

lqd commented Apr 20, 2026

Copy link
Copy Markdown
Member

A note if we want to re-land this: while investigating the recent bevy/wgpu regression in the impossible predicates pass, I've noticed this PR made the binius_field (the crate which didn't work under the new solver and was fixed by #149904, also causing the bevy regression) check builds under the new solver go from ~2m to 50m/an hour. And just to have a few numbers at the same place, the old solver takes 4s.

haasham1 pushed a commit to haasham1/rust that referenced this pull request Sep 19, 2026
haasham1 pushed a commit to haasham1/rust that referenced this pull request Sep 21, 2026
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. perf-regression-triaged The performance regression has been triaged. T-compiler Relevant to the compiler 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.

9 participants