Skip to content

Commit

Permalink
[MOREL-205] Pattern that uses nested type-constructors should not be …
Browse files Browse the repository at this point in the history
…considered redundant

Fixes #205

Adds test cases for #126
  • Loading branch information
julianhyde committed Nov 21, 2023
1 parent 0476670 commit 6741f5b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,14 @@ private void toTerm(Core.Pat pat, Path path, List<Sat.Term> terms) {
case CON_PAT:
final Core.ConPat conPat = (Core.ConPat) pat;
terms.add(typeConstructorTerm(path, conPat.tyCon));
toTerm(conPat.pat, path, terms);
final int j =
ImmutableList.copyOf(
((DataType) conPat.type).typeConstructors.keySet())
.indexOf(conPat.tyCon);
if (j < 0) {
throw new AssertionError("type constructor not found: " + conPat);
}
toTerm(conPat.pat, path.sub(j), terms);
return;

case CONS_PAT:
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/net/hydromatic/morel/MainTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1421,6 +1421,18 @@ public class MainTest {
});
}

/** Test case for "[MOREL-205] Pattern that uses nested type-constructors
* should not be considered redundant". */
@Test void testMatchCoverage13() {
// Even though "SOME i" is seen at depth 1 in the first line,
// the "SOME" at depth 0 in the second line is not the same pattern,
// therefore the pattern is not redundant.
final String ml = "fun f (SOME (SOME i)) = i + 1\n"
+ " | f (SOME NONE) = 0\n"
+ " | f NONE = ~1\n";
ml(ml).assertMatchCoverage(OK);
}

/** Function declaration. */
@Test void testFun() {
final String ml = "let\n"
Expand Down
33 changes: 33 additions & 0 deletions src/test/resources/script/datatype.smli
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,37 @@ stdIn:4.1-4.11 Error: operator and operand don't agree [tycon mismatch]
val it = 3 : int
*)

(*) Pattern matching on the same type constructor, nested.
fun f (SOME (SOME i)) = i + 1
| f (SOME NONE) = 0
| f NONE = ~1;
> val f = fn : int option option -> int
f (SOME (SOME 3));
> val it = 4 : int
f (SOME (SOME 2));
> val it = 3 : int
f (SOME NONE);
> val it = 0 : int
f NONE;
> val it = ~1 : int

(*) Test cases from [MOREL-126].
fun f ((SOME i) :: NIL) = i + 1
| f NIL = 0;
> val f = fn : int option list -> int
f [];
> val it = 0 : int
f [SOME 5];
> val it = 6 : int

fun f [(SOME i)] = i
| f [] = 0;
> 0.0-0.0 Warning: match nonexhaustive
> raised at: 0.0-0.0
> val f = fn : int option list -> int
f [];
> val it = 0 : int
f [SOME 5];
> val it = 5 : int

(*) End datatype.smli

0 comments on commit 6741f5b

Please sign in to comment.