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
Inside $for field in T.fields, when a struct has multiple ?T fields with different non-pointer payload types, $zero(field.typ.payload_type) resolves to the same payload type for every iteration (the last one) instead of the current field's payload type. This causes a C compilation error.
Related: #26995 — same family of bug for T.pointee_type.
Reproduction Steps
modulemainstructFoo {
mut:
a ?int
b ?string
}
fnfill[T](mut x T) {
$for field in T.fields {
$if field.typ is $option {
mutv:= $zero(field.typ.payload_type)
x.$(field.name) = v
}
}
}
fnmain() {
mutf:= Foo{}
fill(mut f)
dump(f)
}
Expected Behavior
Compile cleanly. f.a becomes Some(0) and f.b becomes Some('').
Current Behavior
================== C compilation error (from tcc): ==============
cc: /tmp/v_1000/<...>.tmp.c:8530: error: cannot convert 'struct string' to 'int'
=================================================================
With gcc:
error: incompatible types when initializing type 'int' using type 'string'
8530 | builtin___option_ok(&(int[]) { v }, (_option*)(&_t2), sizeof(int));
Generated C for the a: ?int iteration declares v as string (the payload type of b: ?string, the last option field) and then tries to wrap it in _option_int, hence the type mismatch.
Possible Solution
Resolve field.typ.payload_type per-iteration of $for field in T.fields instead of using a single resolved type for the whole expansion.
Describe the bug
Inside
$for field in T.fields, when a struct has multiple?Tfields with different non-pointer payload types,$zero(field.typ.payload_type)resolves to the same payload type for every iteration (the last one) instead of the current field's payload type. This causes a C compilation error.Introduced by 8b5f74e.
Related: #26995 — same family of bug for
T.pointee_type.Reproduction Steps
Expected Behavior
Compile cleanly.
f.abecomesSome(0)andf.bbecomesSome('').Current Behavior
With gcc:
Generated C for the
a: ?intiteration declaresvasstring(the payload type ofb: ?string, the last option field) and then tries to wrap it in_option_int, hence the type mismatch.Possible Solution
Resolve
field.typ.payload_typeper-iteration of$for field in T.fieldsinstead of using a single resolved type for the whole expansion.V version
V 0.5.1 6dd9033.eb1d47b
Environment details
linux, Ubuntu 24.04 LTS, gcc 14.2.0, tcc 0.9.28rc
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.