Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ty] Avoid bypassing lazy constraints for Divergent#26288

Merged
charliermarsh merged 1 commit into
mainfrom
charlie/fix-divergent-constraint-shortcut
Jun 23, 2026
Merged

[ty] Avoid bypassing lazy constraints for Divergent#26288
charliermarsh merged 1 commit into
mainfrom
charlie/fix-divergent-constraint-shortcut

Conversation

@charliermarsh

Copy link
Copy Markdown
Member

Summary

when_constraint_set_assignable_to_owned avoids entering its tracked Salsa query when a relation appears to be unconditionally satisfied. The shortcut used materialized_divergent_fallback().is_none() to guard the union and intersection cases, but an unmaterialized Divergent marker also has no fallback.

During recursive inference, that allowed the shortcut to return an always-satisfied constraint set for relations such as Divergent to int | Divergent. Lazy constraint-set assignability intentionally handles a top-level Divergent differently, so bypassing the query could admit an inconsistent bound and eventually trigger a debug assertion in constraint solving.

This keeps the exact-equality fast path, but routes every other relation involving a top-level Divergent through the tracked query. It also adds direct coverage for union and dynamic relations alongside the original nested-loop reproducer:

def distance() -> None:
    previous = [0]
    for _ in [0]:
        row = []
        for _ in [0]:
            row.append(previous[0])
        previous = row

Closes astral-sh/ty#3836.

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

astral-sh-bot Bot commented Jun 23, 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 94.37%. The percentage of expected errors that received a diagnostic held steady at 89.00%. The number of fully passing files held steady at 94/134.

@astral-sh-bot

astral-sh-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

Memory usage report

Summary

Project Old New Diff Outcome
prefect 516.14MB 516.30MB +0.03% (162.68kB)
sphinx 193.27MB 193.38MB +0.06% (115.39kB)
flake8 30.74MB 30.75MB +0.03% (8.08kB)
trio 77.50MB 77.51MB +0.00% (3.56kB)

Significant changes

Click to expand detailed breakdown

prefect

Name Old New Diff Outcome
when_constraint_set_assignable_to_owned_impl 2.81MB 2.88MB +2.48% (71.47kB)
when_constraint_set_assignable_to_owned_impl::interned_arguments 570.54kB 637.74kB +11.78% (67.20kB)
is_possibly_constraint_set_assignable 519.61kB 533.60kB +2.69% (13.99kB)
infer_expression_types_impl 55.92MB 55.93MB +0.01% (5.32kB)
infer_definition_types 69.14MB 69.15MB +0.00% (3.26kB)
parsed_module 19.35MB 19.35MB -0.01% (1.53kB)
infer_statement_types_impl 1.51MB 1.51MB +0.07% (1.03kB)
infer_scope_types_impl 38.84MB 38.84MB +0.00% (624.00B)
all_narrowing_constraints_for_expression 6.58MB 6.58MB +0.01% (624.00B)
assignable_solutions_impl 196.78kB 197.25kB +0.24% (480.00B)
member_lookup_with_policy_inner 14.69MB 14.69MB -0.00% (416.00B)
loop_header_reachability 429.25kB 429.53kB +0.07% (288.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_ 1.10MB 1.10MB +0.01% (128.00B)
infer_unpack_types 976.74kB 976.86kB +0.01% (120.00B)
infer_expression_type_impl 385.18kB 385.26kB +0.02% (88.00B)
... 1 more

sphinx

Name Old New Diff Outcome
when_constraint_set_assignable_to_owned_impl 1.38MB 1.43MB +3.62% (51.22kB)
when_constraint_set_assignable_to_owned_impl::interned_arguments 276.63kB 326.30kB +17.96% (49.67kB)
is_possibly_constraint_set_assignable 232.39kB 240.74kB +3.59% (8.34kB)
parsed_module 18.36MB 18.36MB +0.02% (3.53kB)
infer_expression_types_impl 22.98MB 22.98MB +0.01% (1.27kB)
infer_definition_types 19.55MB 19.55MB +0.00% (936.00B)
infer_statement_types_impl 962.59kB 962.80kB +0.02% (216.00B)
try_call_bin_op_return_type_impl 194.14kB 194.02kB -0.06% (120.00B)
UnionType<'db>::from_two_elements_ 182.03kB 182.14kB +0.06% (116.00B)
UnionType<'db>::from_two_elements_::interned_arguments 191.04kB 191.12kB +0.04% (88.00B)
is_possibly_constraint_set_assignable::interned_arguments 165.77kB 165.69kB -0.05% (88.00B)
assignable_solutions_impl 106.64kB 106.71kB +0.07% (72.00B)
all_narrowing_constraints_for_expression 2.70MB 2.70MB +0.00% (72.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_ 781.09kB 781.12kB +0.00% (24.00B)
member_lookup_with_policy_inner 6.10MB 6.10MB +0.00% (24.00B)
... 2 more

flake8

Name Old New Diff Outcome
when_constraint_set_assignable_to_owned_impl 140.74kB 143.73kB +2.13% (2.99kB)
when_constraint_set_assignable_to_owned_impl::interned_arguments 28.45kB 31.37kB +10.27% (2.92kB)
parsed_module 9.77MB 9.77MB +0.01% (1.23kB)
is_possibly_constraint_set_assignable 24.00kB 24.59kB +2.44% (600.00B)
infer_definition_types 1.35MB 1.35MB +0.01% (168.00B)
infer_expression_types_impl 960.80kB 960.88kB +0.01% (72.00B)
infer_statement_types_impl 54.36kB 54.41kB +0.09% (48.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_ 50.61kB 50.63kB +0.05% (24.00B)
member_lookup_with_policy_inner 436.02kB 436.04kB +0.01% (24.00B)
infer_expression_type_impl 15.17kB 15.20kB +0.15% (24.00B)

trio

Name Old New Diff Outcome
parsed_module 15.05MB 15.04MB -0.05% (8.00kB)
when_constraint_set_assignable_to_owned_impl 349.80kB 354.81kB +1.43% (5.01kB)
when_constraint_set_assignable_to_owned_impl::interned_arguments 74.51kB 79.49kB +6.69% (4.98kB)
is_possibly_constraint_set_assignable 71.73kB 72.53kB +1.11% (816.00B)
infer_definition_types 5.59MB 5.59MB +0.01% (312.00B)
infer_expression_types_impl 6.51MB 6.51MB +0.00% (264.00B)
StaticClassLiteral<'db>::implicit_attribute_inner_ 130.57kB 130.62kB +0.04% (48.00B)
member_lookup_with_policy_inner 1.52MB 1.52MB +0.00% (48.00B)
loop_header_reachability 124.46kB 124.50kB +0.04% (48.00B)
infer_expression_type_impl 60.73kB 60.78kB +0.08% (48.00B)
infer_statement_types_impl 56.52kB 56.54kB +0.04% (24.00B)

@astral-sh-bot

astral-sh-bot Bot commented Jun 23, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

No diagnostic changes detected ✅

Full report with detailed diff (timing results)

@charliermarsh charliermarsh marked this pull request as ready for review June 23, 2026 22:34
@charliermarsh charliermarsh requested a review from a team as a code owner June 23, 2026 22:34
@charliermarsh charliermarsh added the bug Something isn't working label Jun 23, 2026
@astral-sh-bot astral-sh-bot Bot requested a review from dcreager June 23, 2026 22:34
@charliermarsh charliermarsh merged commit c0e083e into main Jun 23, 2026
63 checks passed
@charliermarsh charliermarsh deleted the charlie/fix-divergent-constraint-shortcut branch June 23, 2026 22:34
mtshiba added a commit that referenced this pull request Jun 24, 2026
## Summary

#26288 fixed a crash by preventing
`when_constraint_set_assignable_to_owned`
from returning a trivial `always` result for top-level `Divergent`
pairs. The
underlying issue was that the owned fast path and the lazy relation
checker
could disagree: the fast path treated some `Divergent` assignability
checks as
always satisfied, while the lazy relation checker treated top-level
`Divergent`
as never assignable.

This patch resolves the inconsistency in the relation checker instead.
Unmaterialized `Divergent` is assignability-compatible in both eager and
lazy
assignability, while it is still not a subtype of arbitrary types and
still must
not be eliminated by redundancy/union simplification.

With the lazy relation checker aligned with the fast path, we no longer
need the
top-level `Divergent` exclusion in
`is_trivially_constraint_set_assignable_to`.
The regression test from #26288 still passes, and the unit test now
asserts that
constraint-set assignability treats `Divergent` consistently.
## Test Plan

unit test updated
charliermarsh added a commit that referenced this pull request Jun 24, 2026
## Summary

This reverts #26163 and its follow-up changes in #26230, #26246, #26274,
#26275, and #26316.

The recursive nominal-growth recovery replaces a previous cycle result
nested inside a specialization with `Divergent`. The follow-up
regressions show that this local replacement is not structurally safe:
multi-arm union recovery can lose stable arms, and variadic tuple growth
can continue after replacement. Addressing those cases required
increasingly shape-specific alignment and guards without a general way
to establish correspondence between fixed-point iterations.

This restores the cycle-recovery behavior from before #26163. The direct
self-referential `TypeOf` case and the regression coverage for
astral-sh/ty#3835 and astral-sh/ty#3838 continue to pass without the
heuristic and are retained. We remove only the cases that no longer
converge: `TypeOf` references nested in nominal specializations and the
nested-iterable case from astral-sh/ty#3827. The independent `Divergent`
constraint fixes from #26288 and #26334, including the regression
coverage for astral-sh/ty#3836, are also retained.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Debug-only crash on complex interdependencies between locals

1 participant