commit 3525b8778edd235d8d0ad2b55eee83eacd33d5cf (tree)
parent ede379848525dce72c6e903b1895ac3e4acaf3ef
Author: Veikka Tuominen <git@vexu.eu>
Date: Fri, 23 Sep 2022 16:55:46 +0300
Sema: properly handle generic struct as parameter type
Closes #12907
Diffstat:
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git 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
@@ -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 });
+}