-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
[WIP] Fix compiler incorrectly rejecting Drop impls where parent struct uses HRTB #59497
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @estebank (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
(marking as WIP to reflect "draft PR status" as noted in PR description above.) ((i was unware of github's support for "draft" status as an explicit state. however, given that I am also unsure whether bors knows about such state, I am pretty confident that an explicit "WIP" in the title is sensible.)) |
☔ The latest upstream changes (presumably #59810) made this pull request unmergeable. Please resolve the merge conflicts. |
Any updates on reviewing this? |
Pinged @nikomatsakis over zulip. The code doesn't seem bad on its own, but your assessment of this not being the best way of approaching this is correct. I'll defer to Niko for a more in depth review. |
cc @rust-lang/compiler, is there anyone else who can review this PR? It looks like @nikomatsakis probably doesn't have the time to do so. |
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.
I'm a little bit out of my depth here, so take my idea with a grain of salt. Calling p.relate(relater, predicate)
will probably do the right thing, but I have not been able to figure out which relater
you would want or if you'll need to roll your own
} | ||
}; | ||
|
||
if !assumptions_in_impl_context.iter().find(predicate_matches).is_some() { |
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.
nit: .iter().find(f).is_some()
should be .iter().any(f)
let predicate_matches = |p: &'_ &Predicate<'_>| { | ||
match (p, predicate) { | ||
(Predicate::Trait(p), Predicate::Trait(predicate)) => { | ||
let predicate_substs = &*predicate.skip_binder().trait_ref.substs; |
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.
So... I have been told that skip_binder
is always a signal that something with traits is going wrong. Digging around in the (4 years old) PR that created the "fulfill" comment above and in the docs around TraitRef
I believe that using relate
instead of ==
may do the right thing^TM for what you are doing here.
r? @pnkfelix |
☔ The latest upstream changes (presumably #61915) made this pull request unmergeable. Please resolve the merge conflicts. |
Hi! Screwing with late-bound regions like that tends to cause all sort of weird troubles. Have you tried using I don't think you can just use plain |
Ping from triage: @Osspial any updates on this? |
Hi everyone, came here while working on #58311. I think I can refactor @Osspial code to account for both HRTB (using Is it ok if I open a new PR or should we keep the two issues separate? I think that there's some benefit in doing a single refactor of the code that checks for |
…felix Fix too restrictive checks on Drop impls Fixes rust-lang#34426. Fixes rust-lang#58311. This PR completes and extends rust-lang#59497 (which has been inactive for a while now). The problem generating both issues was that when checking that the `Predicate`s of the `Drop` impl are exactly the same as the ones of the struct definition, the check was essentially performed by a simple `==` operator, which was not handling correctly HRTBs and involved `Fn` types. The implemented solution relies on the `relate` machinery to more correctly equate `Predicate`s, and on `anonymize_late_bound_regions` to handle HRTB in a more general way. As the `Relate` trait currently is implemented only for `TraitPredicate` and `ProjectionPredicate` (and as they were the ones generating problems), `relate` is used only for them while for other `Predicate`s the equality check is kept. I'm currently considering whether it would make sense to implement the `Relate` trait also for all other `Predicate`s to render the proposed solution more general.
…felix Fix too restrictive checks on Drop impls Fixes rust-lang#34426. Fixes rust-lang#58311. This PR completes and extends rust-lang#59497 (which has been inactive for a while now). The problem generating both issues was that when checking that the `Predicate`s of the `Drop` impl are exactly the same as the ones of the struct definition, the check was essentially performed by a simple `==` operator, which was not handling correctly HRTBs and involved `Fn` types. The implemented solution relies on the `relate` machinery to more correctly equate `Predicate`s, and on `anonymize_late_bound_regions` to handle HRTB in a more general way. As the `Relate` trait currently is implemented only for `TraitPredicate` and `ProjectionPredicate` (and as they were the ones generating problems), `relate` is used only for them while for other `Predicate`s the equality check is kept. I'm currently considering whether it would make sense to implement the `Relate` trait also for all other `Predicate`s to render the proposed solution more general.
I'll go ahead and close this now, since the underlying issue's been resolved. Thank you @TommasoBianchi for looking into it!' I figured out how to avoid the design pattern that was causing this to be a problem in my code, and I'd had a hard time getting into a groove working on the compiler so fixing this PR up fell to the wayside. I'm sorry for not communicating that earlier. |
@rustbot modify labels to -S-inactive +S-inactive-closed |
Fixes #34426.
The problem here is that
ensure_drop_predicates_are_implied_by_item_defn
indropck.rs
incorrectly rejects all implementations that have HRTB clauses in their where clause, even if the corresponding struct definition has an identical HRTB clause. Digging deep into the types, the issue is aDefId
mismatch inRegionKind::ReLateBound
when it contains aBoundRegion::BrNamed
variant - theBrNamed
'sDefId
in theDrop
impl doesn't match up with the correspondingDefId
in the struct definition.The current solution is to just ignore the
DefId
when we come across that specific pattern, and just compare the overall shape of the HRTB bound. This is an absolutely awful way to do it and probably shouldn't be merged onto master (hence the draft PR status), but it works. There are two better solutions I can come up with:DefId
s in the drop impl's HRTB clauses match up with theDefId
s in the struct's HRTB clauses.However, I have very little knowledge of the compiler's internals, and hence don't know where to look to implement either of those solutions.
Questions for whoever reviews this: