-
Notifications
You must be signed in to change notification settings - Fork 182
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
Variance #609
Variance #609
Conversation
6ad79a2
to
cd44491
Compare
I added the ability to set the variances of adts and fn_defs in tests. E.g.
I didn't add any tests that rely on this, other than a quick lowering success test. |
841de64
to
d11b470
Compare
3635351
to
a206730
Compare
Did some work on this and rebased. |
☔ The latest upstream changes (presumably #628) made this pull request unmergeable. Please resolve the merge conflicts. Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:
|
7b17f8a
to
893e8db
Compare
893e8db
to
7967679
Compare
Rebased this :) |
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.
OK, so, I have been reading the code locally. It seems good. I have to go now. I came here to comment on push_lifetime_eq_goal
but I see that @matthewjasper has already made the comments I came here to make. Locally I have a few tests I was toying with adding and I may rebase and/or push those commits tomorrow.
cc95d4e
to
2d82a43
Compare
tests/test/subtype.rs
Outdated
} yields { | ||
"Unique;substitution [], lifetime constraints [\ | ||
InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ | ||
InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]" |
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 doesn't look right, these constraints are not solvable.
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.
But these are? This just says that 'a == 'b
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.
These are placeholders, so relating them is an error. The requirements here should be !1_0: '?0
, !1_1: ?0
, '!2_0: '?1
, '!2_0: '?2
(the same as subtyping in both directions).
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.
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.
yes, but region inference will error on such constraints.
chalk-solve/src/infer/unify.rs
Outdated
let a_universal = self.table.instantiate_binders_universally(interner, a); | ||
let b_existential = self.table.instantiate_binders_existentially(interner, b); | ||
Zip::zip_with(self, &a_universal, &b_existential)?; | ||
Zip::zip_with(self, variance, &a_universal, &b_existential)?; |
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.
Zip::zip_with(self, variance, &a_universal, &b_existential)?; | |
Zip::zip_with(self, Variance::Contravariant, &a_universal, &b_existential)?; |
(And Covariant
below). This is required for the tests I've commented on to give the correct results.
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.
Is Contravariant
here right? I don't think so, since this also covers the Invariant
case.
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.
In the invariant case this if
uses Contravariant
and the other one uses Covariant
. This is required so that T == U
is the same as T <: U
and U <: T
.
Thank you for the comments! We've found and fixed a bug where We haven't looked at the |
chalk-solve/src/infer/unify.rs
Outdated
let a_universal = self.table.instantiate_binders_universally(interner, a); | ||
let b_existential = self.table.instantiate_binders_existentially(interner, b); | ||
Zip::zip_with(self, &a_universal, &b_existential)?; | ||
Zip::zip_with(self, variance, &a_universal, &b_existential)?; |
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.
Is Contravariant
here right? I don't think so, since this also covers the Invariant
case.
tests/test/subtype.rs
Outdated
} yields { | ||
"Unique;substitution [], lifetime constraints [\ | ||
InEnvironment { environment: Env([]), goal: '!1_0: '!1_1 }, \ | ||
InEnvironment { environment: Env([]), goal: '!1_1: '!1_0 }]" |
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.
But these are? This just says that 'a == 'b
23f4ebb
to
7474fd4
Compare
We found another bug, which was caused by inconsistent use of We also applied the code quality suggestions Jack Huey made, and removed some duplicate tests. Additionally, we looked at the constraints emitted by |
The lifetime variance was correct as it was. It is a bit strange that |
I reverted the lifetime variance change and made |
☔ The latest upstream changes (presumably #650) made this pull request unmergeable. Please resolve the merge conflicts. Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:
|
r=me but it needs a rebase! |
Merge of the following 17 commits by Jack Huey: Remove Zip impl for Substitution and add zip_substs Add unification database fn_def_variance and adt_variance Use actual variances when zipping Introduce FnSubst to wrap Fn subst logic Just use self.variance WIP begin adding subtypegoal Pass ambient variance to zip_substs no with_local_variance, instead zip_with calls xform Relate alias to ty rename unify to relate Start adding subtype tests Fail if trying to subtype to inference vars Use Variances not Vec<Variance> Some renames Review comments
This implements the rough equivalent of the rustc Generalizer in the chalk variance code. This needs significant refactoring, and does not yet pass all tests, however it implements all core functionality. We don't fully understand the Generalizer, and this thus most likely contains errors. Co-authored-by: Super Tuple <supertuple@gmail.com>
Co-authored-by: David Ross <daboross@daboross.net>
Added tests that verify that the generalizer works and outputs the correct constraints, and tests that verify variance is being handled correctly. Co-authored-by: David Ross <daboross@daboross.net>
This changes NormalizeDeep to normalize unified inference variables without values to the same 'root' inference variable, and fixes the normalize_deep::test::infer test. The change is necessary to accomodate the generalizer, which commonly creates new inference variables and then unifies them with old ones. This has no functional change, but would have broken normalization without this new behavior. Co-authored-by: David Ross <daboross@daboross.net>
These are just a few test cases not tested. Co-authored-by: David Ross <daboross@daboross.net>
These mirror the test cases we just added, but relating directly to an InferenceVar so that we directly test the generalizer dealing with recursing into each type. Co-authored-by: David Ross <daboross@daboross.net>
Co-authored-by: David Ross <daboross@daboross.net>
Tuples should always be covariant over their inner types. Co-authored-by: David Ross <daboross@daboross.net>
relate_ty_ty was ignoring the order in which the var and ty were passed in when matching a var and a ty. This mean't if the var was passed in second, the variance would be incorrectly inverted because the parameters were swapped around. We fixed this by inverting the variance if the var is on the right side, and added a test case for the issue. We also had to switch the order we pass the value + generalized value into relate_ty_ty, since the previous incorrect ordering was hidden by the bug. Co-authored-by: David Ross <daboross@daboross.net>
This addresses a previous TODO comment asking for further explanation with said further explanation. Co-authored-by: David Ross <daboross@daboross.net>
Expanding on our earlier bugfix, we've added additional tests where the generalized inference var is on the left side. This will help catch any bugs where the variance or the parameters inadvertantly get flipped. Co-authored-by: David Ross <daboross@daboross.net>
The code that relates Adt's was using `push_lifetime_outlives_goals` in a way that assumed it would push a outlives b when the variance is covariant. The code that relates two references assumed that it would push a constraint b outlives a when the variance was covariant. This latter behavior was what the function actually did, despite its name implying the opposite. This commit changes the behavior of `push_lifetime_outlives_goals` to push a outlives b when the variance is covariant, and updates the code that relates references. We also updated an incorrect test case where a reference was used in a struct. This test case would have failed (because `push_lifetime_outlives_goals` was inverted), but the constraints in the expected output were also incorrectly inverted. The output of two additional test cases also were updated because the constraints were emitted in a different order after making the update. Co-authored-by: David Ross <daboross@daboross.net>
Refactored some of the logic for relating inference vars with types into `relate_var_ty`. This allowed us to massively simplify the code in `relate_ty_ty` that calls `relate_var_ty`. Co-authored-by: David Ross <daboross@daboross.net>
This test was originally unique, but we accidentally duplicated it with tests now in subtype.rs. Further, when attempting to fix PR comments on this test, we actually fixed them on the other tests. Co-authored-by: David Ross <daboross@daboross.net>
This reverts commit d5b0ffc.
3ed4270
to
dfb510a
Compare
@bors r=nikomatsakis |
📌 Commit dfb510a has been approved by |
☀️ Test successful - checks-actions |
This contains @super-tuple and my work on rebasing @jackh726's variance work from #520 and implementing the generalizer on top of it.
As mentioned in Zulip, we've been trying to port rustc tests for the generalizer to chalk, in an effort to see what fails. Since we've been failing at this for so long, we decided to just try to write the generalizer instead! We don't fully understand it, but have enough of an idea to write something that hopefully works.
This fails 5 of the existing tests, and that's part of the motivation for opening this now - we aren't sure how to proceed on those. We have not written any new tests for variance nor the generalizer.
The last one we've debugged is
dyn_lifetime_bound
, which fails because when unifying our generalized value and the original ty value, the code tries to unify a inference var with universe 4, created freshly for our generalized value, with a placeholder with universe 6 - and that fails to pass theOccursCheck
. Here's the debug logs we generated for that failed test: https://gist.github.com/daboross/24f1d2310bd86e1d542678c4ebd550e0