Skip to content

Fix #1146: require command_datatypes to be non-empty#1155

Merged
aqjune-aws merged 6 commits into
mainfrom
fix-1146-empty-datatypes-command
May 18, 2026
Merged

Fix #1146: require command_datatypes to be non-empty#1155
aqjune-aws merged 6 commits into
mainfrom
fix-1146-empty-datatypes-command

Conversation

@tautschnig
Copy link
Copy Markdown
Contributor

The Core grammar declared command_datatypes as

op command_datatypes (datatypes : NewlineSepBy DatatypeDecl) : Command =>
datatypes ";\n";

Without @[nonempty] on the field, NewlineSepBy compiles to a zero-or-more parser, so the trailing ";\n" production alone matched any stray ";" in the input. This is particularly easy to trip accidentally: command_fndef's surface syntax has no trailing semicolon, so a user writing "};" at the end of a function body (by analogy with procedures, whose grammar does end in ";") silently produced a phantom command_datatypes op with zero datatypes.

The phantom later tripped an explicit assertion in translateDatatypes:

"Datatype block must contain at least one datatype"

which calls panic!, producing a large backtrace at gen_smt_vcs time with no useful source location.

Mark the datatypes field @[nonempty]. The stray ";" now surfaces as a parse error at the point it actually appears, and the original repro elaborates cleanly.

Add a regression test (StrataTest/Languages/Core/Tests/Issue1146Test.lean) that pins the canonical form: a program mixing a datatype and a function can run through gen_smt_vcs without panicking.

Fixes: #1146

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

The Core grammar declared command_datatypes as

  op command_datatypes (datatypes : NewlineSepBy DatatypeDecl) : Command =>
    datatypes ";\\n";

Without @[nonempty] on the field, NewlineSepBy compiles to a zero-or-more
parser, so the trailing ";\\n" production alone matched any stray
";" in the input. This is particularly easy to trip accidentally:
command_fndef's surface syntax has no trailing semicolon, so a user
writing "};" at the end of a function body (by analogy with procedures,
whose grammar does end in ";") silently produced a phantom
command_datatypes op with zero datatypes.

The phantom later tripped an explicit assertion in translateDatatypes:

  "Datatype block must contain at least one datatype"

which calls panic!, producing a large backtrace at gen_smt_vcs time with
no useful source location.

Mark the datatypes field @[nonempty]. The stray ";" now surfaces as a
parse error at the point it actually appears, and the original repro
elaborates cleanly.

Add a regression test (StrataTest/Languages/Core/Tests/Issue1146Test.lean)
that pins the canonical form: a program mixing a datatype and a function
can run through gen_smt_vcs without panicking.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a parsing ambiguity in the Core dialect where command_datatypes could match an empty datatype block (i.e. only the trailing ;\n), allowing stray semicolons to be accepted and later triggering a panic during SMT VC generation (Issue #1146). The change tightens the grammar so datatype blocks must contain at least one datatype declaration, and adds a regression test to ensure a mixed datatype+function program no longer panics under gen_smt_vcs.

Changes:

  • Require command_datatypesdatatypes list to be non-empty via @[nonempty] in the Core grammar.
  • Add a regression test ensuring gen_smt_vcs doesn’t panic on a program that combines a datatype declaration and a function definition.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
Strata/Languages/Core/DDMTransform/Grammar.lean Makes command_datatypes reject empty NewlineSepBy DatatypeDecl parses by adding @[nonempty].
StrataTest/Languages/Core/Tests/Issue1146Test.lean Adds a regression test that exercises VC generation for a program containing both a datatype and a function.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread StrataTest/Languages/Core/Tests/Issue1146Test.lean Outdated
The regression test's doc comment described the pre-fix behaviour as a
"large panic! backtrace". The ".github/scripts/checkNoPanic.sh" lint runs
`grep -F 'panic!'` against added lines and flagged this as a net-new panic
call, failing the PR's "Run lint checks (stable)" check.

Rephrase the doc comment to describe the behaviour without the literal
`panic!` token (the symbol actually lives in `TransM.error`, which still
shows up there — unchanged by this PR).

No code change; no behavioural change.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Address Copilot's review feedback on PR #1155: the previous Issue1146Test
only pinned the positive path (canonical form + gen_smt_vcs succeeds). The
original bug was that the stray ';' was silently accepted, so a future
regression (e.g. someone removing @[nonempty] from command_datatypes'
datatypes field) would not be caught by the positive test alone.

Replace the negative-case doc comment with an active #guard_msgs check
that elaborates the exact form from issue #1146 (datatype + function with
trailing '};') and pins the parser's diagnostic message. Removing the
@[nonempty] annotation now fails this test at elaboration time instead of
only manifesting at gen_smt_vcs.

The pattern '#guard_msgs in def ... := #strata ... #end' is already
standard in Core tests — e.g. StrataTest/Languages/Core/Examples/
TypeAlias.lean:18 and StrataTest/Languages/Core/Tests/
PolymorphicDatatypeTest.lean:572 — and my earlier 'would need custom
infrastructure' rationale was mistaken.

Message stability is flagged inline: the text enumerates valid
continuations at that source position, so a new top-level command
production in the Core grammar would require updating the expected
message.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Comment thread Strata/Languages/Core/DDMTransform/Grammar.lean
Comment thread StrataTest/Languages/Core/Tests/Issue1146Test.lean Outdated
Comment thread StrataTest/Languages/Core/Tests/Issue1146Test.lean Outdated
Comment thread StrataTest/Languages/Core/Tests/Issue1146Test.lean Outdated
tautschnig and others added 2 commits May 16, 2026 00:37
Four follow-ups to the PR review thread:

1. Grammar.lean: shrink the 8-line motivation block to a one-line
   "@[nonempty] is load-bearing: see #1146" reference. The full
   explanation now lives in the test file alongside the regression
   itself.

2. Issue1146Test.lean module docstring: drop the before/after history
   and restate the test's purpose statelessly — what the tests currently
   exercise rather than how the code used to behave.

3. Replace the "example : smtVCsCorrect ... := by gen_smt_vcs" success
   case with the canonical Core test idiom
   "TransM.run Inhabited.default (translateProgram p) |>.snd |>.isEmpty"
   from Strata.Languages.Core.DDMTransform.Translate. The panic the
   regression catches was inside translateDatatypes, which
   translateProgram calls directly, so this is functionally equivalent
   and matches the rest of StrataTest/Languages/Core/Tests/. Drops the
   transitive Strata.MetaVerifier import.

4. Drop the meta-commentary about how the parse-error message would
   change if a new top-level command production were added. The
   #guard_msgs-pinned assertion is the active contract; the prose
   describing its brittleness is unnecessary.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@aqjune-aws aqjune-aws enabled auto-merge May 18, 2026 18:43
@aqjune-aws aqjune-aws added this pull request to the merge queue May 18, 2026
Merged via the queue into main with commit 6835d65 May 18, 2026
20 checks passed
@aqjune-aws aqjune-aws deleted the fix-1146-empty-datatypes-command branch May 18, 2026 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SMT translation fails when datatype is present.

6 participants