Skip to content

Commit ea7e62c

Browse files
committed
Disallow a choice expression where a non-final subexpression always matches.
None of the subexpressions following it could ever match, so it's certainly a grammar error. But also, the code generated for such a case does not compile correctly :)
1 parent cfe5bfe commit ea7e62c

2 files changed

Lines changed: 13 additions & 1 deletion

File tree

check.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,10 @@ func (e *Choice) check(ctx ctx, valueUsed bool, errs *Errors) {
253253
sub.check(subCtx, valueUsed, errs)
254254
}
255255
t := e.Exprs[0].Type()
256-
for _, sub := range e.Exprs {
256+
for i, sub := range e.Exprs {
257+
if i < len(e.Exprs) - 1 && !sub.CanFail() {
258+
errs.add(e, "non-final choice subexpression always matches: %s", sub)
259+
}
257260
if got := sub.Type(); *genActions && valueUsed && got != t && got != "" && t != "" {
258261
errs.add(sub, "type mismatch: got %s, expected %s", got, t)
259262
}

check_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,15 @@ G <- [fgh]*`,
253253
err: "^test.file:1.8,1.27: type mismatch: got int, expected string\n" +
254254
"test.file:2.16,2.35: type mismatch: got int, expected string$",
255255
},
256+
{
257+
name: "choice non-final subexpression always matches",
258+
in: `A <- "B"? / "C"`,
259+
err: "non-final choice subexpression always matches:",
260+
},
261+
{
262+
name: "choice final subexpression may alway match",
263+
in: `A <- "B" / "C"?`,
264+
},
256265
}
257266
for _, test := range tests {
258267
test := test

0 commit comments

Comments
 (0)