authorgravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-15 15:53:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-15 20:12:22-04:00
logfd43434149658ee482428714e05722e5a12fdecc
treea2741731117e8a3cfc1f20232ef393f3434c064a
parent1149e8bb088f48e29f3abc06196b1134f5e1c42f

stage2: TypeInfo for func with generic return type should set null

Prior to these, the return type was non-null but the value was generic poison which wasn't usable in user-space. This sets the value to null. This also adds a behavior test for this. Co-authored-by: InKryption <inkryption07@gmail.com>

2 files changed, 61 insertions(+), 4 deletions(-)

src/Sema.zig+9-4
......@@ -10376,6 +10376,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1037610376 break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);
1037710377 };
1037810378
10379 const ret_ty_opt = if (info.return_type.tag() != .generic_poison)
10380 try Value.Tag.opt_payload.create(
10381 sema.arena,
10382 try Value.Tag.ty.create(sema.arena, info.return_type),
10383 )
10384 else
10385 Value.@"null";
10386
1037910387 const field_values = try sema.arena.create([6]Value);
1038010388 field_values.* = .{
1038110389 // calling_convention: CallingConvention,
......@@ -10387,10 +10395,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1038710395 // is_var_args: bool,
1038810396 Value.makeBool(info.is_var_args),
1038910397 // return_type: ?type,
10390 try Value.Tag.opt_payload.create(
10391 sema.arena,
10392 try Value.Tag.ty.create(sema.arena, info.return_type),
10393 ),
10398 ret_ty_opt,
1039410399 // args: []const Fn.Param,
1039510400 args_val,
1039610401 };
test/behavior/type_info.zig+52
......@@ -384,6 +384,58 @@ fn testFunction() !void {
384384extern fn foo(a: usize, b: bool, ...) callconv(.C) usize;
385385extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize;
386386
387test "type info: generic function types" {
388 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
389 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
390 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
391
392 if (builtin.zig_backend != .stage1) {
393 // stage1 marks all args/return types as null if the function
394 // is generic at all. stage2 is more specific.
395 const G1 = @typeInfo(@TypeOf(generic1));
396 try expect(G1.Fn.args.len == 1);
397 try expect(G1.Fn.args[0].is_generic == true);
398 try expect(G1.Fn.args[0].arg_type == null);
399 try expect(G1.Fn.return_type == void);
400
401 const G2 = @typeInfo(@TypeOf(generic2));
402 try expect(G2.Fn.args.len == 3);
403 try expect(G2.Fn.args[0].is_generic == false);
404 try expect(G2.Fn.args[0].arg_type == type);
405 try expect(G2.Fn.args[1].is_generic == true);
406 try expect(G2.Fn.args[1].arg_type == null);
407 try expect(G2.Fn.args[2].is_generic == false);
408 try expect(G2.Fn.args[2].arg_type == u8);
409 try expect(G2.Fn.return_type == void);
410 }
411
412 const G3 = @typeInfo(@TypeOf(generic3));
413 try expect(G3.Fn.args.len == 1);
414 try expect(G3.Fn.args[0].is_generic == true);
415 try expect(G3.Fn.args[0].arg_type == null);
416 try expect(G3.Fn.return_type == null);
417
418 const G4 = @typeInfo(@TypeOf(generic4));
419 try expect(G4.Fn.args.len == 1);
420 try expect(G4.Fn.args[0].is_generic == true);
421 try expect(G4.Fn.args[0].arg_type == null);
422 try expect(G4.Fn.return_type == null);
423}
424
425fn generic1(param: anytype) void {
426 _ = param;
427}
428fn generic2(comptime T: type, param: T, param2: u8) void {
429 _ = param;
430 _ = param2;
431}
432fn generic3(param: anytype) @TypeOf(param) {
433 _ = param;
434}
435fn generic4(comptime param: anytype) @TypeOf(param) {
436 _ = param;
437}
438
387439test "typeInfo with comptime parameter in struct fn def" {
388440 const S = struct {
389441 pub fn func(comptime x: f32) void {