Skip to content

Add rigid alias marker#156742

Open
adwinwhite wants to merge 23 commits into
rust-lang:mainfrom
adwinwhite:rigid-alias
Open

Add rigid alias marker#156742
adwinwhite wants to merge 23 commits into
rust-lang:mainfrom
adwinwhite:rigid-alias

Conversation

@adwinwhite

@adwinwhite adwinwhite commented May 19, 2026

Copy link
Copy Markdown
Contributor

View all comments

This PR adds a rigidness marker to TyKind::Alias and ConstKind::Unevaluated. It's used to skip renormalization of rigid aliases. The tracking issue for this is #155345.

The difficulty is that rigid aliases are only valid in their own TypingEnv so we need to force them back to non-rigid when entering another TypingEnv, either because a change to the ParamEnv or because we enter another TypingMode.

Changes to the ParamEnv currently only happen by moving into a new context. We now make sure that EarlyBinder new contains any rigid aliases, this way we have to normalize all aliases contained in it after instantiating.

Changes to the TypingMode are rare, and have to be manually handled.


The main changes in this PR are as follows:

  • we add enum IsRigid { Yes, No } as a field to TyKind::Alias and ConstKind::Unevaluated. It is always No with the old solver, this makes some of the code less nice than it will be with the old solver removed.
  • if we keep an alias as rigid when proving Projection goals we equate the expected term with that alias with IsRigid::Yes
  • EarlyBinder::bind now takes the tcx and eagerly sets all IsRigid to No, this is necessary as moving aliases into a different TypingEnv may cause them to no longer be rigid
  • EarlyBinder::bind_iter asserts that there are no rigid aliases instead of replacing them
  • type relations and generalization always structurally recurse into rigid aliases
  • a lot of places in the new solver can ICE when matching on TyKind::Alias with IsRigid::No

There's a lot of future work here:

  • coherence don't actually rely on lazy norm :<
  • remove eq_structurally_relating_aliases, have a special type folder for canonical responses
  • yeet AliasRelate, lazily replace non-rigid aliases with infer var + projection goal
  • ParamEnv normalization hack to incorrectly mark things as rigid
  • eagerly normalize when adding stuff to the fulfillment ctxt :>
  • change TypeOutlives goal handling to only expect rigid aliases
  • properly expect IsRigid::Yesin region handling (or yes_if_next_solver)
  • probably change EarlyBinder::bind to also assert that there are no rigid aliases and manually replacing rigid aliases before then where necessary

This PR also adds a flag -Zrenormalize-rigid-aliases to test whether we properly handle typing mode change.

Currently only tests/ui/traits/next-solver/assembly/ambiguity-due-to-uniquification-4.rs fails this check.

r? lcnr

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. PG-exploit-mitigations Project group: Exploit mitigations 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 May 19, 2026
@adwinwhite

Copy link
Copy Markdown
Contributor Author

Unfinished. Let's have a look at the perf impact nonetheless.

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label May 19, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request May 19, 2026
[Experiment] Add rigid alias marker
@rust-log-analyzer

This comment has been minimized.

@rust-bors

rust-bors Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

💔 Test for 73eccb5 failed: CI. Failed job:

@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added the T-clippy Relevant to the Clippy team. label May 20, 2026
@adwinwhite

Copy link
Copy Markdown
Contributor Author

@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 May 20, 2026
[Experiment] Add rigid alias marker
@rust-log-analyzer

This comment has been minimized.

@rust-bors

rust-bors Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 42e2939 (42e2939c892f3c5e872d5751bb653ed74736a040, parent: 4b9792692fbb675174d4d2082e7c37b2bc930e71)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (42e2939): comparison URL.

Overall result: ❌ regressions - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

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.8% [0.2%, 2.2%] 15
Regressions ❌
(secondary)
11.3% [0.1%, 95.1%] 29
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.1% [-0.1%, -0.1%] 2
All ❌✅ (primary) 0.8% [0.2%, 2.2%] 15

Max RSS (memory usage)

Results (primary 1.6%, secondary -1.7%)

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

mean range count
Regressions ❌
(primary)
2.1% [1.7%, 2.7%] 7
Regressions ❌
(secondary)
2.4% [0.8%, 3.6%] 6
Improvements ✅
(primary)
-2.4% [-2.4%, -2.4%] 1
Improvements ✅
(secondary)
-4.1% [-13.8%, -1.1%] 10
All ❌✅ (primary) 1.6% [-2.4%, 2.7%] 8

Cycles

Results (primary 2.5%, secondary 17.8%)

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

mean range count
Regressions ❌
(primary)
2.5% [2.4%, 2.6%] 2
Regressions ❌
(secondary)
19.3% [3.5%, 91.9%] 15
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-4.7% [-4.7%, -4.7%] 1
All ❌✅ (primary) 2.5% [2.4%, 2.6%] 2

Binary size

Results (primary 0.0%, secondary 0.1%)

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

mean range count
Regressions ❌
(primary)
0.0% [0.0%, 0.0%] 28
Regressions ❌
(secondary)
0.1% [0.0%, 0.4%] 27
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.0% [0.0%, 0.0%] 28

Bootstrap: 510.83s -> 514.725s (0.76%)
Artifact size: 400.58 MiB -> 401.07 MiB (0.12%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels May 20, 2026
@adwinwhite

Copy link
Copy Markdown
Contributor Author

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label May 20, 2026
@rust-bors

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@lcnr

lcnr commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

went through all changes myself, and while there's a bunch of future cleanup, I'd like to get this merged and work from there. Let's do another quick perf run and @BoxyUwU was open to look over this as well

@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 Jun 23, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

*self.tcx,
self.typing_env,
ty::EarlyBinder::bind(value),
ty::EarlyBinder::bind(self.tcx.tcx, value),

@BoxyUwU BoxyUwU Jun 23, 2026

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.

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.

TyCtxtAt

}),
ty,
// FIXME(rigid_aliases_marker): We have alias relating in
// `extract_verify_if_eq` which checks rigidness equality.

@BoxyUwU BoxyUwU Jun 23, 2026

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.

what does "checks rigidness equality" mean :3

View changes since the review

let verify_if_eq = verify_if_eq_b.skip_binder();
m.relate(verify_if_eq.ty, test_ty).ok()?;
// FIXME(rigid_aliases_marker): Both types should be a rigid alias in all cases
// with the new solver here. For now we just force things to non-rigid.

@BoxyUwU BoxyUwU Jun 23, 2026

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.

why force things to non-rigid? is it not actually the case that its always rigid here?

View changes since the review

// FIXME(rigid_aliases_marker): The aliases in `erased_ty` are currently not
// marked as rigid. We should probably do that instead as we only ever want to
// prove `TypeOutlives` once all aliases in them have been normalized.
let outlives_ty = ty::set_aliases_to_non_rigid(tcx, outlives_ty).skip_normalization();

@BoxyUwU BoxyUwU Jun 23, 2026

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.

why set them to non rigid :3 the erased_ty ones aren't but why does that mean we need outlives_ty to be non rigid too?

View changes since the review

// is gone. We set the whole type to non-rigid to be consistent with what we do in
// `can_match_erased_ty`.
let erased_alias_ty = self.tcx.erase_and_anonymize_regions(
ty::set_aliases_to_non_rigid(self.tcx, alias_ty)

@BoxyUwU BoxyUwU Jun 23, 2026

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.

why are we setting aliases to non rigid

View changes since the review

}

ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Alias(_) | ty::Param(_) => {
// FIXME: This should not treat aliases this way.

@BoxyUwU BoxyUwU Jun 23, 2026

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.

not an important enough fixme to track this somewhere?

View changes since the review

},
)
| ty::Placeholder(..)
| ty::Alias(ty::IsRigid::No, _)

@BoxyUwU BoxyUwU Jun 23, 2026

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.

where do we actually ensure that everything is normalized before calling into the variety of methods in this module :3

View changes since the review

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.

calls to structurally_normalize_ty before doing anything with them; the existing lazy normalization infrastructure

let predicates = ocx.normalize(&cause, elaborated_env, Unnormalized::new_wip(predicates));
// FIXME: opaque types in param env might be in defining scope but we're
// using non body analysis for here. So the rigidness marker is wrong.
let predicates = ty::set_aliases_to_non_rigid(tcx, predicates).skip_norm_wip();

@BoxyUwU BoxyUwU Jun 23, 2026

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.

i guess u just have to be kinda careful when doing funny stuff with changing envs and we don't really have any guardrails?

View changes since the review

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.

yeah, changing TypingEnvs and adding stuff to the ParamEnv both need to manually handle rigid aliases (which they always have/had to do with eager norm)

I don't really know how to avoid that, I think TypingEnv changes are rare enough that this is "fine" and these are very subtle regardless of rigid aliases, so adding more requirements to them seems barely acceptable to me.

Extending the ParamEnv will be interesting, but we should only do it in a single place in the trait solver, which would then be response to handle the aliases properly.

// Currently we can't guarantee that.
if let Ok(_) = relation.relate(
alias.to_ty(infcx.cx(), IsRigid::No),
set_aliases_to_non_rigid(infcx.cx(), alias2).skip_norm_wip(),

@BoxyUwU BoxyUwU Jun 23, 2026

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.

what effect does this actually have 🤔

View changes since the review

Err(TypeError::ConstMismatch(ExpectedFound::new(
Const::new_unevaluated(cx, a),
Const::new_unevaluated(cx, b),
Const::new_unevaluated(cx, ty::IsRigid::yes_if_next_solver(cx), a),

@BoxyUwU BoxyUwU Jun 23, 2026

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.

we just assume these are normalized?

View changes since the review

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.

yeah, we should never structurally relate aliases and fail unless the alias is rigid.

@rust-bors

rust-bors Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 6fcc74a (6fcc74a21585f4e8304ba80729c1fcce8e85f68f)
Base parent: 4429659 (4429659e4745016bd3f26a4a421843edc7fbc422)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (6fcc74a): comparison URL.

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

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

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.9% [0.3%, 2.1%] 22
Regressions ❌
(secondary)
2.8% [0.2%, 12.0%] 21
Improvements ✅
(primary)
-0.1% [-0.1%, -0.1%] 10
Improvements ✅
(secondary)
-4.7% [-30.5%, -0.1%] 31
All ❌✅ (primary) 0.6% [-0.1%, 2.1%] 32

Max RSS (memory usage)

Results (primary 1.7%, secondary 10.5%)

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

mean range count
Regressions ❌
(primary)
2.3% [1.0%, 5.6%] 10
Regressions ❌
(secondary)
15.8% [4.0%, 53.8%] 9
Improvements ✅
(primary)
-4.5% [-4.5%, -4.5%] 1
Improvements ✅
(secondary)
-1.6% [-2.5%, -1.0%] 4
All ❌✅ (primary) 1.7% [-4.5%, 5.6%] 11

Cycles

Results (primary 2.4%, secondary -4.0%)

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

mean range count
Regressions ❌
(primary)
2.4% [2.1%, 2.8%] 3
Regressions ❌
(secondary)
7.9% [4.9%, 10.9%] 6
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-7.0% [-28.9%, -2.0%] 24
All ❌✅ (primary) 2.4% [2.1%, 2.8%] 3

Binary size

Results (primary 0.0%, secondary 0.0%)

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

mean range count
Regressions ❌
(primary)
0.0% [0.0%, 0.3%] 24
Regressions ❌
(secondary)
0.1% [0.0%, 0.4%] 25
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.1% [-0.1%, -0.0%] 8
All ❌✅ (primary) 0.0% [0.0%, 0.3%] 24

Bootstrap: 504.341s -> 508.657s (0.86%)
Artifact size: 353.08 MiB -> 353.01 MiB (-0.02%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jun 23, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@lcnr

lcnr commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@bors r+ rollup=never p=1

@rust-bors

rust-bors Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 1af8ca5 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 Jun 23, 2026
@lcnr

lcnr commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@bors r- will conflict with the currently happening rollup

@rust-bors rust-bors Bot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jun 23, 2026
@rust-bors

rust-bors Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

This pull request was unapproved.

View changes since this unapproval

@rust-bors rust-bors Bot removed the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-query-system Area: The rustc query system (https://rustc-dev-guide.rust-lang.org/query.html) perf-regression Performance regression. PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. 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.

6 participants