[ty] Use partial-order-friendly representation of typevar constraints#20306
Merged
[ty] Use partial-order-friendly representation of typevar constraints#20306
Conversation
Contributor
Diagnostic diff on typing conformance testsNo changes detected when running ty on typing conformance tests ✅ |
Contributor
|
carljm
approved these changes
Sep 8, 2025
Contributor
carljm
left a comment
There was a problem hiding this comment.
Looks reasonable!
I'm sure if I tell you that all this math seems well-suited to a nice unit test suite, it won't be the first you've thought of it ;)
Member
Author
I'm tackling this in a separate PR, #20319 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The constraint representation that we added in #19997 was subtly wrong, in that it didn't correctly model that type assignability is a partial order — it's possible for two types to be incomparable, with neither a subtype of the other. That means the negation of a constraint like
T ≤ t(typevarTmust be a subtype oft) is nott < T, but rathert < T ∨ T ≁ t(using ≁ to mean "not comparable to").That means we need to update our constraint representation to be an enum, so that we can track both range constraints (upper/lower bound on the typevar), and these new incomparable constraints.
Since we need an enum now, that also lets us simplify how we were modeling range constraints. Before, we let the lower/upper bounds be either open (<) or closed (≤). Now, range constraints are always closed, and we add a third kind of constraint for not equivalent (≠). We can translate an open upper bound
T < tintoT ≤ t ∧ T ≠ t.We already had the logic for doing adding clauses to a set by doing a pairwise simplification. We copy that over to where we add constraints to a clause. To calculate the intersection or union of two constraints, the new enum representation makes it easy to break down all of the possibilities into a small number of cases: intersect range with range, intersect range with not-equivalent, etc. I've done the math here to show that the simplifications for each of these cases is correct.