From 26c7e700c3831f0455ff3987e6d5eb32d16d8729 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 26 Feb 2026 20:06:01 +0300 Subject: [PATCH] checker: fix aliased pointers not recognized (fixes #24621) --- vlib/v/checker/struct.v | 16 +++++++-- ...as_pointer_struct_field_default_nil_test.v | 33 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/aliases/alias_pointer_struct_field_default_nil_test.v diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 3e35c1151..c9ef1bb51 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -319,8 +319,20 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { } } if field.default_expr.is_nil() { - if !field.typ.is_any_kind_of_pointer() - && c.table.sym(field.typ).kind != .function { + mut nil_field_typ := field.typ + mut nil_field_sym := c.table.sym(nil_field_typ) + // Preserve pointer indirections while resolving alias chains. + for { + if mut nil_field_sym.info is ast.Alias { + parent_typ := nil_field_sym.info.parent_type + nil_field_typ = parent_typ.set_nr_muls(parent_typ.nr_muls() + + nil_field_typ.nr_muls()) + nil_field_sym = c.table.sym(nil_field_typ) + } else { + break + } + } + if !nil_field_typ.is_any_kind_of_pointer() && nil_field_sym.kind != .function { c.error('cannot assign `nil` to a non-pointer field', field.type_pos) } } diff --git a/vlib/v/tests/aliases/alias_pointer_struct_field_default_nil_test.v b/vlib/v/tests/aliases/alias_pointer_struct_field_default_nil_test.v new file mode 100644 index 000000000..b30b260bd --- /dev/null +++ b/vlib/v/tests/aliases/alias_pointer_struct_field_default_nil_test.v @@ -0,0 +1,33 @@ +type NilAliasCol = int | string + +struct NilAliasMyType { + cols []NilAliasCol +} + +type NilAliasPtr = &NilAliasMyType + +struct NilAliasStruct { +mut: + alias_ptr NilAliasPtr = unsafe { nil } + alias_ptr_ptr &NilAliasPtr = unsafe { nil } +} + +fn test_struct_field_default_nil_for_pointer_alias() { + value := NilAliasStruct{} + assert isnil(value.alias_ptr) + assert isnil(value.alias_ptr_ptr) +} + +struct NilAliasInnerType {} + +type NilAliasInner = NilAliasInnerType + +struct NilAliasRefStruct { +mut: + alias_ref &NilAliasInner = unsafe { nil } +} + +fn test_struct_field_default_nil_for_reference_to_alias() { + value := NilAliasRefStruct{} + assert isnil(value.alias_ref) +} -- 2.39.5