| 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 | 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 | 1017 | switch (cc) { |
| 1018 | 1018 | case CallingConventionUnspecified: return "undefined"; |
| 1019 | 1019 | case CallingConventionC: return "ccc"; |
| ... | ... | @@ -1037,7 +1037,7 @@ static const char *calling_convention_fn_type_str(CallingConvention cc) { |
| 1037 | 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 | 1041 | switch (cc) { |
| 1042 | 1042 | case CallingConventionUnspecified: |
| 1043 | 1043 | case CallingConventionAsync: |
src/analyze.hpp+3| ... | ... | @@ -207,4 +207,7 @@ AstNode *type_decl_node(ZigType *type_entry); |
| 207 | 207 | |
| 208 | 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 | 213 | #endif |
src/ir.cpp+19-2| ... | ... | @@ -19595,6 +19595,7 @@ static ZigType *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 19595 | 19595 | } |
| 19596 | 19596 | |
| 19597 | 19597 | static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { |
| 19598 | Error err; | |
| 19598 | 19599 | AstNode *proto_node = instruction->base.source_node; |
| 19599 | 19600 | assert(proto_node->type == NodeTypeFnProto); |
| 19600 | 19601 | |
| ... | ... | @@ -19636,9 +19637,25 @@ static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnP |
| 19636 | 19637 | IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other; |
| 19637 | 19638 | if (type_is_invalid(param_type_value->value.type)) |
| 19638 | 19639 | return ira->codegen->builtin_types.entry_invalid; |
| 19639 | param_info->type = ir_resolve_type(ira, param_type_value); | |
| 19640 | if (type_is_invalid(param_info->type)) | |
| 19640 | ZigType *param_type = ir_resolve_type(ira, param_type_value); | |
| 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 | 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 | 674 | } |
| 675 | 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 | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | |
| 3 | 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 | 15 | cases.add( |
| 5 | 16 | "accessing runtime parameter from outer function", |
| 6 | 17 | \\fn outer(y: u32) fn (u32) u32 { |