-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Closed
Labels
proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone
Description
This is a proposal to add a builtin function that returns a tuple type.
Proposed signature:
fn @Tuple([]type) type
This would be a useful feature for metaprogramming purposes.
More specifically, it would be helpful in metaprograms that generate functions that forward arguments using @call
, as it could be used to generate non-generic function pointers that accept tuple types calculated at comptime.
Currently, passing a tuple requires the argument to be 'var' and forces the function to be generic.
Here is an example usecase from the std.interface PR:
// Here, we are generating a type erased version of a method
const args = @typeInfo(fn_decl.fn_type).Fn.args;
// [...] Omitted code, compute our_cc, Return, CurrSelfType, is_const
// Actual function generation
// Currently, there is no way to avoid the following switch statement.
return switch (args.len) {
1 => struct {
fn impl(self_ptr: CurrSelfType) Return {
const self = if (is_const) constSelfPtrAs(self_ptr, ImplT) else selfPtrAs(self_ptr, ImplT);
const f = @field(self, name);
return @call(if (our_cc == .Async) .{ .modifier = .async_kw } else .{ .modifier = .always_inline }, f, .{});
}
}.impl,
2 => struct {
fn impl(self_ptr: CurrSelfType, arg: args[1].arg_type.?) Return {
const self = if (is_const) constSelfPtrAs(self_ptr, ImplT) else selfPtrAs(self_ptr, ImplT);
const f = @field(self, name);
return @call(if (our_cc == .Async) .{ .modifier = .async_kw } else .{ .modifier = .always_inline }, f, .{arg});
}
}.impl,
// [...] Omitted 3 to 6
else => @compileError("Unsupported number of arguments, please provide a manually written vtable."),
};
// With this proposal
var arg_type_arr: [args.len - 1]type = undefined;
for (args[1..]) |arg, i| {
arg_type_arr[i] = arg.arg_type.?;
}
const ArgPackType = @Tuple(arg_type_arr[0..]);
// Call site of generated function also changes from @call(..., .{self, a1,..., aN}) to @call(..., .{self, .{a1, ..., aN} });
return struct {
fn impl(self_ptr: CurrSelfType, args: ArgPackType) Return {
const self = if (is_const) constSelfPtrAs(self_ptr, ImplT) else selfPtrAs(self_ptr, ImplT);
const f = @field(self, name);
return @call(if (our_cc == .Async) .{ .modifier = .async_kw } else .{ .modifier = .always_inline }, f, args);
}
}.impl;
mlarouche, ikskuh, SpexGuy, schroffl, data-man and 2 more
Metadata
Metadata
Assignees
Labels
proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.This issue suggests modifications. If it also has the "accepted" label then it is planned.