Commit f43ea43ac9

Veikka Tuominen <git@vexu.eu>
2022-07-29 09:30:10
stage2: fix hashing of struct values
Closes #12279
1 parent 4fc2acd
Changed files (2)
src
test
behavior
src/value.zig
@@ -2292,25 +2292,13 @@ pub const Value = extern union {
                 }
             },
             .Struct => {
-                if (ty.isTupleOrAnonStruct()) {
-                    const fields = ty.tupleFields();
-                    for (fields.values) |field_val, i| {
-                        field_val.hash(fields.types[i], hasher, mod);
-                    }
-                    return;
-                }
-                const fields = ty.structFields().values();
-                if (fields.len == 0) return;
                 switch (val.tag()) {
-                    .empty_struct_value => {
-                        for (fields) |field| {
-                            field.default_val.hash(field.ty, hasher, mod);
-                        }
-                    },
+                    .empty_struct_value => {},
                     .aggregate => {
                         const field_values = val.castTag(.aggregate).?.data;
                         for (field_values) |field_val, i| {
-                            field_val.hash(fields[i].ty, hasher, mod);
+                            const field_ty = ty.structFieldType(i);
+                            field_val.hash(field_ty, hasher, mod);
                         }
                     },
                     else => unreachable,
test/behavior/tuple.zig
@@ -255,3 +255,23 @@ test "initializing anon struct with mixed comptime-runtime fields" {
     var a: T = .{ .foo = -1234, .bar = x + 1 };
     _ = a;
 }
+
+test "tuple in tuple passed to generic function" {
+    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+
+    const S = struct {
+        fn pair(x: f32, y: f32) std.meta.Tuple(&.{ f32, f32 }) {
+            return .{ x, y };
+        }
+
+        fn foo(x: anytype) !void {
+            try expect(x[0][0] == 1.5);
+            try expect(x[0][1] == 2.5);
+        }
+    };
+    const x = comptime S.pair(1.5, 2.5);
+    try S.foo(.{x});
+}