Skip to content

Do not increase depth when evaluating nested goals of NormalizesTo#157718

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
ShoyuVanilla:nested-normalizes-to-without-depth-increase
Jul 1, 2026
Merged

Do not increase depth when evaluating nested goals of NormalizesTo#157718
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
ShoyuVanilla:nested-normalizes-to-without-depth-increase

Conversation

@ShoyuVanilla

@ShoyuVanilla ShoyuVanilla commented Jun 10, 2026

Copy link
Copy Markdown
Member

View all comments

cc #156619 (comment)

Only the last commit is relevant since this is based on #156619

r? lcnr

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

This comment has been minimized.

Comment on lines +641 to +645
parent.required_depth =
parent.required_depth.max(match parent.increase_depth_for_nested {
IncreaseDepthForNested::Yes => required_depth_for_nested + 1,
IncreaseDepthForNested::No => required_depth_for_nested,
});

@lcnr lcnr Jun 16, 2026

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.

I've been thinking about about this as this feels brittle. Instead of required_depth, could we change the search graph to track the "min_reached_available_depth" and then required depth is computed as "available_depth - min_reached_available_depth"

that way the way depth is actually tracked doesn't matter anymore

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sounds good to me. I'll try that way 👍

@ShoyuVanilla ShoyuVanilla force-pushed the nested-normalizes-to-without-depth-increase branch from e59d7fa to dc07fda Compare June 17, 2026 15:32
@ShoyuVanilla ShoyuVanilla marked this pull request as ready for review June 17, 2026 15:33
@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 Jun 17, 2026
&mut self.stack,
step_kind_from_parent,
0,
None,

@lcnr lcnr Jun 18, 2026

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.

can you put the min_reachable_for_nested in the UpdateParentGoalCtxt instead?

View changes since the review

@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.

does wgpu compile with this change now?

View changes since this review

@ShoyuVanilla

Copy link
Copy Markdown
Member Author

does wgpu compile with this change now?

View changes since this review

Hmm, this doesn't help it at all 🤔
wgpu 25.0.2 is compiled with -Zmin-recursion-limit=141 but not with any lower number regardless of this change.
Maybe the deepest recursion in it isn't a normalization or I'm doing things wrong.
I'll look into that crate more.

@ShoyuVanilla

ShoyuVanilla commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

Yeah, we only have <= 1 NormalizesTo goal for each overflowing goal's search graph stack for that crate

@lcnr

lcnr commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

oh 🤔 interesting xd do we have AliasRelate goals there? these do still exist rn after all

@ShoyuVanilla

ShoyuVanilla commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

Yes, they do still exist. But we have very few of them anyway (<= 1 for each stack, total 3)

@lcnr

lcnr commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

okay, so there are some other goals whose depth we don't properly increase in the old solver but now do in the new one 🤔

what a pain

@ShoyuVanilla

Copy link
Copy Markdown
Member Author

Indeed. I'll take a look this weekend

@ShoyuVanilla ShoyuVanilla force-pushed the nested-normalizes-to-without-depth-increase branch from dc07fda to ee25de1 Compare June 18, 2026 14:26
@rust-log-analyzer

This comment has been minimized.

@ShoyuVanilla ShoyuVanilla force-pushed the nested-normalizes-to-without-depth-increase branch from ee25de1 to e23e501 Compare June 18, 2026 15:03
@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

UpdateParentGoalCtxt::Ordinary { nested_goals, min_reachable_available_depth } => {
parent.min_reached_available_depth = AvailableDepth(
parent.min_reached_available_depth.0.min(min_reachable_available_depth.0),
);

@lcnr lcnr Jun 29, 2026

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.

can we just impl Ord for AvailableDepth to avoid accessing 0 here?

r=me on the change I think

It's unfortunate that this doesn't actually change things for wgpu, but still just seems vaguely desirable?

View changes since the review

@ShoyuVanilla ShoyuVanilla force-pushed the nested-normalizes-to-without-depth-increase branch from e23e501 to 464fb78 Compare June 30, 2026 23:32
@rustbot

rustbot commented Jun 30, 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.

@ShoyuVanilla

Copy link
Copy Markdown
Member Author

@bors r=lcnr

@rust-bors

rust-bors Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 464fb78 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 Jul 1, 2026
jhpratt added a commit to jhpratt/rust that referenced this pull request Jul 1, 2026
…without-depth-increase, r=lcnr

Do not increase depth when evaluating nested goals of `NormalizesTo`

cc rust-lang#156619 (comment)

~~Only the last commit is relevant since this is based on rust-lang#156619~~

r? lcnr
rust-bors Bot pushed a commit that referenced this pull request Jul 1, 2026
Rollup of 6 pull requests

Successful merges:

 - #157718 (Do not increase depth when evaluating nested goals of `NormalizesTo`)
 - #158449 (QNX target renaming)
 - #158483 (signed strict division: just use normal division)
 - #158516 ( Deduplicate codegen backends in bootstrap config)
 - #158542 (Rename `align` to `default_align` on `Scalar` and `Primitive`)
 - #158636 (linkchecker: upgrade to `html5ever v0.39`)
@rust-bors rust-bors Bot merged commit 90faa9c into rust-lang:main Jul 1, 2026
13 checks passed
rust-timer added a commit that referenced this pull request Jul 1, 2026
Rollup merge of #157718 - ShoyuVanilla:nested-normalizes-to-without-depth-increase, r=lcnr

Do not increase depth when evaluating nested goals of `NormalizesTo`

cc #156619 (comment)

~~Only the last commit is relevant since this is based on #156619~~

r? lcnr
@rustbot rustbot added this to the 1.98.0 milestone Jul 1, 2026
@Kobzol

Kobzol commented Jul 1, 2026

Copy link
Copy Markdown
Member

Seems like this made compilation of typenum with the new solver 2x slower (#158639 (comment)).

@ShoyuVanilla

ShoyuVanilla commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

Seems like this made compilation of typenum with the new solver 2x slower (#158639 (comment)).

AFAIK, this PR doesn't regress the perf by its own, like making our trait solving algorithm less efficient.

typenum is a very interesting crate which heavily depends on very complex, recursive associated types: https://docs.rs/typenum/latest/src/typenum/uint.rs.html#424-431 🙃
In its method resolution some candidates indefinitely go down into those nested chain of normalizations and they are discarded by purely hitting the recursion limit.

This PR's intended effect is to increase the available recursion depth when we are dealing with normalization, and in theory, it can increase it by at most twice, when the search graph is a sheer chain of nested normalizations.
So, we have to go into 2 times deeper into search graph to discard the problematic ambiguous candidate and that's the cause of the regression.
We can get the similar regression with the previous revisions before this PR by passing -Zmin-recursion-limit=256(twice of the default 128), comparing it to the result without the flag.

So, I think the regression is direct outcome from the intention of this PR, rather than some sort of side effect. But 50% regression feels very unfortunate 😭 @lcnr Could you share your thoughts on this?

@lcnr

lcnr commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🤣 I love it

@lcnr

lcnr commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

see rust-lang/trait-system-refactor-initiative#73 for what exactly is wrecking performance here

@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.

wait 😅 your doing something different than what I expected xd

I was thinking that we don't increase the depth of the NormalizesTo goal

as in

  • Projection available_depth: 6
  • NoramalizesTo available_depth: 6 (do not increase depth)
  • Trait available_depth: 5 (actually decrease)

not increasing the depth for the nested goals of normalization goals means that we don't slice off important parts of the search tree when encountering overflow, i.e

AvailableDepth(last.available_depth.0 / D::DIVIDE_AVAILABLE_DEPTH_ON_OVERFLOW)

That slicing is necessary to avoid the exponential blowup in rust-lang/trait-system-refactor-initiative#73. Doing the thing I thought we are doing shouldn't be able to have such a perf impact 🤣

View changes since this review

@ShoyuVanilla

This comment was marked as off-topic.

@ShoyuVanilla

ShoyuVanilla commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

not increasing the depth for the nested goals of normalization goals means that we don't slice off important parts of the search tree when encountering overflow, i.e

AvailableDepth(last.available_depth.0 / D::DIVIDE_AVAILABLE_DEPTH_ON_OVERFLOW)

That slicing is necessary to avoid the exponential blowup in rust-lang/trait-system-refactor-initiative#73. Doing the thing I thought we are doing shouldn't be able to have such a perf impact 🤣

Oh, yeah.. looks like I've done things in a wrong way 🥲. I'll try it as you intended

@lcnr

lcnr commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Oh, yeah.. looks like I've done things in a wrong way 🥲.

happens :3 i didn't catch it myself

@ShoyuVanilla

Copy link
Copy Markdown
Member Author

That slicing is necessary to avoid the exponential blowup in rust-lang/trait-system-refactor-initiative#73. Doing the thing I thought we are doing shouldn't be able to have such a perf impact 🤣

But I guess the perf impact wouldn't be that different (though regardless of this, I think doing things as you intended make sense) because it only shifts where the available depth is decreased/overflowed by a single step from the parent normalizes-to goal -> nested goal?

I mean, if a nested goal of a normalizes-to is going to overflow in the correct implementation, the normalizes-to goal itself overflows in the current, wrong implementation and still divides the available depth, and if both of them is not going to overflow, then stepping into from that nested goal into its own nested goal will still decrease the available depth by 1?

@lcnr

lcnr commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Unless I am mistaken here, this does matter imagine a NormalizesTo goal with 2 nested goals, the first one overflows and then divides the recursion depth for the second nested goal. With your PR, the first overflows and the second also gets the same recursion depth as the first 🤔

pull Bot pushed a commit to xtqqczze/rust-lang-miri that referenced this pull request Jul 2, 2026
Rollup of 6 pull requests

Successful merges:

 - rust-lang/rust#157718 (Do not increase depth when evaluating nested goals of `NormalizesTo`)
 - rust-lang/rust#158449 (QNX target renaming)
 - rust-lang/rust#158483 (signed strict division: just use normal division)
 - rust-lang/rust#158516 ( Deduplicate codegen backends in bootstrap config)
 - rust-lang/rust#158542 (Rename `align` to `default_align` on `Scalar` and `Primitive`)
 - rust-lang/rust#158636 (linkchecker: upgrade to `html5ever v0.39`)
@ShoyuVanilla

Copy link
Copy Markdown
Member Author

Unless I am mistaken here, this does matter imagine a NormalizesTo goal with 2 nested goals, the first one overflows and then divides the recursion depth for the second nested goal. With your PR, the first overflows and the second also gets the same recursion depth as the first 🤔

🤔 Oh, that makes sense. I'll try the correct way

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

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

5 participants