Skip to content

enable eager param_env norm in new solver#156976

Open
lcnr wants to merge 5 commits into
rust-lang:mainfrom
lcnr:eagerly-normalize-env
Open

enable eager param_env norm in new solver#156976
lcnr wants to merge 5 commits into
rust-lang:mainfrom
lcnr:eagerly-normalize-env

Conversation

@lcnr

@lcnr lcnr commented May 26, 2026

Copy link
Copy Markdown
Contributor

https://rust-lang.zulipchat.com/#narrow/channel/364551-t-types.2Ftrait-system-refactor/topic/goodbye.20proper.20param_env.20normalization/near/594260464

Slightly unfortunate that this is what we ended up with. but for now, this fixes issues and landing the new solver with this is certainly not worse than keeping the old impl.

This PR only eagerly normalizes, it does not yet treat aliases in param_env candidates as rigid, which is the worse part of this change.

fixes rust-lang/trait-system-refactor-initiative#265
fixes #136661

r? @BoxyUwU

@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. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels May 26, 2026
@rustbot

rustbot commented May 26, 2026

Copy link
Copy Markdown
Collaborator

BoxyUwU is currently at their maximum review capacity.
They may take a while to respond.

@lcnr lcnr force-pushed the eagerly-normalize-env branch from 9cef0c9 to 62e38a9 Compare May 26, 2026 15:26
@lcnr

lcnr commented May 26, 2026

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

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request May 26, 2026
enable eager `param_env` norm in new solver
@rust-log-analyzer

This comment has been minimized.

@rust-bors

rust-bors Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 13060c6 (13060c6b2274ff62e47ad00d65d3f92f610a1d67, parent: b7e97a98f24cdb1335850209991455cb9734d333)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (13060c6): 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
Regressions ❌
(secondary)
1.7% [0.2%, 3.0%] 10
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.1% [-0.1%, -0.1%] 3
All ❌✅ (primary) - - 0

Max RSS (memory usage)

Results (secondary -0.5%)

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.6% [2.3%, 2.8%] 3
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.4% [-3.5%, -0.6%] 5
All ❌✅ (primary) - - 0

Cycles

Results (primary 2.5%, secondary 2.6%)

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.3%, 2.8%] 2
Regressions ❌
(secondary)
2.6% [2.3%, 2.8%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 2.5% [2.3%, 2.8%] 2

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: 511.751s -> 510.766s (-0.19%)
Artifact size: 400.67 MiB -> 400.56 MiB (-0.03%)

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

lcnr commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

r? @jackh726 as Boxy is on leave this week

@rustbot rustbot assigned jackh726 and unassigned BoxyUwU May 27, 2026
@rust-log-analyzer

This comment has been minimized.

@jackh726

jackh726 commented Jun 2, 2026

Copy link
Copy Markdown
Member

r=me with green CI

@rust-bors

This comment has been minimized.

@rustbot

rustbot commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@lcnr lcnr force-pushed the eagerly-normalize-env branch from d52b353 to db4b783 Compare June 12, 2026 12:30
@lcnr

lcnr commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

The only user facing change covered by this FCP is dd884e4: we now entirely ignore region errors when normalizing the ParamEnv, even in the old solver.

This change causes #136661 to compile with the old solver, see the added tests in the last commit:

//@ check-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver

// In `fn hrtb` normalizing the elaborated where-clause
// `T: for<'a> Supertrait<<&'a () as WithAssoc>::As>` results in
// a region error as `&'a ()` is not `&'static ()`.
//
// This happens even though the where-clauses themselves are well-formed
// as we never have to prove `&'a (): WithAssoc` as `'a` is a bound variable.
//
// Unlike `normalize-param-env-missing-implied-bound-1.rs` this snippet caused
// an ICE with the old trait solver, as we did register region constraints from
// relating types. This ICE was tracked in #136661.

#![allow(unused)]

trait Supertrait<T> {}

trait Other {
    fn method(&self) {}
}

impl WithAssoc for &'static () {
    type As = ();
}

trait WithAssoc {
    type As;
}

trait Trait<P: WithAssoc>: Supertrait<P::As> {
    fn method(&self) {}
}

fn hrtb<T: for<'a> Trait<&'a ()>>() {}

With this PR, we entirely ignore region constraints from ParamEnv normalization. This is necessary to avoid breakage with the new solver, see rust-lang/trait-system-refactor-initiative#166.

The core issue here is that the old solver already accepted code like this if the constraint was an explicit outlives clause instead, see tests/ui/traits/normalize/normalize-param-env-missing-implied-bound-1.rs for a test that already compiled with the old solver.

I am slightly unhappy about this as it feels like fully ignoring region constraints here could be unsound in theory. I haven't been able to come up with an exploit for this issue and even if one exists, it should only be easier to trigger as we already ignore explicit outlives where-clauses on stable. This PR only causes us to also ignore region constraints emitted by type relations. In the medium term this should be fixed by proper assumptions on binders.

@steffahn @theemathas would be interesting to see whether u can exploit this issue. To summarize:

  • when proving that where-clauses are well-formed we ignore requirements referencing escaping bound variables, so we don't check &'a (): WithAssoc
  • we can then normalize <&'a () as WithAssoc>::As in an elaborated super trait (or associated item) bound, ignoring the constraints required by normalization. The closest I can get to making this problematic is https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=b8080c65c19259d2a3ab5d9e2ad1cc84
  • can we now use this "incorrectly normalized" elaborated bound in a way that's unsound, e.g. we use them when proving that the ParamEnv is well-formed in the first place
  • can we actually call fn hrtb here

Given my reasoning in the above paragraph, I would merge this as is:

I am slightly unhappy about this as it feels like fully ignoring region constraints here could be unsound in theory. I haven't been able to come up with an exploit for this issue and even if one exists, it should only be easier to trigger as we already ignore explicit outlives where-clauses. This PR only causes us to also ignore region constraints emitted by type relations. In the medium term this should be fixed by proper assumptions on binders.

@rfcbot fcp merge types

@rust-rfcbot

rust-rfcbot commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

@lcnr has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Jun 12, 2026
lcnr added 4 commits June 12, 2026 14:48
the old solver doesn't register `TypeOutlives` and `RegionOutlives` goals if `ignoring_regions` is set. The new solver always registers these requirements, so we instead ignore errors caused by these constraints.
@lcnr lcnr force-pushed the eagerly-normalize-env branch from db4b783 to e7e6758 Compare June 12, 2026 12:49
@rustbot

rustbot commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)

15 LL | | where
16 LL | |     Self::Item: 'a,
17    | |___________________^
-    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+    = note: for more information, see <https://rustc-dev-guide.rust-lang.org/overview.html#queries> and <https://rustc-dev-guide.rust-lang.org/query.html>
19 
20 error: aborting due to 1 previous error
21 


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args specialization/min_specialization/next-solver-region-resolution.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/specialization/min_specialization/next-solver-region-resolution.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/specialization/min_specialization/next-solver-region-resolution" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "-Znext-solver=globally"
stdout: none
--- stderr -------------------------------
error[E0391]: cycle detected when computing normalized predicates of `<impl at /checkout/tests/ui/specialization/min_specialization/next-solver-region-resolution.rs:18:1: 21:21>`
##[error]  --> /checkout/tests/ui/specialization/min_specialization/next-solver-region-resolution.rs:18:1
   |
LL | / impl<'a, T> Foo for &T
LL | | //~^ ERROR: cycle detected when computing normalized predicates of `<impl at $DIR/next-solver-region-resolution.rs:18:1: 21:21>`
LL | | where
LL | |     Self::Item: Baz,
   | |____________________^
   |
   = note: ...which immediately requires computing normalized predicates of `<impl at /checkout/tests/ui/specialization/min_specialization/next-solver-region-resolution.rs:18:1: 21:21>` again
note: cycle used when computing whether impls specialize one another
  --> /checkout/tests/ui/specialization/min_specialization/next-solver-region-resolution.rs:12:1
   |
LL | / impl<'a, T> Foo for &'a T
LL | | where
LL | |     Self::Item: 'a,
   | |___________________^
   = note: for more information, see <https://rustc-dev-guide.rust-lang.org/overview.html#queries> and <https://rustc-dev-guide.rust-lang.org/query.html>

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0391`.
------------------------------------------

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

Labels

disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. perf-regression Performance regression. proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. 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. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

7 participants