Skip to content

fix: report unreachable match case subsumed by earlier sibling class pattern - #5201

Open
bniladridas wants to merge 2 commits into
meta:mainfrom
bniladridas:investigate/3338-match-subsumption
Open

bniladridas wants to merge 2 commits into
meta:mainfrom
bniladridas:investigate/3338-match-subsumption

Conversation

@bniladridas

@bniladridas bniladridas commented Oct 11, 2026 •

Copy link
Copy Markdown

Summary

When the match subject is Any or object, narrowing cannot produce Never, so a class pattern already covered by an earlier unguarded sibling case went unreported. This tracks preceding unguarded case ops at bind time and reports at solve time when the current case's class is a subset of their union.

The subject-based check stays authoritative for precise subjects. The sibling check runs only when subject narrowing is silent (Any/object early return) or fails to produce Never.

A later guard skips classes whose base extends Any, so unresolved base classes (for example numba types) do not produce false positives.

Fixes #3338

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

Test Plan

  • cargo test -p pyrefly pattern_match: 112 tests pass, including the new test_match_case_unreachable_subsumed_by_sibling_any_subject covering subsumption on Any, subclass-first ordering, and guarded predecessors.
  • cargo test -p pyrefly: 9068 passed, 0 failed (last full run before the rebase; the change is a one-line guard).
  • cargo clippy -p pyrefly --lib: clean (last run before the rebase).
  • python3 test.py --no-test --no-tensor-shapes --no-conformance --no-jsonschema --no-extension: passes.
  • False-positive repro on an unresolved base class no longer reports unreachable-match-case.

@meta-codesync

meta-codesync Bot commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

This comment has been minimized.

@github-actions github-actions Bot added the stale label Oct 27, 2026
@bniladridas
bniladridas force-pushed the investigate/3338-match-subsumption branch from 6c269ae to 2333cb5 Compare October 27, 2026 00:36
@github-actions github-actions Bot added size/m and removed size/m labels Oct 27, 2026
@bniladridas

Copy link
Copy Markdown
Author

Hi @samwgoldman (Sam Goldman), I've rebased this onto the latest main and re-run the checks (cargo test -p pyrefly pattern_match: 105 passed; cargo clippy -p pyrefly --lib: clean). The change is still scoped to the match-case reachability fix for #3338. Happy to address any feedback when you have a chance. Thanks, Niladri Das (bniladridas).

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown

Diff from mypy_primer, showing the effect of this PR on open source code:

============================================================
SUMMARY
============================================================
Total: +6 new errors, -0 fixed errors
By preset: +6/-0 (default), +6/-0 (strict)

Projects with changes (2):
  jax: +1 -0
  pytensor: +5 -0
============================================================

FULL DIFF DETAILS
------------------------------------------------------------

jax (https://github.com/google/jax)
+ ERROR jax/experimental/mosaic/gpu/dialect_lowering.py:1166:5-1167:63: Case pattern can never match: an earlier case already matches all `CopyPartitionedAttr` values [unreachable-match-case]

pytensor (https://github.com/pymc-devs/pytensor)
+ ERROR pytensor/link/numba/dispatch/sparse/variable.py:340:9-341:49: Case pattern can never match: an earlier case already matches all `CSCMatrixType` values [unreachable-match-case]
+ ERROR pytensor/link/numba/dispatch/sparse/variable.py:362:9-363:49: Case pattern can never match: an earlier case already matches all `CSCMatrixType` values [unreachable-match-case]
+ ERROR pytensor/link/numba/dispatch/sparse/variable.py:428:9-429:49: Case pattern can never match: an earlier case already matches all `CSCMatrixType` values [unreachable-match-case]
+ ERROR pytensor/link/numba/dispatch/sparse/variable.py:571:9-584:28: Case pattern can never match: an earlier case already matches all `CSCMatrixType` values [unreachable-match-case]
+ ERROR pytensor/link/numba/dispatch/sparse/variable.py:626:9-649:27: Case pattern can never match: an earlier case already matches all `CSCMatrixType` values [unreachable-match-case]

…pattern

When the match subject is Any or object, narrowing cannot produce Never, so
a class pattern already covered by an earlier unguarded case went unreported.
Track preceding unguarded case ops at bind time and, at solve time, report
when the current case's class is a subset of their union.

Signed-off-by: Niladri Das <125604915+bniladridas@users.noreply.github.com>
pattern_class_operand now rejects classes whose metadata has_base_any() is true, preventing false unreachable-match-case diagnostics when a base class is unresolved and both siblings extend Any.

Signed-off-by: Niladri Das <125604915+bniladridas@users.noreply.github.com>
@bniladridas
bniladridas force-pushed the investigate/3338-match-subsumption branch from 2333cb5 to 4d3aa06 Compare November 1, 2026 02:18
@github-actions github-actions Bot added size/m and removed size/m labels Nov 1, 2026
Comment thread pyrefly/lib/alt/narrow.rs
let class_ty = classes.pop().expect("checked length above");
if let Type::ClassDef(cls) = class_ty
&& self.get_class_tparams(&cls).is_none()
&& !self.get_metadata_for_class(&cls).has_base_any()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

the added guard skips sibling subsumption for classes that extend Any and fixes the unresolved-base false positive.

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

2 participants