| author | |
| committer | |
| log | 6632d85e5f1120784b3eb0a7ab8be0792ba27b85 |
| tree | c9665957482dcb85e70ab9dd17954dfacb0d6961 |
| parent | 1d8b8ad687facd25a27b3ff6d083812b45cd529f |
| signature |
closes #9025 files changed, 43 insertions(+), 4 deletions(-)
src/analyze.cpp+2-2| ... | @@ -1013,7 +1013,7 @@ bool calling_convention_does_first_arg_return(CallingConvention cc) { | ... | @@ -1013,7 +1013,7 @@ bool calling_convention_does_first_arg_return(CallingConvention cc) { |
| 1013 | return cc == CallingConventionUnspecified; | 1013 | return cc == CallingConventionUnspecified; |
| 1014 | } | 1014 | } |
| 1015 | 1015 | ||
| 1016 | static const char *calling_convention_name(CallingConvention cc) { | 1016 | const char *calling_convention_name(CallingConvention cc) { |
| 1017 | switch (cc) { | 1017 | switch (cc) { |
| 1018 | case CallingConventionUnspecified: return "undefined"; | 1018 | case CallingConventionUnspecified: return "undefined"; |
| 1019 | case CallingConventionC: return "ccc"; | 1019 | case CallingConventionC: return "ccc"; |
| ... | @@ -1037,7 +1037,7 @@ static const char *calling_convention_fn_type_str(CallingConvention cc) { | ... | @@ -1037,7 +1037,7 @@ static const char *calling_convention_fn_type_str(CallingConvention cc) { |
| 1037 | zig_unreachable(); | 1037 | zig_unreachable(); |
| 1038 | } | 1038 | } |
| 1039 | 1039 | ||
| 1040 | static bool calling_convention_allows_zig_types(CallingConvention cc) { | 1040 | bool calling_convention_allows_zig_types(CallingConvention cc) { |
| 1041 | switch (cc) { | 1041 | switch (cc) { |
| 1042 | case CallingConventionUnspecified: | 1042 | case CallingConventionUnspecified: |
| 1043 | case CallingConventionAsync: | 1043 | case CallingConventionAsync: |
src/analyze.hpp+3| ... | @@ -207,4 +207,7 @@ AstNode *type_decl_node(ZigType *type_entry); | ... | @@ -207,4 +207,7 @@ AstNode *type_decl_node(ZigType *type_entry); |
| 207 | 207 | ||
| 208 | ZigType *get_primitive_type(CodeGen *g, Buf *name); | 208 | ZigType *get_primitive_type(CodeGen *g, Buf *name); |
| 209 | 209 | ||
| 210 | bool calling_convention_allows_zig_types(CallingConvention cc); | ||
| 211 | const char *calling_convention_name(CallingConvention cc); | ||
| 212 | |||
| 210 | #endif | 213 | #endif |
src/ir.cpp+19-2| ... | @@ -19595,6 +19595,7 @@ static ZigType *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -19595,6 +19595,7 @@ static ZigType *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 19595 | } | 19595 | } |
| 19596 | 19596 | ||
| 19597 | static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { | 19597 | static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { |
| 19598 | Error err; | ||
| 19598 | AstNode *proto_node = instruction->base.source_node; | 19599 | AstNode *proto_node = instruction->base.source_node; |
| 19599 | assert(proto_node->type == NodeTypeFnProto); | 19600 | assert(proto_node->type == NodeTypeFnProto); |
| 19600 | 19601 | ||
| ... | @@ -19636,9 +19637,25 @@ static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnP | ... | @@ -19636,9 +19637,25 @@ static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnP |
| 19636 | IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other; | 19637 | IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other; |
| 19637 | if (type_is_invalid(param_type_value->value.type)) | 19638 | if (type_is_invalid(param_type_value->value.type)) |
| 19638 | return ira->codegen->builtin_types.entry_invalid; | 19639 | return ira->codegen->builtin_types.entry_invalid; |
| 19639 | param_info->type = ir_resolve_type(ira, param_type_value); | 19640 | ZigType *param_type = ir_resolve_type(ira, param_type_value); |
| 19640 | if (type_is_invalid(param_info->type)) | 19641 | if (type_is_invalid(param_type)) |
| 19642 | return ira->codegen->builtin_types.entry_invalid; | ||
| 19643 | if ((err = type_ensure_zero_bits_known(ira->codegen, param_type))) | ||
| 19641 | return ira->codegen->builtin_types.entry_invalid; | 19644 | return ira->codegen->builtin_types.entry_invalid; |
| 19645 | if (type_requires_comptime(param_type)) { | ||
| 19646 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { | ||
| 19647 | ir_add_error(ira, &instruction->base, | ||
| 19648 | buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", | ||
| 19649 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); | ||
| 19650 | return ira->codegen->builtin_types.entry_invalid; | ||
| 19651 | } | ||
| 19652 | param_info->type = param_type; | ||
| 19653 | fn_type_id.next_param_index += 1; | ||
| 19654 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | ||
| 19655 | out_val->data.x_type = get_generic_fn_type(ira->codegen, &fn_type_id); | ||
| 19656 | return ira->codegen->builtin_types.entry_type; | ||
| 19657 | } | ||
| 19658 | param_info->type = param_type; | ||
| 19642 | } | 19659 | } |
| 19643 | 19660 | ||
| 19644 | } | 19661 | } |
test/cases/eval.zig+8| ... | @@ -674,3 +674,11 @@ test "inline for with same type but different values" { | ... | @@ -674,3 +674,11 @@ test "inline for with same type but different values" { |
| 674 | } | 674 | } |
| 675 | assert(res == 5); | 675 | assert(res == 5); |
| 676 | } | 676 | } |
| 677 | |||
| 678 | test "refer to the type of a generic function" { | ||
| 679 | const Func = fn (type) void; | ||
| 680 | const f: Func = doNothingWithType; | ||
| 681 | f(i32); | ||
| 682 | } | ||
| 683 | |||
| 684 | fn doNothingWithType(comptime T: type) void {} |
test/compile_errors.zig+11| ... | @@ -1,6 +1,17 @@ | ... | @@ -1,6 +1,17 @@ |
| 1 | const tests = @import("tests.zig"); | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | ||
| 3 | pub fn addCases(cases: *tests.CompileErrorContext) void { | 3 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4 | cases.add( | ||
| 5 | "refer to the type of a generic function", | ||
| 6 | \\export fn entry() void { | ||
| 7 | \\ const Func = fn (type) void; | ||
| 8 | \\ const f: Func = undefined; | ||
| 9 | \\ f(i32); | ||
| 10 | \\} | ||
| 11 | , | ||
| 12 | ".tmp_source.zig:4:5: error: use of undefined value", | ||
| 13 | ); | ||
| 14 | |||
| 4 | cases.add( | 15 | cases.add( |
| 5 | "accessing runtime parameter from outer function", | 16 | "accessing runtime parameter from outer function", |
| 6 | \\fn outer(y: u32) fn (u32) u32 { | 17 | \\fn outer(y: u32) fn (u32) u32 { |