-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Normalize possibly un-normalized GAT projections #93361
Normalize possibly un-normalized GAT projections #93361
Conversation
r? @jackh726 (rust-highfive has picked a reviewer for you, use r? to override) |
thanks highfive, you r?'ed the right person lol |
compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Outdated
Show resolved
Hide resolved
@rustbot author |
@rustbot ready Looks like one test got fixed (?), and another lost one of its errors. I don't think this is a bad thing though, but I'm not really sure. |
The job Click to see the possible cause of the failure (guessed by this bot)
|
Pretty sure that CI test failure is unrelated since it also failed on #93358 lol |
@compiler-errors can you explain a bit about the problem that's occurring (at least in one of the added tests)? |
let obligation_pred_ty = obligation.predicate.term.ty().unwrap(); | ||
// FIXME(compiler-errors): We need to normalize here until we properly handle | ||
// GAT projection types that we can't normalize properly, see note in | ||
// `rustc_trait_selection::traits::project` |
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.
This...is the note?
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.
lmao sorry, copied this from another file and it's definitely ambiguous now.
I meant the note about trying to normalize GAT projections then treating them differently if they fail to normalize (not inserting a type variable because it would capture escaping bounds). I think I linked it in the PR description. I'll fix this comment when I get to my computer.
Yeah probably, that PR looks more general than mine. Lemme check. |
Cool, thanks. If you can't, I'll check at some point (busy week for me). |
@jackh726 to answer your questions, yup this PR seems totally fixed by #90887 instead, and nope this PR doesn't fix #90729. Assuming to get that fixed would require me to insert more normalization somewhere during trait selection, but my approach is kinda like a band-aid, compared to a more general solution like yours in #90887. I'll just close this PR in favor of yours. |
I think I'd like to keep this open for now - if only solely for the eventual discussion I'll have with @nikomatsakis I don't particularly dislike this PR. If nothing else, it does point out that maybe with #90887 we can remove some normalize calls in confirmation. |
The job Click to see the possible cause of the failure (guessed by this bot)
|
Sounds good to me @jackh726.
In that case, do you still want an explanation for why the normalization I added fixes those issues? I'd be happy to write up what I found if you'd like.
Yeah, I was thinking about #90887 this morning after you pointed the PR out. If you're normalizing predicates during the fulfillment loop, maybe we can rip out many of the
Not sure where these discussions with @nikomatsakis are happening, but if they're public or documented anywhere, I'd love to listen in. I've fixed a couple of GAT issues in the past, and getting that feature polished seems like really cool stuff if there's any space to get involved. |
That would be awesome!
This makes sense. It would also make it easily in the future to "just" remove those for lazy norm.
Niko and I meet roughly weekly, on Monday mornings (EST). They are technically GAT meetings (and that's what we usually talk about). It's probably cool if you join; message me on Zulip. |
(yes, np if you want to join those @compiler-errors) |
I think I owed @jackh726 a high-level description for why this PR fixes the issues mentioned above. For issue-93342, I think what's happening is that when we call For issue-93341, a similar thing happens, but for the fn output type. We instantiate the projection obligation I think both of these cases result from us instantiating obligations for method calls before we have substituted all of the generic substs for that the method call. Without GATs, having a not-yet-solved projection type is fine, since we just instantiate an inference variable and unify it later once it can be solved. But with GATs, we leave the un-normalized projection type inside of the obligation untouched if it fails to normalize. Then various parts of Sorry this explanation is kind of a mess! |
... now, all of this would be solved with lazy normalization, but since I'm still pretty new to working on rustc, I don't know where that effort's currently at. I also have been toying with the idea of inserting inference variables for GATs (introducing some concept of "bound inference variables"), and representing them as having captured their inner late bound regions as substs (to avoid the whole "inference variables shouldn't capture placeholders" problem)... I tried working out a PR for what this might look like, but got tied up in the query canonicalization code, and some inference var freshening code... |
@compiler-errors that's actually a fantastic explanation, and I can definitely follow what the cause is (I've seen very similar similar issues from the same root problem). We should definitely chat (with Niko too) about how to solve this problem "correctly" - because it definitely seems as though you're interested in taking a stab at it. We can talk about it the next time we meet together, maybe. |
Absolutely! Sounds good to me. |
☔ The latest upstream changes (presumably #93285) made this pull request unmergeable. Please resolve the merge conflicts. |
Gonna mark this as experimental - really just an alternative implementation that is open just for discussion. |
|
||
debug!(?trait_ref, ?obligations, "generator candidate obligations"); | ||
let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; |
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.
Does this represent cleanup or a change in behavior? I guess we are now normalizing the obligation trait-ref as well? What are we doing that, exactly?
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 believe it was previously an invariant that the obligation trait-ref was always normalized, and it seems like jack's PR also helps ensure that.
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.
We actually landed this specific part of the PR in #94108. So this is change in behavior technically (and kinda cleanup, but mostly the former). @jackh726 and I thought that this (#94108) would offset the perf regression in #90887, but then we came to the conclusion that the perf regression in #90887 is probably noise.
#94108 probably doesn't need to be around after that PR lands. I can put up a revert once it lands, to see if we see perf regressions.
Add some normalization during confirmation/obligation fulfillment because we have some difficulties normalizing GAT projection types (see note in
rustc_trait_selection::traits::project
).This is kinda a hack, and perhaps we want to work towards a better solution about failing to normalize GAT projection types cc: @jackh726, I'd like to be involved if brainstorming around that is happening!
Fixes #93341
Fixes #93342