Skip to content

fix: report unreachable match case after earlier sibling pattern - #5515

Open
bniladridas wants to merge 1 commit into
meta:mainfrom
bniladridas:investigate/3338-match-subsumption-v3
Open

bniladridas wants to merge 1 commit into
meta:mainfrom
bniladridas:investigate/3338-match-subsumption-v3

Conversation

@bniladridas

@bniladridas bniladridas commented Nov 4, 2026 •

Copy link
Copy Markdown

Summary

Fixes #3338.

Any was short-circuited in match-case reachability, so case bool() after case int() was never reported. Narrowing by the current class pattern first, then applying earlier unguarded case negations, reuses the existing narrowing and subtraction path: Any becomes bool, then bool minus int is Never.

This supersedes the closed #5201 approach. It removes the second sibling-subsumption check, the separate class extraction, and the prev_case_ops vector. The binder passes one earlier negation separately, and reachability applies the current pattern before that negation.

Scope

  • detect match case branch subclass #3338 is limited to Any. object keeps the existing early return because structural patterns such as tuples can narrow object to Never spuriously.
  • Partial class patterns are covered for the no-false-positive case, for example case A(x=1) does not subsume case B(). Existing reachability also does not report duplicate partial-class patterns on precise subjects, so positive detection is tracked separately in Report unreachable duplicate partial-class match cases #5516.
  • One projected NarrowOp is cloned because Binding::Narrow and the reachability metadata own separate copies. No vector or class-extraction clone remains.

Test Plan

  • cargo test -p pyrefly pattern_match --quiet: 113 passed, 0 failed.

  • cargo clippy -p pyrefly --lib -- -D warnings: passed.

  • python3 test.py --no-test --no-tensor-shapes --no-conformance --no-jsonschema --no-extension: passed.

  • cargo test -p pyrefly --quiet -- --skip test::cycles::deep_phi_chain_term_expr: 10244 passed, 0 failed, 3 ignored on the rebased origin/main at 10226ec1. That test overflows the default 10 MiB debug stack on clean current origin/main too, so it is unrelated; it passes with PYREFLY_STACK_SIZE=67108864.

  • New regression covers Any int then bool, subclass-first order, guarded predecessor, duplicate literal, Or-pattern, object no-report, and partial-class no-false-positive.

  • I am a human, and I fully understand the code I am submitting.

Narrow by the current case pattern before applying earlier unguarded case negations. This lets an Any subject become its current class first, so subtracting an earlier superclass produces Never and the case is reported unreachable.

Keep object subjects on the existing early return because structural patterns can narrow object to Never spuriously. The check is limited to the Any case tracked by meta#3338.

Signed-off-by: Niladri Das <125604915+bniladridas@users.noreply.github.com>
@meta-codesync

meta-codesync Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

This pull request has been imported. If you are a Meta employee, you can view this in D129509393. (Because this pull request was imported automatically, there will not be any future comments.)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

detect match case branch subclass

1 participant