Multiple return values type mismatch not caught by V #40
The following code gives a C error:
a, b := ''.split_once('') or { '', ?string(none) }
Output of v -g run bugged.v:
bugged.v:1:1: warning: unused variable: `a`
1 | a, b := ''.split_once('') or { '', ?string(none) }
| ^
bugged.v:1:4: warning: unused variable: `b`
1 | a, b := ''.split_once('') or { '', ?string(none) }
| ^
/tmp/v_1000//home/luser/src/v/bugged.v:3: error: cannot convert 'struct _option_string' to 'unsigned char *'
================== C compiler bug report ==============
Sent C compiler bug report to https://bugs.vlang.io/bug-report.
Report id: b5b2c74a-dc30-4ec0-a2d0-2511ebd612cf
Delete this report from the server with:
curl -X DELETE 'https://bugs.vlang.io/bug-report/b5b2c74a-dc30-4ec0-a2d0-2511ebd612cf?token=b1be192b-6cf3-4444-b1c9-822e37be22b4'
Generated C lines sent from /tmp/v_1000/bugged.01KW46RNT4TWXHN7GGF9KZGW90.tmp.c:7652:
7647 | }
7648 |
7649 | #line 1 "/home/luser/src/v/bugged.v"
7650 | void main__main(void) {
7651 | _option_multi_return_string_string _t1 = builtin__string_split_once(_S(""), _S(""));
> 7652 | if (_t1.state != 0) {
7653 |
7654 | #line 1 "/home/luser/src/v/bugged.v"
7655 | IError _t2 = _t1.err;
7656 | IError err = _t2;
7657 | *(multi_return_string_string*) _t1.data = (multi_return_string_string){.arg0=_S(""),.arg1=(_option_string){ .state=2, .err=_const_none__, .data={E_STRUCT} }};
Corresponding V lines sent from /home/luser/src/v/bugged.v:3:
1 | a, b := ''.split_once('') or { '', ?string(none) }
=======================================================
builder error:
==================
C error found while compiling generated C code.
This can be caused by invalid C interop code, C compiler flags, or a V compiler bug.
If your code is pure V and this still happens, please report it using `v bug file.v`,
or goto https://github.com/vlang/v/issues/new/choose .
You can also use #help on Discord: https://discord.gg/vlang .
This error happens because the V compiler didn't catch the type mismatch between the return value of split_once, which is (string, string) and between the or {} block, which is (string, ?string). This then blows up at the C level.
I would expect the V compiler to catch and report this mistake. Indeed, when trying instead following code:
a, b := ''.split_once('') or { '', 1 }
I get this error:
bugged.v:1:32: error: wrong return type `(string, int literal)` in the `or {}` block, expected `(string, string)`
1 | a, b := ''.split_once('') or { '', 1 }
|
V version: V 0.5.1 cd213a1 Environment details:
|V full version |V 0.5.1 63e43d751ce33dd9cd12ac385720ce28764486eb.cd213a1
|:-------------------|:-------------------
|OS |linux, Sabotage Linux
|Processor |4 cpus, 64bit, little endian, Intel(R) Core(TM) i5-2540M CPU @ 2.60GHz
|Memory |6.52GB/7.69GB
| |
|V executable |/home/luser/other-src/v/v
|V last modified time|2026-06-26 13:18:28
| |
|V home dir |OK, value: /home/luser/other-src/v
|VMODULES |OK, value: /home/luser/.vmodules
|VTMP |OK, value: /tmp/v_1000
|Current working dir |OK, value: /home/luser/src/v
| |
|Git version |git version 2.45.1
|V git status |cd213a17
|.git/config present |true
| |
|cc version |cc (GCC) 11.5.0
|gcc version |gcc (GCC) 11.5.0
|clang version |N/A
|tcc version |tcc version 0.9.27 mob:d3e940c (x86_64 Linux)
|tcc git status |thirdparty-linuxmusl-amd64 a3e24da2
|emcc version |N/A
|glibc version |Error: musl libc (x86_64)
Version 1.2.5
Dynamic Program Loader
Usage: ldd [options] [--] pathname