Commit 3fa5415253

martinhath <martinhath@users.noreply.github.com>
2022-08-26 10:37:17
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
1 parent bcaa9df
Changed files (3)
src
test
behavior
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()) {
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,
+        },
+    };
+}
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");