parent
1d8b8ad687
commit
6632d85e5f
@ -1013,7 +1013,7 @@ bool calling_convention_does_first_arg_return(CallingConvention cc) {
|
||||
return cc == CallingConventionUnspecified;
|
||||
}
|
||||
|
||||
static const char *calling_convention_name(CallingConvention cc) {
|
||||
const char *calling_convention_name(CallingConvention cc) {
|
||||
switch (cc) {
|
||||
case CallingConventionUnspecified: return "undefined";
|
||||
case CallingConventionC: return "ccc";
|
||||
@ -1037,7 +1037,7 @@ static const char *calling_convention_fn_type_str(CallingConvention cc) {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static bool calling_convention_allows_zig_types(CallingConvention cc) {
|
||||
bool calling_convention_allows_zig_types(CallingConvention cc) {
|
||||
switch (cc) {
|
||||
case CallingConventionUnspecified:
|
||||
case CallingConventionAsync:
|
||||
|
@ -207,4 +207,7 @@ AstNode *type_decl_node(ZigType *type_entry);
|
||||
|
||||
ZigType *get_primitive_type(CodeGen *g, Buf *name);
|
||||
|
||||
bool calling_convention_allows_zig_types(CallingConvention cc);
|
||||
const char *calling_convention_name(CallingConvention cc);
|
||||
|
||||
#endif
|
||||
|
21
src/ir.cpp
21
src/ir.cpp
@ -19595,6 +19595,7 @@ static ZigType *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
|
||||
}
|
||||
|
||||
static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) {
|
||||
Error err;
|
||||
AstNode *proto_node = instruction->base.source_node;
|
||||
assert(proto_node->type == NodeTypeFnProto);
|
||||
|
||||
@ -19636,9 +19637,25 @@ static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnP
|
||||
IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other;
|
||||
if (type_is_invalid(param_type_value->value.type))
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
param_info->type = ir_resolve_type(ira, param_type_value);
|
||||
if (type_is_invalid(param_info->type))
|
||||
ZigType *param_type = ir_resolve_type(ira, param_type_value);
|
||||
if (type_is_invalid(param_type))
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
if ((err = type_ensure_zero_bits_known(ira->codegen, param_type)))
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
if (type_requires_comptime(param_type)) {
|
||||
if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
|
||||
ir_add_error(ira, &instruction->base,
|
||||
buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'",
|
||||
buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc)));
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
param_info->type = param_type;
|
||||
fn_type_id.next_param_index += 1;
|
||||
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
|
||||
out_val->data.x_type = get_generic_fn_type(ira->codegen, &fn_type_id);
|
||||
return ira->codegen->builtin_types.entry_type;
|
||||
}
|
||||
param_info->type = param_type;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -674,3 +674,11 @@ test "inline for with same type but different values" {
|
||||
}
|
||||
assert(res == 5);
|
||||
}
|
||||
|
||||
test "refer to the type of a generic function" {
|
||||
const Func = fn (type) void;
|
||||
const f: Func = doNothingWithType;
|
||||
f(i32);
|
||||
}
|
||||
|
||||
fn doNothingWithType(comptime T: type) void {}
|
||||
|
@ -1,6 +1,17 @@
|
||||
const tests = @import("tests.zig");
|
||||
|
||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
cases.add(
|
||||
"refer to the type of a generic function",
|
||||
\\export fn entry() void {
|
||||
\\ const Func = fn (type) void;
|
||||
\\ const f: Func = undefined;
|
||||
\\ f(i32);
|
||||
\\}
|
||||
,
|
||||
".tmp_source.zig:4:5: error: use of undefined value",
|
||||
);
|
||||
|
||||
cases.add(
|
||||
"accessing runtime parameter from outer function",
|
||||
\\fn outer(y: u32) fn (u32) u32 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user