Skip to content

checker: ?&T cannot be compared to nil even inside a comptime $if T.indirections != 0 branch #26893

@enghitalo

Description

@enghitalo

Describe the bug

The checker rejects a comptime-guarded val == unsafe { nil } comparison when val has type ?&T, even though the $if T.indirections != 0 branch only fires because the option's payload is a pointer. The diagnostic says "unwrap the option first", but inside the comptime branch the program already knows the payload is a pointer — the option wrapper should not block the nil comparison.

Reproduction Steps

struct Tag {
	id     string
	parent ?&Tag
}

fn is_nil_field[T](val T) bool {
	$if T.indirections != 0 {
		return val == unsafe { nil }
	}
	return false
}

fn main() {
	t := Tag{}
	$for f in Tag.fields {
		println(is_nil_field(t.$(f.name)))
	}
}

Expected Behavior

Compiles. Prints false for id (string is not pointer-typed, falls into return false) and true for parent (option is none).

Current Behavior

error: `?Tag` cannot be used as `nil`, unwrap the option first
   8 |         return val == unsafe { nil }
     |                ~~~

Possible Solution

Either (a) distinguish ?&T from ?T in T.indirections so the comptime guard maps to the actual pointer-ness of the payload, or (b) teach the ==-with-nil checker to look through the option wrapper when T.indirections != 0. Alternatively, generalize isnil(val) in builtin to accept ?&T so user code has a clean escape hatch.

V version

V 0.5.1 (40b3711)

Environment details (OS name and version, etc.)

|V full version      |V 0.5.1 1b3385cc34ff783e793d1a26a8ec5be587c80fe0.40b3711
|:-------------------|:-------------------
|OS                  |linux, Ubuntu 24.04 LTS
|Processor           |16 cpus, 64bit, little endian, AMD Ryzen 7 5800H with Radeon Graphics
|Memory              |10.02GB/30.7GB
|                    |
|V executable        |/home/hitalo/Documents/v/v
|V last modified time|2026-04-18 09:18:00
|                    |
|V home dir          |OK, value: /home/hitalo/Documents/v
|VMODULES            |OK, value: /home/hitalo/.vmodules
|VTMP                |OK, value: /tmp/v_1000
|Current working dir |OK, value: /home/hitalo/Documents/v
|                    |
|Git version         |git version 2.43.0
|V git status        |0.5.1-1006-g40b3711b-dirty
|.git/config present |true
|                    |
|cc version          |cc (GCC) 14.2.0
|gcc version         |gcc (GCC) 14.2.0
|clang version       |Ubuntu clang version 18.1.3 (1)
|tcc version         |tcc version 0.9.28rc 2025-02-13 HEAD@f8bd136d (x86_64 Linux)
|tcc git status      |thirdparty-linux-amd64 696c1d84
|emcc version        |emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.6 ()
|glibc version       |ldd (Ubuntu GLIBC 2.39-0ubuntu8.3) 2.39

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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions