astral-sh
ruff
BlogDocsChangelog

[ty] Fix contravariant type variable bound checking in specialization inference

#22488
Comparing
bxff:fix-ty-2427
(
b9adfa7
) with
main
(
11cc324
)
CodSpeed Performance Gauge
-1%
Untouched
23
Skipped
30

Benchmarks

Skipped (30)

Passed

multithreaded
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
+2%
1.1 s1.1 s
ty_check_file[incremental]
crates/ruff_benchmark/benches/ty.rs::check_file::benchmark_incremental
CodSpeed Performance Gauge
0%
6.1 ms6.1 ms
tanjun
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
0%
2.5 s2.5 s
sympy
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
0%
50.5 s50.6 s
static_frame
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
0%
21 s21 s
altair
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
0%
4.5 s4.6 s
freqtrade
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
0%
7.8 s7.8 s
ty_micro[many_enum_members_2]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_many_enum_members_2
CodSpeed Performance Gauge
-1%
152.2 ms153.1 ms
pandas
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
-1%
62.3 s62.7 s
ty_micro[many_enum_members]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_many_enum_members
CodSpeed Performance Gauge
-1%
122.9 ms123.6 ms
hydra-zen
crates/ruff_benchmark/benches/ty.rs::project::hydra::project
CodSpeed Performance Gauge
-1%
1.2 s1.2 s
ty_check_file[cold]
crates/ruff_benchmark/benches/ty.rs::check_file::benchmark_cold
CodSpeed Performance Gauge
-1%
130.2 ms131.3 ms
ty_micro[many_string_assignments]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_many_string_assignments
CodSpeed Performance Gauge
-1%
77.9 ms78.7 ms
anyio
crates/ruff_benchmark/benches/ty.rs::project::anyio::project
CodSpeed Performance Gauge
-1%
1.2 s1.2 s
ty_micro[many_tuple_assignments]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_many_tuple_assignments
CodSpeed Performance Gauge
-1%
65.5 ms66.3 ms
attrs
crates/ruff_benchmark/benches/ty.rs::project::attrs::project
CodSpeed Performance Gauge
-1%
428 ms433.3 ms
ty_micro[complex_constrained_attributes_3]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_complex_constrained_attributes_3
CodSpeed Performance Gauge
-1%
70.8 ms71.7 ms
ty_micro[many_tuple_assignments]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_tuple_implicit_instance_attributes
CodSpeed Performance Gauge
-1%
67.6 ms68.5 ms
ty_micro[complex_constrained_attributes_2]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_complex_constrained_attributes_2
CodSpeed Performance Gauge
-1%
67.6 ms68.4 ms
ty_micro[complex_constrained_attributes_1]
crates/ruff_benchmark/benches/ty.rs::micro::benchmark_complex_constrained_attributes_1
CodSpeed Performance Gauge
-1%
67.6 ms68.4 ms
pydantic
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
-1%
10 s10.2 s
colour_science
crates/ruff_benchmark/benches/ty_walltime.rs
CodSpeed Performance Gauge
-2%
86.6 s88.1 s
DateType
crates/ruff_benchmark/benches/ty.rs::project::datetype::project
CodSpeed Performance Gauge
-2%
231.4 ms235.8 ms

Commits

Click on a commit to change the comparison range
Base
main
11cc324
-0.74%
[ty] Fix contravariant type variable bound checking in specialization inference ## Summary Correctly handle upper bounds for contravariant type variables during specialization inference. Previously, the type checker incorrectly applied covariant subtyping rules, requiring the actual type to directly satisfy the bound rather than checking for a valid intersection. In contravariant positions, subtyping relationships are inverted. The bug caused valid code like `f(x: Contra[str])` where `f` expects `Contra[T: int]` to be incorrectly rejected, when it should solve `T` to `Never` (the intersection of `int` and `str`). Closes https://github.com/astral-sh/ty/issues/2427 ## Details - Added `is_contravariant()` helper to `TypeVarVariance` in `variance.rs` - Updated `SpecializationBuilder::infer_map_impl` in `generics.rs` to treat bounds and constraints differently based on variance: * Skip immediate `ty <: bound` check for contravariant upper bounds * Flip constraint check to `constraint <: ty` for contravariant positions - Added test case for bounded contravariant type variables in `variance.md` - All 308 mdtest cases pass & 150 ty_python_semantic unit tests pass
b9adfa7
18 hours ago
by bxff
© 2026 CodSpeed Technology
Home Terms Privacy Docs