Skip to content

[ty] Avoid redundant constraint saturation work#25786

Open
charliermarsh wants to merge 1 commit into
charlie/fix-dynamic-constraint-explosionfrom
charlie/optimize-constraint-saturation
Open

[ty] Avoid redundant constraint saturation work#25786
charliermarsh wants to merge 1 commit into
charlie/fix-dynamic-constraint-explosionfrom
charlie/optimize-constraint-saturation

Conversation

@charliermarsh

@charliermarsh charliermarsh commented Jun 9, 2026

Copy link
Copy Markdown
Member

Summary

The constraint-set subtype checks introduced in #25778 can be repeated many times while saturating pairs of constraints. On pytest-robotframework, that increased median check time from 105.8 ms on main to 159.9 ms with #25778.

This caches those checks for the lifetime of a constraint-set builder.

As a separate, semantics-preserving optimization, this also skips calling add_nested_typevar_sequents when neither constraint has a type variable in its bounds. In that case, the method cannot derive any sequents: all of its variance checks return Bivariant. The precheck visits lazy types to match the traversal performed by variance_of.

With this change, pytest-robotframework takes 108.5 ms, 2.6% above main, with byte-for-byte identical diagnostics. The full ty_python_semantic test suite, focused Clippy, and repository hooks pass.

@astral-sh-bot astral-sh-bot Bot added the ty Multi-file analysis & type inference label Jun 9, 2026
@astral-sh-bot

astral-sh-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown

Typing conformance results

No changes detected ✅

Current numbers
The percentage of diagnostics emitted that were expected errors held steady at 92.23%. The percentage of expected errors that received a diagnostic held steady at 87.42%. The number of fully passing files held steady at 92/134.

@astral-sh-bot

astral-sh-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown

Memory usage report

Summary

Project Old New Diff Outcome
flake8 35.38MB 35.36MB -0.06% (21.05kB) ⬇️
trio 87.75MB 87.70MB -0.06% (55.20kB) ⬇️
sphinx 207.56MB 207.16MB -0.19% (404.17kB) ⬇️
prefect 563.95MB 562.42MB -0.27% (1.52MB) ⬇️

Significant changes

Click to expand detailed breakdown

flake8

Name Old New Diff Outcome
StaticClassLiteral<'db>::variance_of_::interned_arguments 11.67kB 5.70kB -51.20% (5.98kB) ⬇️
Type<'db>::is_constraint_set_subtype_of_::interned_arguments 0.00B 5.16kB +5.16kB (new) ⬇️
when_constraint_set_assignable_to_owned_impl 159.03kB 153.99kB -3.17% (5.04kB) ⬇️
StaticClassLiteral<'db>::variance_of_ 9.19kB 4.52kB -50.77% (4.66kB) ⬇️
Type<'db>::is_constraint_set_subtype_of_ 0.00B 4.41kB +4.41kB (new) ⬇️
is_possibly_constraint_set_assignable 28.17kB 24.80kB -11.98% (3.38kB) ⬇️
infer_definition_types 1.57MB 1.57MB -0.19% (3.12kB) ⬇️
infer_expression_types_impl 974.41kB 972.36kB -0.21% (2.05kB) ⬇️
GenericAlias<'db>::variance_of_ 3.49kB 1.62kB -53.69% (1.88kB) ⬇️
GenericAlias<'db>::variance_of_::interned_arguments 3.23kB 1.48kB -54.35% (1.76kB) ⬇️
infer_scope_types_impl 788.72kB 787.30kB -0.18% (1.42kB) ⬇️
assignable_solutions_impl 18.12kB 16.77kB -7.50% (1.36kB) ⬇️
infer_statement_types_impl 39.98kB 40.29kB +0.76% (312.00B) ⬇️
function_known_decorators 146.02kB 145.85kB -0.11% (168.00B) ⬇️
try_call_bin_op_return_type_impl 6.24kB 6.12kB -1.88% (120.00B) ⬇️

trio

Name Old New Diff Outcome
Type<'db>::is_constraint_set_subtype_of_::interned_arguments 0.00B 14.95kB +14.95kB (new) ⬇️
Type<'db>::is_constraint_set_subtype_of_ 0.00B 12.20kB +12.20kB (new) ⬇️
StaticClassLiteral<'db>::variance_of_::interned_arguments 26.37kB 14.62kB -44.53% (11.74kB) ⬇️
when_constraint_set_assignable_to_owned_impl 401.74kB 390.97kB -2.68% (10.77kB) ⬇️
is_possibly_constraint_set_assignable 88.48kB 77.87kB -11.99% (10.61kB) ⬇️
GenericAlias<'db>::variance_of_ 16.27kB 6.14kB -62.25% (10.12kB) ⬇️
StaticClassLiteral<'db>::variance_of_ 20.27kB 11.16kB -44.97% (9.12kB) ⬇️
infer_definition_types 6.61MB 6.60MB -0.13% (8.95kB) ⬇️
GenericAlias<'db>::variance_of_::interned_arguments 15.54kB 6.96kB -55.20% (8.58kB) ⬇️
infer_expression_types_impl 6.57MB 6.57MB -0.11% (7.54kB) ⬇️
assignable_solutions_impl 44.16kB 42.27kB -4.27% (1.89kB) ⬇️
try_call_bin_op_return_type_impl 46.30kB 45.48kB -1.77% (840.00B) ⬇️
infer_scope_types_impl 3.78MB 3.77MB -0.02% (828.00B) ⬇️
all_narrowing_constraints_for_expression 1012.84kB 1012.24kB -0.06% (612.00B) ⬇️
member_lookup_with_policy_inner 1.42MB 1.41MB -0.04% (568.00B) ⬇️
... 18 more

sphinx

Name Old New Diff Outcome
infer_expression_types_impl 20.49MB 20.39MB -0.46% (95.67kB) ⬇️
infer_definition_types 20.72MB 20.65MB -0.38% (80.30kB) ⬇️
when_constraint_set_assignable_to_owned_impl 1.50MB 1.44MB -3.77% (57.80kB) ⬇️
Type<'db>::is_constraint_set_subtype_of_::interned_arguments 0.00B 51.30kB +51.30kB (new) ⬇️
Type<'db>::is_constraint_set_subtype_of_ 0.00B 48.11kB +48.11kB (new) ⬇️
is_possibly_constraint_set_assignable 262.36kB 223.14kB -14.95% (39.22kB) ⬇️
GenericAlias<'db>::variance_of_ 49.03kB 12.96kB -73.57% (36.07kB) ⬇️
function_known_decorators 973.05kB 939.45kB -3.45% (33.60kB) ⬇️
GenericAlias<'db>::variance_of_::interned_arguments 44.65kB 13.85kB -68.98% (30.80kB) ⬇️
StaticClassLiteral<'db>::variance_of_::interned_arguments 46.27kB 16.52kB -64.29% (29.74kB) ⬇️
infer_deferred_types 3.88MB 3.86MB -0.65% (26.05kB) ⬇️
StaticClassLiteral<'db>::variance_of_ 39.09kB 14.81kB -62.11% (24.28kB) ⬇️
assignable_solutions_impl 187.67kB 167.64kB -10.67% (20.03kB) ⬇️
infer_scope_types_impl 12.55MB 12.53MB -0.14% (17.85kB) ⬇️
try_call_bin_op_return_type_impl 201.35kB 196.08kB -2.62% (5.27kB) ⬇️
... 25 more

prefect

Name Old New Diff Outcome
infer_definition_types 75.87MB 75.21MB -0.86% (669.80kB) ⬇️
infer_expression_types_impl 55.21MB 54.75MB -0.82% (465.55kB) ⬇️
infer_scope_types_impl 47.64MB 47.48MB -0.34% (164.27kB) ⬇️
Type<'db>::is_constraint_set_subtype_of_::interned_arguments 0.00B 116.10kB +116.10kB (new) ⬇️
GenericAlias<'db>::variance_of_ 136.20kB 24.45kB -82.05% (111.75kB) ⬇️
Type<'db>::is_constraint_set_subtype_of_ 0.00B 99.28kB +99.28kB (new) ⬇️
GenericAlias<'db>::variance_of_::interned_arguments 116.79kB 28.05kB -75.98% (88.73kB) ⬇️
when_constraint_set_assignable_to_owned_impl 3.01MB 2.95MB -2.29% (70.68kB) ⬇️
is_possibly_constraint_set_assignable 593.09kB 535.98kB -9.63% (57.11kB) ⬇️
StaticClassLiteral<'db>::variance_of_::interned_arguments 89.93kB 38.18kB -57.54% (51.75kB) ⬇️
StaticClassLiteral<'db>::variance_of_ 78.77kB 36.99kB -53.04% (41.78kB) ⬇️
function_known_decorators 3.92MB 3.90MB -0.69% (27.79kB) ⬇️
assignable_solutions_impl 319.27kB 295.95kB -7.30% (23.32kB) ⬇️
infer_statement_types_impl 878.18kB 900.71kB +2.57% (22.54kB) ⬇️
infer_deferred_types 8.75MB 8.74MB -0.14% (12.73kB) ⬇️
... 24 more

@astral-sh-bot

astral-sh-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

No diagnostic changes detected ✅

Full report with detailed diff (timing results)

@charliermarsh charliermarsh added the performance Potential performance improvement label Jun 9, 2026
@charliermarsh charliermarsh force-pushed the charlie/fix-dynamic-constraint-explosion branch from 28d7fdb to be0c908 Compare June 9, 2026 16:54
@charliermarsh charliermarsh force-pushed the charlie/optimize-constraint-saturation branch from c433edc to 294e3f1 Compare June 9, 2026 16:56
@charliermarsh charliermarsh marked this pull request as ready for review June 9, 2026 16:56
Comment thread crates/ty_python_semantic/src/types/constraints.rs Outdated
Comment thread crates/ty_python_semantic/src/types/constraints.rs Outdated
@charliermarsh charliermarsh force-pushed the charlie/fix-dynamic-constraint-explosion branch from be0c908 to ab9db7e Compare June 9, 2026 20:01
@charliermarsh charliermarsh force-pushed the charlie/optimize-constraint-saturation branch from 294e3f1 to d249349 Compare June 9, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Potential performance improvement ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants