Remove the NormalizesTo/Projection split#154108
Remove the NormalizesTo/Projection split#154108ShoyuVanilla wants to merge 2 commits intorust-lang:mainfrom
NormalizesTo/Projection split#154108Conversation
| ty::AliasTermKind::ProjectionTy | ||
| | ty::AliasTermKind::ProjectionConst | ||
| | ty::AliasTermKind::InherentTy | ||
| | ty::AliasTermKind::InherentConst |
There was a problem hiding this comment.
As the NormalizesTo is going to be replaced by Projection, this function can be called upon some non-projection aliases
There was a problem hiding this comment.
an exhaustive match please (and comment)
This comment has been minimized.
This comment has been minimized.
5b630c4 to
83d432a
Compare
| // FIXME: Longterm canonical queries should deal with all placeholders | ||
| // created inside of the query directly instead of returning them to the | ||
| // caller. | ||
| let prev_universe = delegate.universe(); |
There was a problem hiding this comment.
The change here is
- normal instantiation: unaffected.
- instantiation inside the very same query: use the
max_input_universeinstead of the delegate's universe.
Currently, we don't instantiate the canonicalized response within the very same query, but as per rust-lang/trait-system-refactor-initiative#223 (comment) (5. the root of the Projection goal then instantiates this query result inside of the same query using the var_values with the added entry for the new infer var) we should do.
In such cases, the current instantiation is not so idempotent modulo universes.
Suppose that the current query's max_input_universe is U(N) and we have the max universe U(N + 1) when computing the projection goal by here, because we have some higher-kinded binder in the goal,
rust/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Lines 564 to 567 in 1f7f8ea
rust/compiler/rustc_next_trait_solver/src/canonical/mod.rs
Lines 139 to 143 in 1f7f8ea
And we have some max universe U(M) in the probe's canonicalized response, instantiating it increases the current query's universe index by M, so it becomes U(N + 1 + M) and the prev_universe is U(N + 1).
Suppose that we have a region var with universe U(i) in the probe's canonical response.
We instantiate it into the universe U(i + N + 1) in the following lines
rust/compiler/rustc_next_trait_solver/src/canonical/mod.rs
Lines 187 to 194 in 1f7f8ea
Then when we finally finishing the query, we canonicalize it as a response, but since our max_input_universe is U(N)
rust/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs
Lines 458 to 468 in 1f7f8ea
rust/compiler/rustc_next_trait_solver/src/canonical/canonicalizer.rs
Lines 300 to 313 in 1f7f8ea
the resulting universe of that region becomes U(i + N + 1 - N) = U(i + 1), increased by 1 from the probe's response.
This might result into a leak check failure or other higher-kinded error. So, we should either do use max_input_universe to instantiate the canonical response from the probe or use the delegate's universe when canonicalizing the final response. I chose the former as it feels more hard to mistake with. (Sorry for the messy language since I'm very tired rn 😅 )
There was a problem hiding this comment.
i agree, annoying issue. I think we shouldn't canonicalize an input while inside of a binder, so not immediately clear how to handle higher-kinded Projection goals 🤔 I think this is definitely an issue, not happy with your current fix for it though 😅
There was a problem hiding this comment.
Yeah, I'll think about the proper fix 😅
Edit) Looks like the intermediate step you've suggested would be the road to it, right?
| } | ||
| }) | ||
| })?; | ||
| debug_assert!(resp.value.external_constraints.normalization_nested_goals.is_empty()); |
There was a problem hiding this comment.
| return Some( | ||
|
|
||
| let term = self.next_term_infer_of_kind(goal.predicate.term); | ||
| self.eq(goal.param_env, goal.predicate.term, term)?; |
There was a problem hiding this comment.
I'm adding another fresh inference var to the Projection goal's term here, besides the unconstrained one below and it's a bit subtle.
Currently, NormalizesTo goals cannot be a root goal so if it's term is an alias type, it is replaced by an inference var when being added as a nested goal in EvalCtxt::add_goal.
But as it becomes the Projection goal and can be evaluated as a root goal in some places such as normalization, it's term can be an alias type, which isn't replaced by an inference var.
That's a bit sad especially when I'm calling eq_structurally_relating_alias after the probe.
It should be normalized or otherwise fail the evaluation, so I'm replacing it with an inference var and the candidate evaluation inside the probe would either normalize it or fail the current query (I feel both ways are correct)
| let resp = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| { | ||
| ecx.var_values.var_values = extended_var_values; | ||
| ecx.var_kinds = extended_var_kinds; | ||
| ecx.current_goal_kind = CurrentGoalKind::NormalizesTo; |
There was a problem hiding this comment.
48e119ef#diff-3cb8110806ddb0ad4c49129dde2f9656727f8baf1f9f7456bfe6d008c5222009
Exactly the same purpose on candidate selection 😄
| goal: Goal<I, ty::ProjectionPredicate<I>>, | ||
| term: I::Term, | ||
| ) { | ||
| ) -> Result<(), NoSolution> { |
There was a problem hiding this comment.
The above premise on the function's comment is not true anymore, so Result instead of ICE
There was a problem hiding this comment.
this should still hold inside of the nested candidate assemble instantiate 🤔 would expect that we use normal eq outside of it
There was a problem hiding this comment.
Okay, I'll revert this and check whether it triggers ICE
| goal: Goal<I, ty::ProjectionPredicate<I>>, | ||
| term: ty::AliasTerm<I>, | ||
| ) { | ||
| ) -> Result<(), NoSolution> { |
| extended_var_kinds.push(extra_var_kind); | ||
| let extended_var_kinds = cx.mk_canonical_var_kinds(&extended_var_kinds); | ||
|
|
||
| let resp = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| { |
There was a problem hiding this comment.
The probe kind and the following EvalCtxt's field visivility changes are temporary PoCs 😅
|
r? lcnr The overall implementation is a coarse PoC so far, and I'd like check whether I'm understanding your initial design correctly 😄 I somehow ended up with |
83d432a to
cfbd86e
Compare
|
The job Click to see the possible cause of the failure (guessed by this bot) |
There was a problem hiding this comment.
hmm, as an intermediate step, could you remove the NormalizesTo special handling and do this nested canonical stuff inside of NormalizesTo, with a strict requiremetn that the goal itself is not higher-ranked, so we don't need to deal with the binder jank?
What is the current breakage/bugs here btw
| ty::AliasTermKind::ProjectionTy | ||
| | ty::AliasTermKind::ProjectionConst | ||
| | ty::AliasTermKind::InherentTy | ||
| | ty::AliasTermKind::InherentConst |
There was a problem hiding this comment.
an exhaustive match please (and comment)
| // FIXME: Longterm canonical queries should deal with all placeholders | ||
| // created inside of the query directly instead of returning them to the | ||
| // caller. | ||
| let prev_universe = delegate.universe(); |
There was a problem hiding this comment.
i agree, annoying issue. I think we shouldn't canonicalize an input while inside of a binder, so not immediately clear how to handle higher-kinded Projection goals 🤔 I think this is definitely an issue, not happy with your current fix for it though 😅
| goal: Goal<I, ty::ProjectionPredicate<I>>, | ||
| term: I::Term, | ||
| ) { | ||
| ) -> Result<(), NoSolution> { |
There was a problem hiding this comment.
this should still hold inside of the nested candidate assemble instantiate 🤔 would expect that we use normal eq outside of it
|
especially: how many of these issues are due to diagnostics changes, and what are the non-diagnostics bugs? |
Okay, I'll try this. Do you mean the following lines by rust/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs Lines 656 to 667 in 0312931
I guess currently all the remaning ones would be unblessed diagnostics drifts or fulfillment error reporting things as I haven't adjusted |
|
☔ The latest upstream changes (presumably #154637) made this pull request unmergeable. Please resolve the merge conflicts. |
cc rust-lang/trait-system-refactor-initiative#223