Commit 9431100736

Veikka Tuominen <git@vexu.eu>
2022-06-01 01:19:40
Sema: apply previous changes to `validateUnionInit`
1 parent 3c4e7ab
Changed files (3)
lib
std
math
src
test
behavior
lib/std/math/big/int.zig
@@ -2063,9 +2063,8 @@ pub const Const = struct {
         // This is the inverse of calcDivLimbsBufferLen
         const available_len = (limbs.len / 3) - 2;
 
-        // TODO https://github.com/ziglang/zig/issues/11439
-        const biggest = comptime Const{
-            .limbs = &([1]Limb{math.maxInt(Limb)} ** available_len),
+        const biggest: Const = .{
+            .limbs = &([1]Limb{comptime math.maxInt(Limb)} ** available_len),
             .positive = false,
         };
         var buf: [biggest.sizeInBaseUpperBound(radix)]u8 = undefined;
src/Sema.zig
@@ -3215,7 +3215,9 @@ fn validateUnionInit(
         return sema.failWithOwnedErrorMsg(block, msg);
     }
 
-    if (is_comptime or block.is_comptime) {
+    if ((is_comptime or block.is_comptime) and
+        (try sema.resolveDefinedValue(block, init_src, union_ptr)) != null)
+    {
         // In this case, comptime machinery already did everything. No work to do here.
         return;
     }
@@ -3261,7 +3263,18 @@ fn validateUnionInit(
         if (store_inst == field_ptr_air_inst) break;
         if (air_tags[store_inst] != .store) continue;
         const bin_op = air_datas[store_inst].bin_op;
-        if (bin_op.lhs != field_ptr_air_ref) continue;
+        var lhs = bin_op.lhs;
+        if (Air.refToIndex(lhs)) |lhs_index| {
+            if (air_tags[lhs_index] == .bitcast) {
+                lhs = air_datas[lhs_index].ty_op.operand;
+                block_index -= 1;
+            }
+        }
+        if (lhs != field_ptr_air_ref) continue;
+        while (block_index > 0) : (block_index -= 1) {
+            const block_inst = block.instructions.items[block_index - 1];
+            if (air_tags[block_inst] != .dbg_stmt) break;
+        }
         if (block_index > 0 and
             field_ptr_air_inst == block.instructions.items[block_index - 1])
         {
test/behavior/basic.zig
@@ -1005,3 +1005,51 @@ test "generic function uses return type of other generic function" {
     };
     try std.testing.expect(S.call(S.func, .{@as(u8, 1)}) == 1);
 }
+
+test "const alloc with comptime known initializer is made comptime known" {
+    const S = struct {
+        a: bool,
+        b: [2]u8,
+    };
+    {
+        const s: S = .{
+            .a = false,
+            .b = .{ 1, 2 },
+        };
+        if (s.a) @compileError("bad");
+    }
+    {
+        const s: S = .{
+            .a = false,
+            .b = [2]u8{ 1, 2 },
+        };
+        if (s.a) @compileError("bad");
+    }
+    {
+        const s: S = comptime .{
+            .a = false,
+            .b = .{ 1, 2 },
+        };
+        if (s.a) @compileError("bad");
+    }
+    {
+        const Const = struct {
+            limbs: []const usize,
+            positive: bool,
+        };
+        const biggest: Const = .{
+            .limbs = &([1]usize{comptime std.math.maxInt(usize)} ** 128),
+            .positive = false,
+        };
+        if (biggest.positive) @compileError("bad");
+    }
+    {
+        const U = union(enum) {
+            a: usize,
+        };
+        const u: U = .{
+            .a = comptime std.math.maxInt(usize),
+        };
+        if (u.a == 0) @compileError("bad");
+    }
+}