Support "match only" mode in pattern compilation#421
Support "match only" mode in pattern compilation#421chengluyu wants to merge 39 commits intohkust-taco:hkmc2from
Conversation
# Conflicts: # hkmc2/shared/src/test/mlscript/ups/specialization/SimpleLiterals.mls
hkmc2/shared/src/main/scala/hkmc2/semantics/ups/SplitCompiler.scala
Outdated
Show resolved
Hide resolved
Co-authored-by: Lionel Parreaux <lionel.parreaux@gmail.com>
hkmc2/shared/src/main/scala/hkmc2/semantics/ups/SplitCompiler.scala
Outdated
Show resolved
Hide resolved
# Conflicts: # hkmc2/shared/src/test/mlscript/ups/MatchResult.mls
# Conflicts: # hkmc2/shared/src/test/mlscript/codegen/BlockPrinter.mls # hkmc2/shared/src/test/mlscript/ups/MatchResult.mls # hkmc2/shared/src/test/mlscript/ups/SimpleTransform.mls # hkmc2/shared/src/test/mlscript/ups/TransformFree.mls
hkmc2/shared/src/test/mlscript/ups/transformation/BindingLess.mls
Outdated
Show resolved
Hide resolved
| pi is @compile IncFst | ||
| //│ = true | ||
|
|
||
| pattern Char = (Str as s where s.length is 1) => s |
There was a problem hiding this comment.
Char should probably be a builtin pattern, right? Otherwise, because of the where clause, I guess it won't behave as expected within compiled string patterns with concatenation.
There was a problem hiding this comment.
I placed it into Char.mls for now. When I implement the string compilation later, I will make it a built-in pattern.
There was a problem hiding this comment.
I'm leaving this "unresolved" for reference. We'll still merge the PR.
# Conflicts: # hkmc2/shared/src/main/scala/hkmc2/codegen/Printer.scala # hkmc2/shared/src/test/mlscript/ups/MatchResult.mls
hkmc2/shared/src/test/mlscript/ups/transformation/BindingLess.mls
Outdated
Show resolved
Hide resolved
LPTK
left a comment
There was a problem hiding this comment.
Do you have any tests that shows the IR of a match-only pattern? So we can make sure it doesn't regress later.
Otherwise LGTM, thanks!
|
|
||
| // :sir | ||
| fun toSumPair(t) = if t is (@compile SumPair) as s then s else null |
There was a problem hiding this comment.
| // :sir | |
| fun toSumPair(t) = if t is (@compile SumPair) as s then s else null | |
| // :sir | |
| fun toSumPair(t) = if t is (@compile SumPair) as s then s else null | |
There was a problem hiding this comment.
Why did you close this? You haven't applied the change.
There was a problem hiding this comment.
Pull request overview
This PR extends UPS pattern compilation to support a “match only” result mode, allowing compiled patterns to return booleans (and reuse the original scrutinee as the output) when no transformed output/bindings are required. This reduces generated code size and avoids constructing MatchSuccess/MatchFailure objects in common is @compile P cases, while adding/adjusting diagnostics and updating the test suite accordingly.
Changes:
- Add
ResultModeto UPS pattern compilation and propagate anoutputNeededflag throughSplitCompilerto enable boolean-only matching when safe. - Improve constructor-pattern handling to avoid rebuilding outputs when not needed, and add warnings when extraction-argument transformation results are implicitly discarded.
- Update/add a large set of MLscript tests and compilation examples to reflect new runtime shapes (e.g.
MatchSuccess(..., null)), new warnings/errors, and new match-only behavior.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| hkmc2/shared/src/main/scala/hkmc2/semantics/ups/SplitCompiler.scala | Thread outputNeeded through matching/compilation; choose match-only vs full compilation; add warnings for discarded extraction outputs; refine inaccessible-field diagnostics. |
| hkmc2/shared/src/main/scala/hkmc2/semantics/ups/Compiler.scala | Introduce ResultMode and boolean match-only matcher generation; refactor field matcher plumbing; support transform-free reuse of scrutinee outputs. |
| hkmc2/shared/src/main/scala/hkmc2/semantics/ups/Pattern.scala | Add MatchedClassLike specialized node and preservesOriginalScrutinee analysis; adjust specialization/printing/field collection. |
| hkmc2/shared/src/main/scala/hkmc2/semantics/ucs/TermSynthesizer.scala | Make empty bindings represent as null (and standardize MatchSuccess bindings emission). |
| hkmc2/shared/src/main/scala/hkmc2/semantics/Split.scala | When expanding SimpleSplit, call makeMatchSplit with outputNeeded = false. |
| hkmc2/shared/src/test/mlscript/ups/TransformFree.mls | New test for compiled patterns whose output can reuse the scrutinee when transform-free. |
| hkmc2/shared/src/test/mlscript/ups/transformation/BindingLess.mls | New tests around transformations in subpatterns and match-only behavior. |
| hkmc2/shared/src/test/mlscript/ups/syntax/PatternBody.mls | New/updated diagnostics tests for inaccessible constructor params during rebuild. |
| hkmc2/shared/src/test/mlscript/ups/syntax/MixedParameters.mls | New warning test for implicitly discarded extraction-argument transformations. |
| hkmc2/shared/src/test/mlscript/ups/specialization/SimpleLiterals.mls | Add logging/side-effect tests demonstrating match-only compilation skipping transforms. |
| hkmc2/shared/src/test/mlscript/ups/SimpleTransform.mls | Update IR expectations and add transform side-effect tests in compiled patterns. |
| hkmc2/shared/src/test/mlscript/ups/SimpleConjunction.mls | Add conjunction test ensuring both sides’ transforms run when output is demanded. |
| hkmc2/shared/src/test/mlscript/ups/regex/Separation.mls | Update expected MatchSuccess bindings shape ({} → null). |
| hkmc2/shared/src/test/mlscript/ups/recursion/NatBox.mls | Update lowered IR expectation for boolean match-only compilation path. |
| hkmc2/shared/src/test/mlscript/ups/parametric/EtaConversion.mls | Update normalized output expectation for module/pattern references. |
| hkmc2/shared/src/test/mlscript/ups/MatchResult.mls | Expand coverage around @compile usage and update expected MatchSuccess bindings. |
| hkmc2/shared/src/test/mlscript/ups/LocalPatterns.mls | Update expected MatchSuccess bindings shape (null). |
| hkmc2/shared/src/test/mlscript/ups/Future.mls | Update MatchSuccess expectations and line-numbered diagnostics. |
| hkmc2/shared/src/test/mlscript/ups/examples/Extraction.mls | Add tests for biased disjunction + transforms and adjust outputs to preserve constructor tags when transform-free. |
| hkmc2/shared/src/test/mlscript/ups/examples/EvaluationContext2.mls | Adjust evaluation-context patterns/tests to align with match-only output behavior. |
| hkmc2/shared/src/test/mlscript/ups/examples/DoubleOrSum.mls | Update expected list output representation to preserve constructor structure. |
| hkmc2/shared/src/test/mlscript/ucs/patterns/where.mls | Update expected MatchSuccess bindings shape (null). |
| hkmc2/shared/src/test/mlscript/ucs/patterns/Parameters.mls | Add tests ensuring “keep scrutinee” works with private params when no rebuild is needed; refine rebuild error. |
| hkmc2/shared/src/test/mlscript/codegen/BlockPrinter.mls | Update printed block output to reflect null bindings and simplified output. |
| hkmc2/shared/src/test/mlscript/basics/PrefixOps.mls | Update expected MatchSuccess bindings shape (null). |
| hkmc2/shared/src/test/mlscript-compile/ups/TruthyFalsy.mls | New compilation-size example program exercising match-only entrypoints. |
| hkmc2/shared/src/test/mlscript-compile/ups/README.md | New documentation summarizing SLOC deltas for match-only vs full compiled patterns. |
| hkmc2/shared/src/test/mlscript-compile/ups/EvenOddTree.mls | New compilation-size example for mutually recursive tree patterns. |
| hkmc2/shared/src/test/mlscript-compile/ups/EvaluationContext.mls | New compilation-size example for evaluation-context patterns. |
| hkmc2/shared/src/test/mlscript-compile/ups/DnfCnf.mls | New compilation-size example for recursive logical-formula patterns. |
| hkmc2/shared/src/test/mlscript-compile/Char.mls | Add AnyChar pattern used by compilation examples/tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
hkmc2/shared/src/main/scala/hkmc2/semantics/ups/SplitCompiler.scala
Outdated
Show resolved
Hide resolved
hkmc2/shared/src/main/scala/hkmc2/semantics/ups/SplitCompiler.scala
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| :sir | ||
| // Keep the IR output to prevent regressions. |
There was a problem hiding this comment.
I think the one below is enough.
| pattern ToFahrenheit = | ||
| ((Celsius(c)) => Fahrenheit((c * 9 / 5) + 32)) | | ||
| ((Fahrenheit as f) => f) | ||
| | ((Celsius(c)) => Fahrenheit((c * 9 / 5) + 32)) |
There was a problem hiding this comment.
You don't need parentheses in all these examples.
No description provided.