parent
1d8b8ad687
commit
6632d85e5f
@ -1013,7 +1013,7 @@ bool calling_convention_does_first_arg_return(CallingConvention cc) {
|
|||||||
return cc == CallingConventionUnspecified;
|
return cc == CallingConventionUnspecified;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *calling_convention_name(CallingConvention cc) {
|
const char *calling_convention_name(CallingConvention cc) {
|
||||||
switch (cc) {
|
switch (cc) {
|
||||||
case CallingConventionUnspecified: return "undefined";
|
case CallingConventionUnspecified: return "undefined";
|
||||||
case CallingConventionC: return "ccc";
|
case CallingConventionC: return "ccc";
|
||||||
@ -1037,7 +1037,7 @@ static const char *calling_convention_fn_type_str(CallingConvention cc) {
|
|||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool calling_convention_allows_zig_types(CallingConvention cc) {
|
bool calling_convention_allows_zig_types(CallingConvention cc) {
|
||||||
switch (cc) {
|
switch (cc) {
|
||||||
case CallingConventionUnspecified:
|
case CallingConventionUnspecified:
|
||||||
case CallingConventionAsync:
|
case CallingConventionAsync:
|
||||||
|
@ -207,4 +207,7 @@ AstNode *type_decl_node(ZigType *type_entry);
|
|||||||
|
|
||||||
ZigType *get_primitive_type(CodeGen *g, Buf *name);
|
ZigType *get_primitive_type(CodeGen *g, Buf *name);
|
||||||
|
|
||||||
|
bool calling_convention_allows_zig_types(CallingConvention cc);
|
||||||
|
const char *calling_convention_name(CallingConvention cc);
|
||||||
|
|
||||||
#endif
|
#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) {
|
static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) {
|
||||||
|
Error err;
|
||||||
AstNode *proto_node = instruction->base.source_node;
|
AstNode *proto_node = instruction->base.source_node;
|
||||||
assert(proto_node->type == NodeTypeFnProto);
|
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;
|
IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other;
|
||||||
if (type_is_invalid(param_type_value->value.type))
|
if (type_is_invalid(param_type_value->value.type))
|
||||||
return ira->codegen->builtin_types.entry_invalid;
|
return ira->codegen->builtin_types.entry_invalid;
|
||||||
param_info->type = ir_resolve_type(ira, param_type_value);
|
ZigType *param_type = ir_resolve_type(ira, param_type_value);
|
||||||
if (type_is_invalid(param_info->type))
|
if (type_is_invalid(param_type))
|
||||||
return ira->codegen->builtin_types.entry_invalid;
|
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);
|
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");
|
const tests = @import("tests.zig");
|
||||||
|
|
||||||
pub fn addCases(cases: *tests.CompileErrorContext) void {
|
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(
|
cases.add(
|
||||||
"accessing runtime parameter from outer function",
|
"accessing runtime parameter from outer function",
|
||||||
\\fn outer(y: u32) fn (u32) u32 {
|
\\fn outer(y: u32) fn (u32) u32 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user