Skip to content

[ty] Narrow later match cases after always-true guards - #28960

Merged
AlexWaygood merged 8 commits into
mainfrom
alex/always-true-match-guards
Oct 1, 2026
Merged

AlexWaygood merged 8 commits into
mainfrom
alex/always-true-match-guards

Conversation

@AlexWaygood

@AlexWaygood AlexWaygood commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Summary

ty currently retains values matched by an earlier match case whenever that case has a guard, even if the guard is statically true. This can make later pattern captures too broad and leave impossible cases appearing reachable.

This PR changes our inference so that we treat a pattern whose guard is statically true like an unguarded pattern when narrowing later cases, including enum-pattern reachability. False and ambiguous guards remain conservative. Guard truthiness uses the existing condition analysis, including its conservative recovery for inference cycles.

On its own, this isn't a particularly important change, but codex was worried that analyzing reachability of match patterns without this change would lead to false positives/negatives when it came to adding a check that would complain about non-exhaustive match statements. I'm therefore separating this into a standalone change that can be merged first.

A naive implementation of this PR led to hangs (and eventual panics, if the script was left for a very long time) on three py-fuzzer seeds. Some changes were therefore required to reachability.rs to tweak which queries we cache and which we don't. Happily, this PR appears to have the side effect of significantly speeding up one of our microbenchmarks following those tweaks.

@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Sep 28, 2026
@astral-sh-bot

astral-sh-bot Bot commented Sep 28, 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.

@astral-sh-bot

astral-sh-bot Bot commented Sep 28, 2026

Copy link
Copy Markdown

Memory usage report

Memory usage unchanged ✅

@astral-sh-bot

astral-sh-bot Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

ecosystem-analyzer results

No diagnostic changes detected ✅

Flaky changes detected. This PR summary excludes flaky changes; see the HTML report for details.

Full report with detailed diff (timing results)

@codspeed

codspeed Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 8.63%

⚡ 1 improved benchmark
✅ 161 untouched benchmarks
⏩ 60 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ Simulation ty_micro[large_union_narrowing] 517 ms 475.9 ms +8.63%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing alex/always-true-match-guards (6f12c13) with main (00dda0e)

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

@AlexWaygood
AlexWaygood force-pushed the alex/always-true-match-guards branch from 34f299c to 4de227b Compare September 30, 2026 11:01
@AlexWaygood
AlexWaygood marked this pull request as ready for review September 30, 2026 15:56
@AlexWaygood
AlexWaygood requested a review from a team as a code owner September 30, 2026 15:56
@astral-sh-bot
astral-sh-bot Bot requested a review from dcreager September 30, 2026 15:57
@carljm
carljm requested review from carljm and removed request for dcreager September 30, 2026 19:17
@sharkdp
sharkdp requested review from sharkdp and removed request for carljm October 1, 2026 10:30

@sharkdp sharkdp left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. This makes a lot of sense to me.

After reading the PR description I was expecting to see a test case like the following, but that seems too ambitious. Probably requires additional changes to narrowing?

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

class Answer(Enum):
    NO = 0
    YES = 1

def _(color: Color, answer: Answer):
    match color:
        case Color.RED if answer is Answer.NO:
            x = 0
        case Color.RED if answer is Answer.YES:  # always true guard
            x = 1
        case Color.RED:
            x = 2  # unreachable
        case _:
            x = 3

    reveal_type(x)  # Literal[0, 1, 2, 3] on your branch, excluding 2 would be nice

Comment on lines +709 to +711
class Color(Enum):
RED = 1
BLUE = 2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deeply disappointed that you didn't pick up my

class Answer(Enum):
    NO = 0
    YES = 1

pattern.

Comment thread crates/ty_python_semantic/resources/mdtest/conditional/match.md Outdated
Comment thread crates/ty_python_semantic/resources/mdtest/narrow/match.md Outdated
@AlexWaygood

Copy link
Copy Markdown
Member Author

After reading the PR description I was expecting to see a test case like the following, but that seems too ambitious. Probably requires additional changes to narrowing?

That would be very cool indeed, but yes, I think it's too ambitious for now

@AlexWaygood
AlexWaygood force-pushed the alex/always-true-match-guards branch from 19c5bb4 to 6f12c13 Compare October 1, 2026 11:29
@AlexWaygood
AlexWaygood enabled auto-merge (squash) October 1, 2026 11:30
@AlexWaygood
AlexWaygood merged commit 8b90665 into main Oct 1, 2026
72 checks passed
@AlexWaygood
AlexWaygood deleted the alex/always-true-match-guards branch October 1, 2026 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants