[ty] Inform literal promotion with variance of inferred argument types#22322
[ty] Inform literal promotion with variance of inferred argument types#22322ibraheemdev wants to merge 5 commits intomainfrom
Conversation
Diagnostic diff on typing conformance testsNo changes detected when running ty on typing conformance tests ✅ |
|
CodSpeed Performance ReportMerging this PR will degrade performance by 52.98%Comparing Summary
Performance Changes
Footnotes
|
f5cfc73 to
e169795
Compare
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
invalid-argument-type |
16 | 9 | 63 |
invalid-return-type |
3 | 12 | 7 |
invalid-assignment |
0 | 6 | 7 |
possibly-missing-attribute |
11 | 1 | 1 |
unresolved-attribute |
0 | 11 | 0 |
unused-ignore-comment |
0 | 2 | 0 |
no-matching-overload |
0 | 1 | 0 |
redundant-cast |
1 | 0 | 0 |
unsupported-operator |
0 | 0 | 1 |
| Total | 31 | 42 | 79 |
8268bc6 to
06f17fd
Compare
e046945 to
fba4ac1
Compare
|
There seems to be some subtle changes in the ecosystem that I have yet to look into, but I think this is ready for an initial review. The overall problem that this is trying to solve is: if we infer a type variable The approach taken in this PR transforms the formal and actual types to contain synthetic type variables and recursing one generic layer at a time, keeping track of the variance of the inferred type along the way. This is very similar to how we perform reverse inference. Alternatively, we might be able to transform the actual type such that each type is uniquely identified, e.g., wrapping each type in a synthetic type alias?. This seems to have a quite significant performance and memory usage impact (though there are some optimizations that could be made here), but I'm wondering if there's a simpler approach that I am missing. |
|
|
||
| # TODO: we should avoid literal promotion here. | ||
| # error: [invalid-argument-type] "Argument to function `f12` is incorrect: Expected `(int, /) -> None`, found `def takes_literal[T](x: Literal[1]) -> Unknown`" | ||
| reveal_type(f12(takes_literal)) # revealed: Invariant[int] | None |
There was a problem hiding this comment.
This is a regression from main because we don't currently support the synthetic type mapping on Callable types, but this shouldn't be too hard to fix.
|
@dcreager I wonder if you can take a look at this? |
…23107) Updates our literal promotion heuristics to only promote implicitly inferred literal values, i.e., literal values inferred without an explicit literal annotation. This requires us to track promotability on the literal value type itself, and so a lot of the changes here are churn from having to split the literal value variants of `Type` into a separate `LiteralValue` type. Another consequence of this change is that the same literal value does not compare equal in its promotable and unpromotable form, so there are a few cases where we relied on type equality (or hashing) that need to be changed. Resolves astral-sh/ty#2664, astral-sh/ty#1815, and supersedes #22322.
Summary
This also indirectly implements #21905. Similar how to we perform reverse inference, we can perform regular inference by recursing one generic layer at a time, and keep track of the variance manually.
Resolves astral-sh/ty#1815.