Skip to content

[ty] Preserve recursive aliases when rebuilding intersections - #29057

Open
charliermarsh wants to merge 7 commits into
mainfrom
charlie/ty-3195-recursive-complement
Open

charliermarsh wants to merge 7 commits into
mainfrom
charlie/ty-3195-recursive-complement

Conversation

@charliermarsh

@charliermarsh charliermarsh commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Summary

We avoid panics and hangs when recursive aliases appear in mapped intersections. Both negated and positive aliases retain their identity when the intersection does not need to simplify them. For example, indexing a recursive list containing a complement now yields object:

from ty_extensions import Not

type A = list[Not[A] | A]

def f(x: A):
    reveal_type(x[0])  # object

The same applies when specialization puts a recursive tuple alias into a positive intersection:

from collections.abc import Iterable
from typing import Any, assert_type
from ty_extensions import Intersection

type WithIterable[T] = Intersection[Iterable[Any], T]
type B = tuple[WithIterable[B], ...]

def g(x: B):
    assert_type(x[0], WithIterable[B])

The intersection builder expands set operations for distribution and flattening, then inspects the types behind aliases when simplifying the resulting intersections. This preserves existing rules for object, Never, double negation, truthiness, enums, and gradual generics while avoiding repeated expansion of unchanged recursive aliases. Type comparisons still treat aliased and expanded intersections as equivalent, including those containing gradual types.

The invalid x[] form in the issue now reports a syntax error without panicking.

Closes astral-sh/ty#3195.

@charliermarsh charliermarsh added the ty The ty type checker label Oct 1, 2026
@astral-sh-bot

astral-sh-bot Bot commented Oct 1, 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 98.24%. The percentage of expected errors that received a diagnostic held steady at 98.24%. The number of fully passing files held steady at 134/146.

@charliermarsh charliermarsh added the bug An issue describing something that isn't working, or a PR that fixes a bug label Oct 1, 2026
@astral-sh-bot

astral-sh-bot Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot

astral-sh-bot Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

ecosystem-analyzer results

No diagnostic changes detected ✅

Full report with detailed diff (timing results)

@codspeed

codspeed Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 4.19%

❌ 1 regressed benchmark
✅ 175 untouched benchmarks
⏩ 60 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Simulation ty_micro[gradual_intersection_negation] 1.9 s 2 s -4.19%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing charlie/ty-3195-recursive-complement (9d7b5bb) with main (c33cdaa)

Open in CodSpeed

Footnotes

  1. 60 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. ↩

@charliermarsh
charliermarsh marked this pull request as ready for review October 1, 2026 20:44
@charliermarsh
charliermarsh requested a review from a team as a code owner October 1, 2026 20:44
@astral-sh-bot
astral-sh-bot Bot requested a review from ibraheemdev October 1, 2026 20:44
@charliermarsh charliermarsh changed the title [ty] Preserve unchanged intersections during type mapping [ty] Preserve alias references in mapped negations Oct 1, 2026
@charliermarsh
charliermarsh force-pushed the charlie/ty-3195-recursive-complement branch from 8fdf4c1 to 5e7339c Compare October 5, 2026 14:43
Comment thread crates/ty_python_semantic/src/types/set_theoretic.rs Outdated
@charliermarsh
charliermarsh marked this pull request as draft October 6, 2026 20:16
@charliermarsh
charliermarsh marked this pull request as ready for review October 6, 2026 20:32
@astral-sh-bot
astral-sh-bot Bot requested a review from carljm October 6, 2026 20:32
@charliermarsh
charliermarsh requested review from ibraheemdev and removed request for carljm October 6, 2026 20:35
@charliermarsh
charliermarsh added this pull request to stack #29153 October 6, 2026 20:54
@charliermarsh charliermarsh changed the title [ty] Preserve alias references in mapped negations [ty] Preserve recursive aliases when rebuilding intersections Oct 6, 2026
@charliermarsh
charliermarsh removed this pull request from stack #29153 October 7, 2026 00:09
@charliermarsh
charliermarsh force-pushed the charlie/ty-3195-recursive-complement branch from 064192d to 9d7b5bb Compare October 7, 2026 02:00

This branch was successfully deployed

1 active deployment
automations — 9d7b5bb6 Deployed Oct 7, 2026 by charliermarsh via security-review / security review #90910
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug An issue describing something that isn't working, or a PR that fixes a bug ty The ty type checker

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stack overflow on syntax error indexing of list of recursive typevar union complement

2 participants