authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-23 16:55:46+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-24 14:43:03+03:00
log3525b8778edd235d8d0ad2b55eee83eacd33d5cf
tree5c0ca92c05bae4d64f062a30ba98d335e578234d
parentede379848525dce72c6e903b1895ac3e4acaf3ef

Sema: properly handle generic struct as parameter type

Closes #12907

2 files changed, 28 insertions(+), 2 deletions(-)

src/Sema.zig+15-2
......@@ -8277,8 +8277,21 @@ fn zirParam(
82778277 else => |e| return e,
82788278 }
82798279 };
8280 const is_comptime = comptime_syntax or
8281 try sema.typeRequiresComptime(param_ty);
8280 const is_comptime = sema.typeRequiresComptime(param_ty) catch |err| switch (err) {
8281 error.GenericPoison => {
8282 // The type is not available until the generic instantiation.
8283 // We result the param instruction with a poison value and
8284 // insert an anytype parameter.
8285 try block.params.append(sema.gpa, .{
8286 .ty = Type.initTag(.generic_poison),
8287 .is_comptime = comptime_syntax,
8288 .name = param_name,
8289 });
8290 try sema.inst_map.putNoClobber(sema.gpa, inst, .generic_poison);
8291 return;
8292 },
8293 else => |e| return e,
8294 } or comptime_syntax;
82828295 if (sema.inst_map.get(inst)) |arg| {
82838296 if (is_comptime) {
82848297 // We have a comptime value for this parameter so it should be elided from the
test/behavior/generics.zig+13
......@@ -369,3 +369,16 @@ test "extern function used as generic parameter" {
369369 };
370370 try expect(S.baz(S.foo) != S.baz(S.bar));
371371}
372
373test "generic struct as parameter type" {
374 const S = struct {
375 fn doTheTest(comptime Int: type, thing: struct { int: Int }) !void {
376 try expect(thing.int == 123);
377 }
378 fn doTheTest2(comptime Int: type, comptime thing: struct { int: Int }) !void {
379 try expect(thing.int == 456);
380 }
381 };
382 try S.doTheTest(u32, .{ .int = 123 });
383 try S.doTheTest2(i32, .{ .int = 456 });
384}