From 4aaff75c8191b9cff40d3423f44bdb831a88d89b Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 17 Oct 2022 16:39:44 +0300 Subject: [PATCH] Sema: resolve tuple default values before hashing Closes #12488 --- src/Sema.zig | 29 +++++++++++++++++++++++++++++ test/behavior.zig | 1 + test/behavior/bugs/12488.zig | 13 +++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 test/behavior/bugs/12488.zig diff --git a/src/Sema.zig b/src/Sema.zig index cb9d505e41..cf5aa87c90 100644 --- a/src/Sema.zig +++ b/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, } } diff --git a/test/behavior.zig b/test/behavior.zig index 0abf58290b..b3c1654607 100644 --- a/test/behavior.zig +++ b/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"); diff --git a/test/behavior/bugs/12488.zig b/test/behavior/bugs/12488.zig new file mode 100644 index 0000000000..b05197b24f --- /dev/null +++ b/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)}}); +}