Pattern-matching test coverage (matching.ml / parmatch.ml)#4
Draft
JonoPrest wants to merge 8 commits into
Draft
Conversation
First batch of fixtures targeting uncovered branches in compiler/ml/matching.ml (pattern compilation to lambda). Covers `combine_constant` across every constant kind, each routed to a distinct compilation strategy: - Const_int -> call_switcher (interval edges, holes, negatives) - Const_char -> call_switcher - Const_float -> make_test_sequence with Pfloatcomp - Const_bigint -> make_test_sequence with Pbigintcomp Runtime-asserted via Mocha so the suite stays portable across alternative bsc implementations. Signed-off-by: Jono Prest <jono@envio.dev> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ts, records, arrays, or-patterns)
Second batch of portable runtime-behavior fixtures targeting uncovered
branches in compiler/ml/matching.ml:
- constructors: exhaustive variant Lswitch, extension/exception
constructors (Pextension_slot_eq), unboxed single constructor
- polyvariant: const + block tags (Pis_poly_var_block split, both
variant switchers)
- record/tuple: field projection, mutable fields, `if` guards
- array: dispatch by length
- or-patterns: constant-constructor or, shared-variable or-binding,
or-patterns inside tuple columns (explode_or_pat / precompile_or)
All matches exhaustive (warning-clean under -warn-error A); 942 mocha
tests pass.
Signed-off-by: Jono Prest <jono@envio.dev>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Apply `make format` to pattern_match_array_test.res and commit the generated .mjs for all pattern-match fixtures, matching the repo convention of checking in tests/tests compiled output. Signed-off-by: Jono Prest <jono@envio.dev> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
float/bigint/char matches now have >= 4 cases, so make_test_sequence exercises split_sequence/cut (the binary-search comparison tree in matching.ml) rather than only the flat comparison chain. Signed-off-by: Jono Prest <jono@envio.dev> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ines) Add tests/PATTERN_MATCHING_COVERAGE.md cataloguing, for matching.ml and parmatch.ml, which uncovered lines are structurally unreachable (dead OCaml-bytecode string-search tree, int32/64 asserts, `when false` guards, `if dbg` debug printers, defensive fatal_error/assert) versus reachable-but-cold edges worth fixtures (witness pretty-printers, All_clauses_guarded, lub, dichotomic comparison split, partial-match failaction paths). Companion to ERROR_VARIANTS.md. Signed-off-by: Jono Prest <jono@envio.dev> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Target parmatch.ml analysis paths and matching.ml partial-match
compilation via non-exhaustive / redundant matches:
- non_exhaustive_{tuple,list,record,variant,polyvariant,array}: drive
the per-shape witness pretty-printers (pretty_val) that render the
"you forgot to handle" counter-example
- non_exhaustive_{int,char,string,float,bigint}: drive pretty_const
for each scalar witness
- all_clauses_guarded: Warnings.All_clauses_guarded
- redundant_or_branch: Upartial (partially-redundant or-pattern)
- overlapping_or_lub: least-upper-bound of overlapping or-branches
Snapshots generated via `node input.js update`; verify run passes.
Signed-off-by: Jono Prest <jono@envio.dev>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cross-reference PATTERN_MATCHING_COVERAGE.md and the new non_exhaustive_* / redundancy fixtures from the Warnings section of ERROR_VARIANTS.md; apply `make format` to the constants fixture comment. Signed-off-by: Jono Prest <jono@envio.dev> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ess printer Direct per-fixture BISECT_FILE measurement showed parmatch.ml's pretty_val/pretty_const family (~364-434) stays cold even when a non-exhaustive witness prints: the user-facing witness is rendered by Pattern_printer.print_pattern (compiler/common, already ~88% covered), not by these debug printers. Move them to the dead-code table. Also record the measured contribution of this PR's fixtures (~10 lines in matching.ml from the dichotomic split, ~5 in parmatch.ml from All_clauses_guarded/Upartial) and note the matching.ml partial-match paths remain cold (simple non-exhaustive matches don't reach them). Signed-off-by: Jono Prest <jono@envio.dev> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Goal
Lift test coverage of the two most central, correctness-critical pattern-matching files in the compiler, using portable
.resfixtures so alternativebscimplementations can run the same suite.Baseline (fresh
make coverageoffmaster):compiler/ml/matching.ml— 72.6% (pattern → lambda compilation)compiler/ml/parmatch.ml— 75.6% (exhaustiveness / redundancy analysis)Approach
Split by what's portable:
matching.ml→ runtime-behavior fixtures intests/tests/src/*_test.res(Mochaeq(__LOC__, …)), fully implementation-agnostic. Compiles under-warn-error A, so all matches are exhaustive.parmatch.ml→ warning snapshots intests/build_tests/super_errors/(these also emit JS, so they exercisematching.mlpartial-match paths too).Targets were derived from line-level coverage + reading the source, excluding genuinely unreachable branches (e.g.
expand_stringswitch— the JS backend emitsLstringswitchinstead;Const_int32/64assert false;when falseguards;if dbgdebug code). Those will be documented as unreachable rather than chased.Planned fixture matrix
matching.mlbehavior (tests/tests/src/)pattern_match_constants_test—combine_constant: int/char (call_switcher), float/bigint (make_test_sequence)pattern_match_intswitch_test— dense vs sparse int intervals (edges/holes)pattern_match_constructors_test— variant arity 0/1/N, unboxed, extension constructorspattern_match_polyvariant_test— const-tag + block-tag polymorphic variantspattern_match_record_tuple_test— immutable/mutable/optional-field/inlined records, tuplespattern_match_array_test— match by lengthpattern_match_orpat_test— nested or-patterns, or-pats binding vars / under constructorsparmatch.mlanalysis (super_errors/)lub(w11)super_errors_multi/)Draft — pushing fixtures incrementally. Coverage lift will be re-measured at the end.
🤖 Generated with Claude Code