cgen: as/is on a sumtype option-type variant (type Foo = ?Bar | Baz) uses the wrong union member #1
Description
When a sumtype has an option-type variant (e.g. type Foo = ?Bar | Baz), an as/is cast to that option variant generates C that references the wrong union member: it emits (f)._main__Bar instead of the option-variant member (_main__OptBar), so the C compiler fails.
V version: V 0.5.1, current master (498584ccd)
OS/Backend: reproduced on macOS arm64; originally reported on Linux/cc.
Reproducer
struct Bar {
i int
}
struct Baz {}
type Foo = ?Bar | Baz
fn main() {
f := Foo(?Bar(Bar{i: 5}))
got := f as ?Bar
println(got != none)
}
Compile with:
v file.v
Current behavior
error: no member named '_main__Bar' in 'struct main__Foo'; did you mean '_main__Baz'?
_option_main__Bar got = *(_option_main__Bar*)builtin____as_cast((f)._main__Bar, (f)._typ, ...);
The as ?Bar cast (and the is ?Bar check) emit (f)._main__Bar, but the union member generated for the ?Bar variant is named _main__OptBar, not _main__Bar.
Expected behavior
The as/is codegen for an option-type sumtype variant should reference the correct union member (the option-variant member), so the program compiles.
Notes
- Reported via the bugs.vlang.io crash reporter (~6 reports). Original used
assert f is ?Barfollowed bygot := f as ?Bar.