Skip to content

A for condition that tests an optional value is made a boolean - #510

Merged
ASDAlexander77 merged 1 commit into
mainfrom
fix-for-optional-condition
Oct 5, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
fix-for-optional-condition

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

for (let node = head; node; node = node.next) with node: Node | undefined failed module verification under every memory model:

error: 'ts.Condition' op operand #0 must be , but got '!ts.optional<!ts.class<@Node, !ts.class_storage<@Node>>>'
error: module verification error

mlirGen(ForStatement) passed the condition to ts.Condition unchanged. mlirGen(WhileStatement), mlirGen(DoStatement) and mlirGen(IfStatement) cast a non-boolean condition to boolean first. The for condition now goes through the same cast. node !== undefined already produced a boolean, which is why that form worked.

Test

00for_optional_class_condition.ts runs a for over an optional class (in main and in a function), over a nullable (| null) class and over an optional string, and runs the same tests with while and if. It is registered for compile and JIT and in TSLANG_CORPUS (rc and none). On main it fails to compile with the error above.

ctest -C Release: 3858/3858 passed. gtest unittests were not built in this build tree.

Not covered here

  • The test leaves out an empty string: "" is truthy in every condition (if, while, !, ?:), filed as An empty string "" is truthy in if / while / ! / ?: conditions #509.
  • -mm=own rejects this list traversal ("borrows a field and cannot be stored"), with or without this fix and with node !== undefined too, so the test is not registered under own.
  • while narrows the tested variable in its body (checkSafeCast); for still does not. Nothing in this test needs it.

🤖 Generated with Claude Code

`for (let node = head; node; node = node.next)` with `node: Node |
undefined` failed module verification under every memory model:
'ts.Condition' op operand #0 must be , but got '!ts.optional<...>'.
mlirGen(ForStatement) handed the condition to ts.Condition as it was,
while mlirGen(WhileStatement), mlirGen(DoStatement) and mlirGen(IfStatement)
cast a non-boolean condition to boolean first. The for condition now
goes through the same cast. `node !== undefined` was already boolean,
which is why it worked.

00for_optional_class_condition.ts: a for over an optional class (in
main and in a function), a nullable (`| null`) class and
an optional string, next to the same test in while and if.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant