You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
V 0.5.1 1510663 on Windows 11, MSVC backend (-cc msvc).
Description
When a function returning !T (T non-void) is called as a statement (return value discarded) with an or { ... } block whose tail expression is itself an or block on a !void call, the C generator emits an assignment with an empty right-hand side:
*(T*) _t.data= ;
MSVC rejects this with error C2059: syntax error: ';'.
Minimal reproduction
modulemainstructItem {
id int
}
fnget_item() !Item {
return Item{id: 1}
}
fndo_void() ! {
returnerror('boom')
}
fnmain() {
get_item() or {
do_void() or {
println('inner: ${err}')
}
}
}
The compiler appears to treat the inner or block (a !void expression used as a statement) as a value expression yielding Item, then emits the standard "store the or-block's value into _t1.data" assignment with no RHS because there is no value.
Expected behavior
Either:
No assignment should be emitted at all, since the outer call's result is discarded (the call is used as a statement); the or block exists only for side-effecting error handling, or
A V-level error/warning should reject the program if codegen cannot lower it.
Workarounds
Any of these compile and behave correctly:
Use the if x := call() { } else { } form on the outer call instead of or { ... }.
Extract the inner do_void() or { ... } into a helper function so the outer or block does not end with a nested or expression.
Add a non-or trailing statement inside the outer or block (e.g. return, continue, or another non-or call).
Notes
Reproduces on all three C backends I tested (Windows 11):
-cc msvc → error C2059: syntax error: ';'
-cc tcc → error: identifier expected
-cc gcc → error: expected expression before ';' token
Triggered specifically by nesting — a single-level or { do_void() or { ... } } is the smallest shape that hits it. A non-or tail in the outer block (e.g. or { do_void() or { ... }; return }) avoids the bug.
Note
You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.
V version
V 0.5.1 1510663on Windows 11, MSVC backend (-cc msvc).Description
When a function returning
!T(T non-void) is called as a statement (return value discarded) with anor { ... }block whose tail expression is itself anorblock on a!voidcall, the C generator emits an assignment with an empty right-hand side:MSVC rejects this with
error C2059: syntax error: ';'.Minimal reproduction
Build:
Result:
Generated C (excerpt)
The compiler appears to treat the inner
orblock (a!voidexpression used as a statement) as a value expression yieldingItem, then emits the standard "store the or-block's value into_t1.data" assignment with no RHS because there is no value.Expected behavior
Either:
orblock exists only for side-effecting error handling, orWorkarounds
Any of these compile and behave correctly:
if x := call() { } else { }form on the outer call instead ofor { ... }.do_void() or { ... }into a helper function so the outerorblock does not end with a nestedorexpression.ortrailing statement inside the outerorblock (e.g.return,continue, or another non-orcall).Notes
-cc msvc→error C2059: syntax error: ';'-cc tcc→error: identifier expected-cc gcc→error: expected expression before ';' tokenor { do_void() or { ... } }is the smallest shape that hits it. A non-ortail in the outer block (e.g.or { do_void() or { ... }; return }) avoids the bug.Note
You can use the 👍 reaction to increase the issue's priority for developers.
Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.