Commit 15dddfd84d

Veikka Tuominen <git@vexu.eu>
2022-07-22 12:20:18
AstGen: make comptime fields in packed and extern structs compile errors
1 parent 0ef4cc7
Changed files (3)
src
test
cases
src/AstGen.zig
@@ -4214,6 +4214,12 @@ fn structDeclInner(
         const have_value = member.ast.value_expr != 0;
         const is_comptime = member.comptime_token != null;
 
+        if (is_comptime and layout == .Packed) {
+            return astgen.failTok(member.comptime_token.?, "packed struct fields cannot be marked comptime", .{});
+        } else if (is_comptime and layout == .Extern) {
+            return astgen.failTok(member.comptime_token.?, "extern struct fields cannot be marked comptime", .{});
+        }
+
         if (!is_comptime) {
             known_non_opv = known_non_opv or
                 nodeImpliesMoreThanOnePossibleValue(tree, member.ast.type_expr);
src/Sema.zig
@@ -14509,6 +14509,7 @@ fn zirStructInit(
         var field_i: u32 = 0;
         var extra_index = extra.end;
 
+        const is_packed = resolved_ty.containerLayout() == .Packed;
         while (field_i < extra.data.fields_len) : (field_i += 1) {
             const item = sema.code.extraData(Zir.Inst.StructInit.Item, extra_index);
             extra_index = item.end;
@@ -14535,7 +14536,7 @@ fn zirStructInit(
             }
             found_fields[field_index] = item.data.field_type;
             field_inits[field_index] = try sema.resolveInst(item.data.init);
-            if (resolved_ty.structFieldValueComptime(field_index)) |default_value| {
+            if (!is_packed) if (resolved_ty.structFieldValueComptime(field_index)) |default_value| {
                 const init_val = (try sema.resolveMaybeUndefVal(block, field_src, field_inits[field_index])) orelse {
                     return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime known");
                 };
@@ -14544,7 +14545,7 @@ fn zirStructInit(
                     // TODO add note showing where default value is provided
                     return sema.fail(block, field_src, "value stored in comptime field does not match the default value of the field", .{});
                 }
-            }
+            };
         }
 
         return sema.finishStructInit(block, src, src, field_inits, resolved_ty, is_ref);
test/cases/compile_errors/invalid_comptime_fields.zig
@@ -0,0 +1,21 @@
+const U = union {
+    comptime a: u32 = 1,
+};
+const E = enum {
+    comptime a = 1,
+};
+const P = packed struct {
+    comptime a: u32 = 1,
+};
+const X = extern struct {
+    comptime a: u32 = 1,
+};
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:5: error: union fields cannot be marked comptime
+// :5:5: error: enum fields cannot be marked comptime
+// :8:5: error: packed struct fields cannot be marked comptime
+// :11:5: error: extern struct fields cannot be marked comptime