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:
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,
+ },
+ };
+}