From 3525b8778edd235d8d0ad2b55eee83eacd33d5cf Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Fri, 23 Sep 2022 16:55:46 +0300 Subject: [PATCH] Sema: properly handle generic struct as parameter type Closes #12907 --- src/Sema.zig | 17 +++++++++++++++-- test/behavior/generics.zig | 13 +++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 465a3ceb1b..342213dad1 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -8277,8 +8277,21 @@ fn zirParam( else => |e| return e, } }; - const is_comptime = comptime_syntax or - try sema.typeRequiresComptime(param_ty); + const is_comptime = sema.typeRequiresComptime(param_ty) catch |err| switch (err) { + error.GenericPoison => { + // The type is not available until the generic instantiation. + // We result the param instruction with a poison value and + // insert an anytype parameter. + try block.params.append(sema.gpa, .{ + .ty = Type.initTag(.generic_poison), + .is_comptime = comptime_syntax, + .name = param_name, + }); + try sema.inst_map.putNoClobber(sema.gpa, inst, .generic_poison); + return; + }, + else => |e| return e, + } or comptime_syntax; if (sema.inst_map.get(inst)) |arg| { if (is_comptime) { // We have a comptime value for this parameter so it should be elided from the diff --git a/test/behavior/generics.zig b/test/behavior/generics.zig index b3c399cea8..9ec949bbf5 100644 --- a/test/behavior/generics.zig +++ b/test/behavior/generics.zig @@ -369,3 +369,16 @@ test "extern function used as generic parameter" { }; try expect(S.baz(S.foo) != S.baz(S.bar)); } + +test "generic struct as parameter type" { + const S = struct { + fn doTheTest(comptime Int: type, thing: struct { int: Int }) !void { + try expect(thing.int == 123); + } + fn doTheTest2(comptime Int: type, comptime thing: struct { int: Int }) !void { + try expect(thing.int == 456); + } + }; + try S.doTheTest(u32, .{ .int = 123 }); + try S.doTheTest2(i32, .{ .int = 456 }); +}