-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Don't assemble non-env/bound candidates if projection is rigid #139762
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
base: master
Are you sure you want to change the base?
Conversation
Some changes occurred to the core trait solver cc @rust-lang/initiative-trait-system-refactor |
compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs
Outdated
Show resolved
Hide resolved
This PR has two separate effects
I feel 🤷 about the first case. I think we should fix #139788 regardless as using RPITITs recursively shouldn't cycle even if they are actually needed. It does match the behavior of the old solver so it feels generally reasonable to do so. The second one is a bit worrying. I would be opposed/far more hesitant if it were to do the same when assembling trait goals as that definitely has an exponential performance impact (e.g. it would fix rust-lang/trait-system-refactor-initiative#109). I want to be very careful here as I expect us to consider impl candidates in more cases in the future and ideally doing so won't introduce new hangs :< I expect that in theory we may have exponential performance differences depending on whether or not we check impl item bounds. I don't know if they are likely enough to actually cause issues for us in the future. I am still a bit on the fence about this PR, but generally in favor I think. |
Well part of the point of this approach is we're already doing all the work of proving the trait goal in order to even compute the Totally unrelated side-note that it would be nice if query cycles were recoverable, lol. |
☔ The latest upstream changes (presumably #139845) made this pull request unmergeable. Please resolve the merge conflicts. |
yeah, exactly, the only hangs we'd be avoiding this way are due to GAT bounds. I guess this seems acceptable to me, so yeah. Let's go ahead with this change |
55069b6
to
513ace6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an alternative structure would be to change assemble_and_evaluate_candidates
to also take
enum AssembledCandidates {
All,
/// Only assemble candidates from the environment,
/// ignoring impls. We only look for `ParamEnv` and
/// `AliasBound` candidates.
FromEnv,
}
and then put assemble_impl_candidates
behind an if/match 🤔
I feel like splitting assembly into multiple functions is making this a bit harder to reason about.
thoughts?
Putting this up for an initial review, it's still missing comments, clean-up, and possibly a tweak to deal with ambiguities in the
BestObligation
folder.This PR fixes rust-lang/trait-system-refactor-initiative#173. Specifically, we're creating an unnecessary query cycle in normalization by assembling an impl candidate even if we know later on during
merge_candidates
that we'll be filtering out that impl candidate.This PR adjusts the
merge_candidates
to assemble only env/bound candidates if we haveTraitGoalProvenVia::ParamEnv | TraitGoalProvenVia::AliasBound
.I'll leave some thoughts/comments in the code.
r? lcnr