vlang

/

v Public
0 commits 39 issues 0 pull requests 0 contributors Discussions Projects CI

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 ?Bar followed by got := f as ?Bar.