authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-05 21:21:59-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-05 21:21:59-04:00
log6632d85e5f1120784b3eb0a7ab8be0792ba27b85
treec9665957482dcb85e70ab9dd17954dfacb0d6961
parent1d8b8ad687facd25a27b3ff6d083812b45cd529f
signaturelock-open Commit is signed but in an unrecognized format.

stage1: improve handling of generic fn proto type expr

closes #902

5 files changed, 43 insertions(+), 4 deletions(-)

src/analyze.cpp+2-2
......@@ -1013,7 +1013,7 @@ bool calling_convention_does_first_arg_return(CallingConvention cc) {
10131013 return cc == CallingConventionUnspecified;
10141014}
10151015
1016static const char *calling_convention_name(CallingConvention cc) {
1016const char *calling_convention_name(CallingConvention cc) {
10171017 switch (cc) {
10181018 case CallingConventionUnspecified: return "undefined";
10191019 case CallingConventionC: return "ccc";
......@@ -1037,7 +1037,7 @@ static const char *calling_convention_fn_type_str(CallingConvention cc) {
10371037 zig_unreachable();
10381038}
10391039
1040static bool calling_convention_allows_zig_types(CallingConvention cc) {
1040bool calling_convention_allows_zig_types(CallingConvention cc) {
10411041 switch (cc) {
10421042 case CallingConventionUnspecified:
10431043 case CallingConventionAsync:
src/analyze.hpp+3
......@@ -207,4 +207,7 @@ AstNode *type_decl_node(ZigType *type_entry);
207207
208208ZigType *get_primitive_type(CodeGen *g, Buf *name);
209209
210bool calling_convention_allows_zig_types(CallingConvention cc);
211const char *calling_convention_name(CallingConvention cc);
212
210213#endif
src/ir.cpp+19-2
......@@ -19595,6 +19595,7 @@ static ZigType *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
1959519595}
1959619596
1959719597static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) {
19598 Error err;
1959819599 AstNode *proto_node = instruction->base.source_node;
1959919600 assert(proto_node->type == NodeTypeFnProto);
1960019601
......@@ -19636,9 +19637,25 @@ static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnP
1963619637 IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other;
1963719638 if (type_is_invalid(param_type_value->value.type))
1963819639 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)))
1964119644 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;
1964219659 }
1964319660
1964419661 }
test/cases/eval.zig+8
......@@ -674,3 +674,11 @@ test "inline for with same type but different values" {
674674 }
675675 assert(res == 5);
676676}
677
678test "refer to the type of a generic function" {
679 const Func = fn (type) void;
680 const f: Func = doNothingWithType;
681 f(i32);
682}
683
684fn doNothingWithType(comptime T: type) void {}
test/compile_errors.zig+11
......@@ -1,6 +1,17 @@
11const tests = @import("tests.zig");
22
33pub 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
415 cases.add(
516 "accessing runtime parameter from outer function",
617 \\fn outer(y: u32) fn (u32) u32 {