zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 3fa5415253695001149ad65ae6f2ca8d0fa63565 (tree)
parent bcaa9df5b42747577dcb529a99f6da6d69e09309
Author: martinhath <martinhath@users.noreply.github.com>
Date:   Fri, 26 Aug 2022 10:37:17 +0200

Sema: ensure resolveTypeFields is called for optional and error union types

We call `sema.resolveTypeFields` in order to get the fields of structs
and unions inserted into their data structures. If it isn't called, it
can happen that the fields of a type is queried before those fields are
inserted into (for instance) `Module.Union.fields`, which would result in
a wrong 'no field named' error.

Fixes: #12486
Diffstat:
Msrc/Sema.zig | 5+++--
Mtest/behavior.zig | 1+
Atest/behavior/bugs/12486.zig | 49+++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/src/Sema.zig b/src/Sema.zig @@ -16190,9 +16190,10 @@ fn fieldType( field_src: LazySrcLoc, ty_src: LazySrcLoc, ) CompileError!Air.Inst.Ref { - const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty); - var cur_ty = resolved_ty; + var cur_ty = aggregate_ty; while (true) { + const resolved_ty = try sema.resolveTypeFields(block, ty_src, cur_ty); + cur_ty = resolved_ty; switch (cur_ty.zigTypeTag()) { .Struct => { if (cur_ty.isAnonStruct()) { diff --git a/test/behavior.zig b/test/behavior.zig @@ -84,6 +84,7 @@ test { _ = @import("behavior/bugs/12003.zig"); _ = @import("behavior/bugs/12033.zig"); _ = @import("behavior/bugs/12430.zig"); + _ = @import("behavior/bugs/12486.zig"); _ = @import("behavior/byteswap.zig"); _ = @import("behavior/byval_arg_var.zig"); _ = @import("behavior/call.zig"); diff --git a/test/behavior/bugs/12486.zig b/test/behavior/bugs/12486.zig @@ -0,0 +1,49 @@ +const SomeEnum = union(enum) { + EnumVariant: u8, +}; + +const SomeStruct = struct { + struct_field: u8, +}; + +const OptEnum = struct { + opt_enum: ?SomeEnum, +}; + +const ErrEnum = struct { + err_enum: anyerror!SomeEnum, +}; + +const OptStruct = struct { + opt_struct: ?SomeStruct, +}; + +const ErrStruct = struct { + err_struct: anyerror!SomeStruct, +}; + +test { + _ = OptEnum{ + .opt_enum = .{ + .EnumVariant = 1, + }, + }; + + _ = ErrEnum{ + .err_enum = .{ + .EnumVariant = 1, + }, + }; + + _ = OptStruct{ + .opt_struct = .{ + .struct_field = 1, + }, + }; + + _ = ErrStruct{ + .err_struct = .{ + .struct_field = 1, + }, + }; +}