v icon indicating copy to clipboard operation
v copied to clipboard

Checker disallows `t as Type` Option unwrapping inside `if` expression

Open gechandesu opened this issue 2 months ago • 2 comments

V version: V 0.4.12 c3e0637, press to see full `v doctor` output
V full version V 0.4.12 ebf629dc4124a6207b18028cf89dc6910d25eaf3.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.66GB/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 c3e06373
.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.v && opt_unwrap

fn foo(s ?string) int {
	if s as string != '' {
		return 1
	}
	return 0
}

fn main() {
	assert foo(none) == 0
	assert foo('') == 0
	assert foo('x') == 1
}

What did you see?

opt_unwrap.v:2:5: error: variable `s` is an Option, it must be unwrapped first
    1 | fn foo(s ?string) int {
    2 |     if s as string != '' {
      |        ^
    3 |         return 1
    4 |     }

What did you expect to see?

s unwrapped

Additional info

t as Type works with struct fields. This code compiles and all asserts passes:

struct Foo {
        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.

gechandesu avatar Nov 30 '25 01:11 gechandesu

Related https://github.com/vlang/v/issues/25861

gechandesu avatar Nov 30 '25 01:11 gechandesu

The checker error is correct, the s should be unwrapped, to eliminate the possibility of it being none, before being compared to a string.

spytheman avatar Dec 01 '25 12:12 spytheman