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) {...@@ -1013,7 +1013,7 @@ bool calling_convention_does_first_arg_return(CallingConvention cc) {
1013 return cc == CallingConventionUnspecified;1013 return cc == CallingConventionUnspecified;
1014}1014}
10151015
1016static const char *calling_convention_name(CallingConvention cc) {1016const 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}
10391039
1040static bool calling_convention_allows_zig_types(CallingConvention cc) {1040bool 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);
207207
208ZigType *get_primitive_type(CodeGen *g, Buf *name);208ZigType *get_primitive_type(CodeGen *g, Buf *name);
209209
210bool calling_convention_allows_zig_types(CallingConvention cc);
211const char *calling_convention_name(CallingConvention cc);
212
210#endif213#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}
1959619596
19597static ZigType *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) {19597static 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);
1960019601
...@@ -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 }
1964319660
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
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 @@...@@ -1,6 +1,17 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub 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 {