Commit 4aaff75c81

Veikka Tuominen <git@vexu.eu>
2022-10-17 15:39:44
Sema: resolve tuple default values before hashing
Closes #12488
1 parent 6582896
Changed files (3)
src
test
behavior
src/Sema.zig
@@ -6622,6 +6622,11 @@ fn instantiateGenericCall(
             }
 
             const arg_ty = sema.typeOf(uncasted_args[i]);
+            if (is_comptime or is_anytype) {
+                // Tuple default values are a part of the type and need to be
+                // resolved to hash the type.
+                try sema.resolveTupleLazyValues(block, call_src, arg_ty);
+            }
 
             if (is_comptime) {
                 const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[i]) catch |err| switch (err) {
@@ -6997,6 +7002,16 @@ fn instantiateGenericCall(
     return result;
 }
 
+fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
+    if (!ty.isTuple()) return;
+    const tuple = ty.tupleFields();
+    for (tuple.values) |field_val, i| {
+        try sema.resolveTupleLazyValues(block, src, tuple.types[i]);
+        if (field_val.tag() == .unreachable_value) continue;
+        try sema.resolveLazyValue(block, src, field_val);
+    }
+}
+
 fn emitDbgInline(
     sema: *Sema,
     block: *Block,
@@ -28606,6 +28621,20 @@ fn resolveLazyValue(
             const ty = val.castTag(.lazy_size).?.data;
             return sema.resolveTypeLayout(block, src, ty);
         },
+        .comptime_field_ptr => {
+            const field_ptr = val.castTag(.comptime_field_ptr).?.data;
+            return sema.resolveLazyValue(block, src, field_ptr.field_val);
+        },
+        .@"union" => {
+            const union_val = val.castTag(.@"union").?.data;
+            return sema.resolveLazyValue(block, src, union_val.val);
+        },
+        .aggregate => {
+            const aggregate = val.castTag(.aggregate).?.data;
+            for (aggregate) |elem_val| {
+                try sema.resolveLazyValue(block, src, elem_val);
+            }
+        },
         else => return,
     }
 }
test/behavior/bugs/12488.zig
@@ -0,0 +1,13 @@
+const expect = @import("std").testing.expect;
+
+const A = struct {
+    a: u32,
+};
+
+fn foo(comptime a: anytype) !void {
+    try expect(a[0][0] == @sizeOf(A));
+}
+
+test {
+    try foo(.{[_]usize{@sizeOf(A)}});
+}
test/behavior.zig
@@ -88,6 +88,7 @@ test {
     _ = @import("behavior/bugs/12033.zig");
     _ = @import("behavior/bugs/12430.zig");
     _ = @import("behavior/bugs/12486.zig");
+    _ = @import("behavior/bugs/12488.zig");
     _ = @import("behavior/bugs/12551.zig");
     _ = @import("behavior/bugs/12644.zig");
     _ = @import("behavior/bugs/12680.zig");