Skip to content

Scope the type of return in state refinement checks - #441

Open
CatarinaGamboa wants to merge 1 commit into
mainfrom
fix/440-return-type-scope
Open

CatarinaGamboa wants to merge 1 commit into
mainfrom
fix/440-return-type-scope

Conversation

@CatarinaGamboa

Copy link
Copy Markdown
Collaborator

Fixes #440.

Problem. AuxStateHandler.createStatePredicate checks the to of a non-void method by renaming return to _ and declaring _ with the method's return type. That declaration (and the this variables) went into the current context, outside any scope, and only when _ didn't exist yet. So the first non-void method with a to fixed the type of return for every spec checked after it. A later to = "!return && ..." on a boolean method then crashed with Expr cannot be cast to BoolExpr (or IntExpr ... when the earlier method returned int). Which specs crash depends on the order the packages are checked in.

Change. Declare these variables in their own scope (enterContext / exitContext in a finally), and always declare _ with this method's return type. An inner declaration shadows an outer one in the SMT translation.

Test. testSuite/classes/state_return_type_scope_correct: a Vector spec whose set returns E, checked before an UndoManager spec with !return in canUndo. It fails on main with the crash and passes with this change. mvn test passes.

Also checked on a six-exercise study project (Vector, UndoManager, ImageWriteParam, JFrame, Random, Socket specs in one source folder): before the change, the UndoManager exercise's real error turned into this crash. After it, all six report their intended error lines.

🤖 Generated with Claude Code

createStatePredicate declared `_` (the renamed `return`) and the `this`
variables in the current context, outside any scope, and only when `_` was not
declared yet. The first non-void method with a `to` fixed the type of `return`
for every spec checked after it, and `!return` on a later boolean method
crashed with "Expr cannot be cast to BoolExpr".

Declare them in a scope of their own, always with the method's return type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CatarinaGamboa

Copy link
Copy Markdown
Collaborator Author

[Codex review] I checked the scope change in createStatePredicate, including the finally exit on errors and the regression with two different return types. It keeps the temporary this and _ declarations local to each check, and the verifier suite passes locally at this head (./mvnw -q -pl liquidjava-verifier -am test). I found no further issue with this PR.

@CatarinaGamboa

Copy link
Copy Markdown
Collaborator Author

[Claude] Thanks for checking. No changes needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash "Expr cannot be cast to BoolExpr": the type of return in a state refinement leaks into later specs

1 participant