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

Skip to content

[ty] Avoid redundant equality intersections#26057

Merged
charliermarsh merged 1 commit into
mainfrom
charlie/avoid-redundant-equality-intersections
Jun 17, 2026
Merged

[ty] Avoid redundant equality intersections#26057
charliermarsh merged 1 commit into
mainfrom
charlie/avoid-redundant-equality-intersections

Conversation

@charliermarsh

Copy link
Copy Markdown
Member

Summary

This restores the dynamic-only guard when applying removed union arms as negative constraints during equality narrowing. Static alternatives have already been narrowed individually, so intersecting every surviving arm with the removed set creates redundant intersection types that compound across repeated fallthrough narrowing.

Dynamic alternatives still need those negative constraints to preserve the branch predicate. Keeping that distinction avoids the guarded-Any equality benchmark regression introduced by 4e7ab3ac6c without changing narrowing behavior. The targeted benchmark showed that removing the guard increased runtime by about 33% locally.

The full ty_python_semantic suite, Clippy with warnings denied, and file-scoped hooks pass.

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

astral-sh-bot Bot commented Jun 16, 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 16, 2026

Copy link
Copy Markdown

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot

astral-sh-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

ecosystem-analyzer results

No diagnostic changes detected ✅

Full report with detailed diff (timing results)

@codspeed-hq

codspeed-hq Bot commented Jun 16, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 13.78%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
✅ 69 untouched benchmarks
⏩ 64 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation ty_micro[literal_equality_fallthrough_guarded_any] 161.6 ms 130.9 ms +23.48%
Memory ty_micro[literal_equality_fallthrough_guarded_any] 13 MB 12.4 MB +4.84%

Tip

Curious why this is faster? Use the CodSpeed MCP and ask your agent.


Comparing charlie/avoid-redundant-equality-intersections (fdfd4d8) with main (870fc14)

Open in CodSpeed

Footnotes

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

@charliermarsh charliermarsh force-pushed the charlie/revive-equality-narrowing branch from 0ac18a4 to 80a0a61 Compare June 16, 2026 23:48
Base automatically changed from charlie/revive-equality-narrowing to main June 16, 2026 23:53
@charliermarsh charliermarsh force-pushed the charlie/avoid-redundant-equality-intersections branch from a7960d2 to 3949d2d Compare June 16, 2026 23:56
@charliermarsh charliermarsh added the performance Potential performance improvement label Jun 16, 2026
@charliermarsh charliermarsh force-pushed the charlie/avoid-redundant-equality-intersections branch 2 times, most recently from 9305e37 to 65a13dc Compare June 17, 2026 00:18
@charliermarsh charliermarsh marked this pull request as ready for review June 17, 2026 00:20
@charliermarsh charliermarsh requested a review from a team as a code owner June 17, 2026 00:20
@astral-sh-bot astral-sh-bot Bot requested a review from dcreager June 17, 2026 00:20
@charliermarsh

Copy link
Copy Markdown
Member Author

Just gonna merge this in as a fast-follow-up on the previous PR; it's a bit silly but seems not-useless.

@charliermarsh charliermarsh force-pushed the charlie/avoid-redundant-equality-intersections branch from 65a13dc to fdfd4d8 Compare June 17, 2026 00:20
@charliermarsh charliermarsh enabled auto-merge (squash) June 17, 2026 00:20
@charliermarsh charliermarsh merged commit b9ea5d9 into main Jun 17, 2026
59 checks passed
@charliermarsh charliermarsh deleted the charlie/avoid-redundant-equality-intersections branch June 17, 2026 00:42
@AlexWaygood

AlexWaygood commented Jun 17, 2026

Copy link
Copy Markdown
Member

It's nice that this is faster, but unfortunately I don't think this is correct. The premise seems to be that an intersection T & ~U, where U is a Literal type, can only be unsimplifiable if T is a dynamic type. But that doesn't hold true -- there are lots of T & ~U intersections where T is not a dynamic type yet the intersection cannot be simplified, e.g Sequence[str] & ~Literal[""], or T where T is some kind of protocol type, etc. etc.

Sequence[str] & ~Literal[""] takes a different path through equality.rs so isn't actually affected by the fast path you've introduced here, but codex was able to find the following regression as a result of this change:

from enum import Enum
from typing import Literal, TypeVar

from ty_extensions import Not


class Color(Enum):
    RED = 1
    BLUE = 2


T = TypeVar("T")


def accepts_not_red(value: Not[Literal[Color.RED]]) -> None:
    pass


def f(value: T | Literal[Color.RED]) -> None:
    if value == Color.RED:
        return
    accepts_not_red(value)

Prior to this PR, we accepted this code; now, on main, we reject it and report invalid-assignment on the last line because we incorrectly infer value as having type T after the return statement instead of T & ~Color.RED.

I think we should revert this change and add ^that as a regression test.

charliermarsh added a commit that referenced this pull request Jun 17, 2026
## Summary

This reverts the dynamic-only guard added in #26057. Non-dynamic union
arms can still overlap alternatives removed by equality narrowing when
their individual comparison result is ambiguous. For example, after
excluding `Color.RED` from `T | Literal[Color.RED]`, an unconstrained
`T` must remain `T & ~Literal[Color.RED]`; dropping that negative
constraint incorrectly widens the result to `T`.

The regression test covers that fallthrough behavior. This restores the
previous narrowing while we develop a narrower optimization that only
skips constraints for arms proven to take the selected branch.

The focused equality mdtest and file-scoped hooks pass.
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