mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
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>
This commit is contained in:
parent
1149e8bb08
commit
fd43434149
2 changed files with 61 additions and 4 deletions
13
src/Sema.zig
13
src/Sema.zig
|
|
@ -10376,6 +10376,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||||
break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);
|
break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ret_ty_opt = if (info.return_type.tag() != .generic_poison)
|
||||||
|
try Value.Tag.opt_payload.create(
|
||||||
|
sema.arena,
|
||||||
|
try Value.Tag.ty.create(sema.arena, info.return_type),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Value.@"null";
|
||||||
|
|
||||||
const field_values = try sema.arena.create([6]Value);
|
const field_values = try sema.arena.create([6]Value);
|
||||||
field_values.* = .{
|
field_values.* = .{
|
||||||
// calling_convention: CallingConvention,
|
// calling_convention: CallingConvention,
|
||||||
|
|
@ -10387,10 +10395,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||||
// is_var_args: bool,
|
// is_var_args: bool,
|
||||||
Value.makeBool(info.is_var_args),
|
Value.makeBool(info.is_var_args),
|
||||||
// return_type: ?type,
|
// return_type: ?type,
|
||||||
try Value.Tag.opt_payload.create(
|
ret_ty_opt,
|
||||||
sema.arena,
|
|
||||||
try Value.Tag.ty.create(sema.arena, info.return_type),
|
|
||||||
),
|
|
||||||
// args: []const Fn.Param,
|
// args: []const Fn.Param,
|
||||||
args_val,
|
args_val,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -384,6 +384,58 @@ fn testFunction() !void {
|
||||||
extern fn foo(a: usize, b: bool, ...) callconv(.C) usize;
|
extern fn foo(a: usize, b: bool, ...) callconv(.C) usize;
|
||||||
extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize;
|
extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize;
|
||||||
|
|
||||||
|
test "type info: generic function types" {
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||||
|
|
||||||
|
if (builtin.zig_backend != .stage1) {
|
||||||
|
// stage1 marks all args/return types as null if the function
|
||||||
|
// is generic at all. stage2 is more specific.
|
||||||
|
const G1 = @typeInfo(@TypeOf(generic1));
|
||||||
|
try expect(G1.Fn.args.len == 1);
|
||||||
|
try expect(G1.Fn.args[0].is_generic == true);
|
||||||
|
try expect(G1.Fn.args[0].arg_type == null);
|
||||||
|
try expect(G1.Fn.return_type == void);
|
||||||
|
|
||||||
|
const G2 = @typeInfo(@TypeOf(generic2));
|
||||||
|
try expect(G2.Fn.args.len == 3);
|
||||||
|
try expect(G2.Fn.args[0].is_generic == false);
|
||||||
|
try expect(G2.Fn.args[0].arg_type == type);
|
||||||
|
try expect(G2.Fn.args[1].is_generic == true);
|
||||||
|
try expect(G2.Fn.args[1].arg_type == null);
|
||||||
|
try expect(G2.Fn.args[2].is_generic == false);
|
||||||
|
try expect(G2.Fn.args[2].arg_type == u8);
|
||||||
|
try expect(G2.Fn.return_type == void);
|
||||||
|
}
|
||||||
|
|
||||||
|
const G3 = @typeInfo(@TypeOf(generic3));
|
||||||
|
try expect(G3.Fn.args.len == 1);
|
||||||
|
try expect(G3.Fn.args[0].is_generic == true);
|
||||||
|
try expect(G3.Fn.args[0].arg_type == null);
|
||||||
|
try expect(G3.Fn.return_type == null);
|
||||||
|
|
||||||
|
const G4 = @typeInfo(@TypeOf(generic4));
|
||||||
|
try expect(G4.Fn.args.len == 1);
|
||||||
|
try expect(G4.Fn.args[0].is_generic == true);
|
||||||
|
try expect(G4.Fn.args[0].arg_type == null);
|
||||||
|
try expect(G4.Fn.return_type == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generic1(param: anytype) void {
|
||||||
|
_ = param;
|
||||||
|
}
|
||||||
|
fn generic2(comptime T: type, param: T, param2: u8) void {
|
||||||
|
_ = param;
|
||||||
|
_ = param2;
|
||||||
|
}
|
||||||
|
fn generic3(param: anytype) @TypeOf(param) {
|
||||||
|
_ = param;
|
||||||
|
}
|
||||||
|
fn generic4(comptime param: anytype) @TypeOf(param) {
|
||||||
|
_ = param;
|
||||||
|
}
|
||||||
|
|
||||||
test "typeInfo with comptime parameter in struct fn def" {
|
test "typeInfo with comptime parameter in struct fn def" {
|
||||||
const S = struct {
|
const S = struct {
|
||||||
pub fn func(comptime x: f32) void {
|
pub fn func(comptime x: f32) void {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue