Skip to content

t as Type Option unwrapping causes C error with mut struct fields #25861

@gechandesu

Description

@gechandesu
V version: V 0.4.12 c3e0637, press to see full `v doctor` output
V full version V 0.4.12 ebf629d.c3e0637
OS linux, Linux version 6.17.6-arch1-1 (linux@archlinux) (gcc (GCC) 15.2.1 20250813, GNU ld (GNU Binutils) 2.45.0) #1 SMP PREEMPT_DYNAMIC Wed, 29 Oct 2025 22:23:47 +0000
Processor 16 cpus, 64bit, little endian, 12th Gen Intel(R) Core(TM) i5-1240P
Memory 1.29GB/15.34GB
V executable /home/ge/.vlang/v
V last modified time 2025-11-29 15:34:32
V home dir OK, value: /home/ge/.vlang
VMODULES OK, value: /home/ge/.vmodules
VTMP OK, value: /tmp/v_1000
Current working dir OK, value: /tmp
env VFLAGS "-Wimpure-v"
Git version git version 2.51.2
V git status c3e0637
.git/config present true
cc version cc (GCC) 15.2.1 20250813
gcc version gcc (GCC) 15.2.1 20250813
clang version clang version 21.1.4
tcc version tcc version 0.9.28rc 2025-02-13 HEAD@f8bd136d (x86_64 Linux)
tcc git status thirdparty-linux-amd64 696c1d84
emcc version N/A
glibc version ldd (GNU libc) 2.42

What did you do?
./v -g -o vdbg cmd/v && ./vdbg opt_unwrap_struct_field.v && opt_unwrap_struct_field

struct Foo {
mut:
	state ?string
}

fn (mut c Foo) foo() int {
	if c.state as string != '' {
		return 1
	}
	return 0
}

fn main() {
	mut f1 := Foo{}
	mut f2 := Foo{''}
	mut f3 := Foo{'foo'}
	assert f1.foo() == 0
	assert f2.foo() == 0
	assert f3.foo() == 1
}

What did you see?

================== C compilation error (from tcc): ==============
cc: /tmp/v_1000/opt_unwrap_struct_field.01KB96CK7RE4EDW1CP4D30KKWF.tmp.c:4929: error: struct or union expected
=================================================================
Try passing `-g` when compiling, to see a .v file:line information, that correlates more with the C error.
(Alternatively, pass `-show-c-output`, to print the full C error message).
builder error: 
==================
C error found. It should never happen, when compiling pure V code.
This is a V compiler bug, 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 .

What did you expect to see?

Successful compilation

Additional info

Unwrapping works until receiver argument is not mut.

So this code works as expected:

struct Foo {
mut:
	state ?string
}

fn (c Foo) foo() int {
	if c.state as string != '' {
		return 1
	}
	return 0
}

fn main() {
	f1 := Foo{}
	f2 := Foo{''}
	f3 := Foo{'foo'}
	assert f1.foo() == 0
	assert f2.foo() == 0
	assert f3.foo() == 1
}

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugThis tag is applied to issues which reports bugs.Status: ConfirmedThis bug has been confirmed to be valid by a contributor.Unit: CheckerBugs/feature requests, that are related to the type checker.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions