Skip to content

Fix: WF ICE assumptions on binders - #160497

Open
ssenthilnathan3 wants to merge 1 commit into
rust-lang:mainfrom
ssenthilnathan3:fix/wf-ice-assumptions-on-binders
Open

Fix: WF ICE assumptions on binders#160497
ssenthilnathan3 wants to merge 1 commit into
rust-lang:mainfrom
ssenthilnathan3:fix/wf-ice-assumptions-on-binders

Conversation

@ssenthilnathan3

@ssenthilnathan3 ssenthilnathan3 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #160293

-Zassumptions-on-binders ICEs because the solver's well_formed_goals passes terms with resolvable inference variables to unnormalized_obligations, which asserts they're already resolved (unlike other callers).

Resolve inference variables before computing WF obligations.

@rustbot

rustbot commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred to the core trait solver

cc @rust-lang/initiative-trait-system-refactor

@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 Aug 4, 2026
@rustbot

rustbot commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust Project is excited to review your changes, and you should hear from @adwinwhite (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue
Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 75 candidates
  • Random selection from 21 candidates

@rustbot

This comment has been minimized.

@rustbot rustbot added has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 4, 2026
@ssenthilnathan3 ssenthilnathan3 changed the title Fixes wf ICE assumptions on binders Fix: WF ICE assumptions on binders Aug 4, 2026
@ssenthilnathan3
ssenthilnathan3 force-pushed the fix/wf-ice-assumptions-on-binders branch from aefa84f to 5b7244d Compare August 4, 2026 09:43
@rustbot rustbot removed has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 4, 2026
@@ -0,0 +1,38 @@
//@ compile-flags: -Znext-solver=globally -Zassumptions-on-binders
//@ check-pass

@adwinwhite adwinwhite Aug 10, 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.

Could you add some comments on what this test is about?

View changes since the review

param_env: ty::ParamEnv<'tcx>,
term: ty::Term<'tcx>,
) -> Option<Vec<Goal<'tcx, ty::Predicate<'tcx>>>> {
let term = self.0.resolve_vars_if_possible(term);

@adwinwhite adwinwhite Aug 10, 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.

We already resolve vars for goal input and normalized term in the next solver. Could you find the specific callers that forget to do this? If there're only one or two cases, we probably should fix it there instead.

View changes since the review

@adwinwhite

Copy link
Copy Markdown
Contributor

@rustbot author

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

rustbot commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot

rustbot commented Aug 10, 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.

@rustbot

This comment has been minimized.

@rustbot rustbot added the has-merge-commits PR has merge commits, merge with caution. label Aug 10, 2026
@ssenthilnathan3
ssenthilnathan3 force-pushed the fix/wf-ice-assumptions-on-binders branch from 79ad637 to e176c84 Compare August 10, 2026 05:48
@rustbot rustbot removed has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 10, 2026
@ssenthilnathan3

Copy link
Copy Markdown
Contributor Author

@rustbot review

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 10, 2026
@adwinwhite

Copy link
Copy Markdown
Contributor

I think we should look into the callers of enter_forall_with_assumptions and find out why we have unresolved vars there. It should be easy to find out which caller is relevant from the ICE backtrace :>

@ssenthilnathan3

Copy link
Copy Markdown
Contributor Author

I think we should look into the callers of enter_forall_with_assumptions and find out why we have unresolved vars there. It should be easy to find out which caller is relevant from the ICE backtrace :>

I think the only caller of enter_forall_with_assumptions is compute_goal, which gets the predicate from enter_canonical (fresh vars). The ICE comes from a nested call deep in the probe:

eager_resolve_vars in evaluate_goal_raw uses opportunistic_resolve_ty_var, so some type vars may escape canonicalization unresolved, get unified later during equating, and then a deeper nested forall visits them in the RawAssumptions visitor.

The fix resolves them in visit_ty/visit_const before computing WF obligations, matching what the debug_assert_eq! in unnormalized_obligations expects.

Let me know if I'm overlooking something here.

@adwinwhite

adwinwhite commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

I think the only caller of enter_forall_with_assumptions is compute_goal, which gets the predicate from enter_canonical (fresh vars). The ICE comes from a nested call deep in the probe:

How so? ripgrep would show 6 callers. And compute_goal uses resolved vars already since the goal is instantiated from canonical form directly.

@ssenthilnathan3

ssenthilnathan3 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

I think the only caller of enter_forall_with_assumptions is compute_goal, which gets the predicate from enter_canonical (fresh vars). The ICE comes from a nested call deep in the probe:

How so? ripgrep would show 6 callers. And compute_goal uses resolved vars already since the goal is instantiated from canonical form directly.

Sorry.. you're right, I only checked compute_goal.

And yes, there are 6 callers that could trigger this pattern, but fixing at every caller would be fragile.

The visitor-level resolve matches the convention: callers of unnormalized_obligations should resolve first (same as implied_outlives_bounds.rs:100).

@adwinwhite

Copy link
Copy Markdown
Contributor

Convention is different in the next solver. We do not expect random unresolved vars here.

@ssenthilnathan3
ssenthilnathan3 force-pushed the fix/wf-ice-assumptions-on-binders branch from e176c84 to 94dc630 Compare August 12, 2026 13:05
@adwinwhite

adwinwhite commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Those target_projections come from existential predicates of trait object(ty::Dyn) and the trait object type is normalized here which resolves infer vars. Unsure why we get unresolved infer vars later.

Sorry for being pedantic over this. It's totally fine if you don't want to dig further and we can merge the original fix with a FIXME that we didn't find the source of the unresolved vars.

@ssenthilnathan3

ssenthilnathan3 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Those target_projections come from existential predicates of trait object(ty::Dyn) and the trait object type is normalized here which resolves infer vars. Unsure why we get unresolved infer vars later.

Sorry for being pedantic over this. It's totally fine if you don't want to dig further and we can merge the original fix with a FIXME that we didn't find the source of the unresolved vars.

thanks for the direction!! i’d like to dig into this a bit further. i’ll try to trace where the target_projection state changes and probably fine why the infer vars end up unresolved later

@ssenthilnathan3

Copy link
Copy Markdown
Contributor Author

@adwinwhite, i did some tracing. the principal eq in the Trait arm resolves the vars in the unification table, but the projection binder still holds the old var ids since the terms are interned/immutable. when the Projection arm runs, those vars are stale but resolvable.

i'll add this explanation to the FIXME and keep the call-site resolution as the fix :)

@adwinwhite

Copy link
Copy Markdown
Contributor

👍 Good job. We don't need the FIXME then. Just keep current fix and add comments on resolve_if_possible calls.

I think we should add a debug_assert resolve_vars_if_possible(value) = value in enter_forall as it doesn't resolve vars inside. I wonder why that doesn't cause problems before. This can be a follow up.

@ssenthilnathan3
ssenthilnathan3 force-pushed the fix/wf-ice-assumptions-on-binders branch from 94dc630 to d430a5c Compare August 14, 2026 05:35
@ssenthilnathan3
ssenthilnathan3 force-pushed the fix/wf-ice-assumptions-on-binders branch from e1a620e to d918d13 Compare August 14, 2026 05:59
@rust-bors

rust-bors Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

☔ The latest upstream changes (presumably #161093) made this pull request unmergeable. Please resolve the merge conflicts by rebasing.

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

Labels

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

Development

Successfully merging this pull request may close these issues.

[ICE]: Term != Term

3 participants