[ty] Bind bare generic property receivers in protocol checks#26379
[ty] Bind bare generic property receivers in protocol checks#26379charliermarsh wants to merge 35 commits into
Conversation
Typing conformance resultsThe percentage of diagnostics emitted that were expected errors increased from 94.44% to 94.52%. The percentage of expected errors that received a diagnostic decreased from 90.21% to 90.03%. The number of fully passing files held steady at 95/134. SummaryHow are test cases classified?Each test case represents one expected error annotation or a group of annotations sharing a tag. Counts are per test case, not per diagnostic — multiple diagnostics on the same line count as one. Required annotations (
Test file breakdown1 file altered
False positives removed (1)1 diagnostic
True positives removed (2)2 diagnostics
|
Memory usage reportMemory usage unchanged ✅ |
|
5c6e1ad to
dde5560
Compare
29fd2e9 to
5399dc5
Compare
Merging this PR will degrade performance by 18.18%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | ty_micro[many_protocol_members_mismatch] |
364.3 ms | 801.5 ms | -54.55% |
| ❌ | WallTime | colour_science |
43.3 s | 45.9 s | -5.69% |
| ⚡ | Simulation | DateType |
258 ms | 201.9 ms | +27.78% |
Tip
Investigate this regression with the CodSpeed MCP and your agent.
Comparing charlie/protocol-property-generic-self (5399dc5) with main (f82a36b)2
Footnotes
-
64 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
-
No successful run was found on
charlie/protocol-property-check-2(8f86bcf) during the generation of this report, somain(f82a36b) was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
385851c to
0e47141
Compare
Summary
#25332 checks protocol property getter types covariantly, but it resolves a property accessor to its return type before binding an explicitly generic receiver. For a getter like as
def value(self: T) -> T, the unresolvedTcan make an incompatible property appear to satisfy the protocol.This binds a bare, unbounded accessor-local receiver type variable to the concrete implementing instance before comparing the getter result:
This is intentionally limited to a single non-overloaded getter whose receiver annotation is exactly one unbounded, unconstrained type variable bound by that accessor. Bounded or constrained type variables, nested receiver annotations such as
Box[T], overloaded getters, generic setters, and protocol-to-protocol generic receiver relations remain unsupported and are rejected conservatively, so valid programs using those forms may still be rejected. Broader support should reuse a receiver-aware callable abstraction rather than adding a second generic solver inside protocol checking; the lazy receiver binding discussed in astral-sh/ty#1172 is the likely shared foundation.