-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Don't check GAT bounds in normalization #117682
base: master
Are you sure you want to change the base?
Conversation
Niko tried this same thing in #98742. Can't remember that we actually discussed this much then, though. My biggest thought is that, in theory, the bounds we prove for projections is the same that we prove when normalizing that projection. So, if we start actually proving that projections are WF correctly, we're going to end up proving these bounds still. |
I'm curious: Does this variation of your example above pass or fail under this PR? trait Trait { type Gat<'a> where Self: 'a; }
impl<T> Trait for T { type Gat<'a> = &'a T where Self: 'a; }
type Raw<'a, T> = &'a T; // requires T: 'a
type Gat<'a, T> = <T as Trait>::Gat::<'a>; // requires T: 'a as well
fn test<T, U: Trait>() {
let _: fn(Gat<'static, T>);
} |
This PR accepts more code because it applies to impl candidates as well (vs. Niko's PR which applies to param env candidates only). The snippet above, for example, does not pass under Niko's PR // ...
fn test<T, U: Trait>() {
let _: fn(Gat<'_, T>); // Error always
}
It fails beacause it is normalized to |
Removing well formedness checks that are evidently required for soundness makes me pretty nervous, regardless of the fact that normalization being where we end up actually checking the bounds hold for soundness reasons is weird. This kind of compounds with the fact that the motivation here to me doesn't feel very good, this doesn't directly fix the issue it just works around it by avoiding proving bounds that we should be able to prove. Is it particularly urgent to solve this? It was acceptable to stabilize gats with these bugs in mind so I would assume we are not in any kind of rush. with that in mind i'd prefer us to wait until the new solver is done to tackle this (and do so by tracking implied bounds properly so that we can check wfness of types under binders properly) |
☔ The latest upstream changes (presumably #118138) made this pull request unmergeable. Please resolve the merge conflicts. |
This should fix most of GAT bugs related to
where Self: 'a
. See the ui tests for examples.The core idea is that we don't check associated type bounds when normalizing them, but rather rely on the them being well-formed. This is similar to how we deal with other rigid types. This should, for example, eliminate the strange inconsistent behavior in this snippet:
The main problem with this approach is that we currently don't check the well-formedness of projection types before normalizing them. See #100041 and #104764. This causes us to accept the following invalid code (from
tests/ui/generic-associated-types/unsatisfied-{body,item}-lifetime-bound.rs
)but I believe both issues are relatively straightforward to fix given the previous attempts in #100046 and #104746.
Another problem is that of
tests/ui/generic-associated-types/projection-bound-cycle{,-generic}.rs
, but that's hopefully fixable in some kind of analysis. (I can see it incompare_predicate_entailement
).So, my question to @rust-lang/types is that, assuming that we have a satisfactory solution to both problems above, do you have other concerns about this approach?
r? @ghost