Skip to content

normalise host effect sub-obligations from builtin impls #143391

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

davidtwco
Copy link
Member

Obligations produced by builtin impls need to be normalised so as not to later be compared to normalised candidates and fail.

For example, when introducing const sizedness then during the compilation of std, there will be a thread::Inner as const MetaSized obligation, the builtin impl will create a
<u32 as AtomicPrimitive>::AtomicInner as const MetaSized obligation, which if unnormalised, will end up in
evaluate_host_effect_from_item_bounds and then match_candidate being compared with a normalised candidate and failing.

r? @compiler-errors

Obligations produced by builtin impls need to be normalised so as not to
later be compared to normalised candidates.

For example, when introducing const sizedness then during the compilation
of `std`, there will be a `thread::Inner as const MetaSized` obligation,
the builtin impl will create a
`<u32 as AtomicPrimitive>::AtomicInner as const MetaSized`
obligation, which if unnormalised, will end up in
`evaluate_host_effect_from_item_bounds` and then `match_candidate` being
compared with a normalised candidate and failing.
@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. labels Jul 3, 2025
@compiler-errors compiler-errors changed the title trait_sel: normalise obligations from builtin impls normalise host effect sub-obligations from builtin impls Jul 3, 2025
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth,
obligation,
Copy link
Member

Choose a reason for hiding this comment

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

Don't normalize the whole obligation; it's not really needed.

obligations = obligations
.drain(..)
.map(|mut obligation| {
obligation.recursion_depth += 1;
Copy link
Member

Choose a reason for hiding this comment

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

We don't do recursion depth incrementation anywhere else, why did you add this here? Needs a comment at least.

Copy link
Member Author

Choose a reason for hiding this comment

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

On my branch with const sizedness, if I don't add this then it will just recurse indefinitely. It mirrors the increment that happens with trait predicates before it calls collect_predicates_for_types which is where those are normalised.

Copy link
Member

Choose a reason for hiding this comment

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

Then add a comment pls

}
}?;

let mut obligations_from_normalization = thin_vec![];
Copy link
Member

Choose a reason for hiding this comment

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

Uplift this normalization into evaluate_host_effect_for_destruct_goal. Each built-in obligation should be responsible for normalizing its own sub-obligations if needed.

Copy link
Member

Choose a reason for hiding this comment

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

Specifically, we only need to normalize the const condition part of the obligation before we create the obligation itself, so normalizing it there is more clear what it's doing.

Copy link
Member Author

@davidtwco davidtwco Jul 3, 2025

Choose a reason for hiding this comment

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

I did this in evaluate_host_effect_from_builtin_impls mirroring what happened for trait predicates, where this happened for every kind of builtin impl, but also because I'm not certain whether evaluate_host_effect_for_destruct_goal needs it, but I know that the evaluate_host_effect_for_sizedness_goal that exists in the branch that I spun this out of does need it, and putting it here did both.

self.collect_predicates_for_types(
obligation.param_env,
cause,
obligation.recursion_depth + 1,
trait_def,
types,
)

That's also why I do this on the whole obligation returned by this function, because it wasn't trivial to get the same return type out of both destruct and sizedness functions that wasn't Obligation. I could probably do that if we wanted but it was cleaner this way.

Copy link
Member

Choose a reason for hiding this comment

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

I'd rather be explicit rather than just normalizing everything at the end. I would recommend not modeling things off of the old solver; it's not great architecturally, and a lot of its behavior is just how things grew organically over the last 10 years. Sorry for the code duplication, but this normalization is subtle and right now it feels like kinda a large hammer.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's totally fair. As I don't have a justification for doing normalisation for the destruct goal and only know it is necessary for the const sizedness goal, there's not really anything to do in this PR, I don't have a function in master to add the normalisation to - so I'll close this. I'll incorporate your feedback for these changes into my local working branch though.

@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 Jul 3, 2025
@davidtwco
Copy link
Member Author

davidtwco commented Jul 3, 2025

#143391 (comment)

@davidtwco davidtwco closed this Jul 3, 2025
@davidtwco davidtwco deleted the const-traits-normalize-builtin-impls branch July 4, 2025 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants