authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-09 22:10:57-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-03-09 22:10:57-04:00
log675f01f1768aa08c307640b53e8a5240fa190fab
tree14702a748268e301cf5fc23a0d28221c487fae7e
parent1f44b29724b52433d84b43345a52da59f9220e62
parente7cc45642138472c29e09cd10e31962426c1aba5
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4590 from xackus/fix-4587

fix failed assert on generic fn opaque return type

4 files changed, 68 insertions(+), 24 deletions(-)

src/analyze.cpp+20-22
...@@ -1962,29 +1962,14 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -1962,29 +1962,14 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
1962 return g->builtin_types.entry_invalid;1962 return g->builtin_types.entry_invalid;
1963 }1963 }
19641964
1965 switch (specified_return_type->id) {1965 if(!is_valid_return_type(specified_return_type)){
1966 case ZigTypeIdInvalid:1966 ErrorMsg* msg = add_node_error(g, fn_proto->return_type,
1967 zig_unreachable();1967 buf_sprintf("%s return type '%s' not allowed", type_id_name(specified_return_type->id), buf_ptr(&specified_return_type->name)));
19681968 Tld *tld = find_decl(g, &fn_entry->fndef_scope->base, &specified_return_type->name);
1969 case ZigTypeIdUndefined:1969 if (tld != nullptr) {
1970 case ZigTypeIdNull:1970 add_error_note(g, msg, tld->source_node, buf_sprintf("type declared here"));
1971 add_node_error(g, fn_proto->return_type,
1972 buf_sprintf("return type '%s' not allowed", buf_ptr(&specified_return_type->name)));
1973 return g->builtin_types.entry_invalid;
1974
1975 case ZigTypeIdOpaque:
1976 {
1977 ErrorMsg* msg = add_node_error(g, fn_proto->return_type,
1978 buf_sprintf("opaque return type '%s' not allowed", buf_ptr(&specified_return_type->name)));
1979 Tld *tld = find_decl(g, &fn_entry->fndef_scope->base, &specified_return_type->name);
1980 if (tld != nullptr) {
1981 add_error_note(g, msg, tld->source_node, buf_sprintf("declared here"));
1982 }
1983 return g->builtin_types.entry_invalid;
1984 }1971 }
19851972 return g->builtin_types.entry_invalid;
1986 default:
1987 break;
1988 }1973 }
19891974
1990 if (fn_proto->auto_err_set) {1975 if (fn_proto->auto_err_set) {
...@@ -2056,6 +2041,19 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc...@@ -2056,6 +2041,19 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
2056 return get_fn_type(g, &fn_type_id);2041 return get_fn_type(g, &fn_type_id);
2057}2042}
20582043
2044bool is_valid_return_type(ZigType* type) {
2045 switch (type->id) {
2046 case ZigTypeIdInvalid:
2047 case ZigTypeIdUndefined:
2048 case ZigTypeIdNull:
2049 case ZigTypeIdOpaque:
2050 return false;
2051 default:
2052 return true;
2053 }
2054 zig_unreachable();
2055}
2056
2059bool type_is_invalid(ZigType *type_entry) {2057bool type_is_invalid(ZigType *type_entry) {
2060 switch (type_entry->id) {2058 switch (type_entry->id) {
2061 case ZigTypeIdInvalid:2059 case ZigTypeIdInvalid:
src/analyze.hpp+1
...@@ -267,6 +267,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *...@@ -267,6 +267,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *
267void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);267void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
268bool fn_is_async(ZigFn *fn);268bool fn_is_async(ZigFn *fn);
269CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto);269CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto);
270bool is_valid_return_type(ZigType* type);
270271
271Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align);272Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align);
272Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,273Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,
src/ir.cpp+13
...@@ -19392,6 +19392,19 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -19392,6 +19392,19 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
19392 ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node);19392 ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node);
19393 if (type_is_invalid(specified_return_type))19393 if (type_is_invalid(specified_return_type))
19394 return ira->codegen->invalid_inst_gen;19394 return ira->codegen->invalid_inst_gen;
19395
19396 if(!is_valid_return_type(specified_return_type)){
19397 ErrorMsg *msg = ir_add_error(ira, source_instr,
19398 buf_sprintf("call to generic function with %s return type '%s' not allowed", type_id_name(specified_return_type->id), buf_ptr(&specified_return_type->name)));
19399 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("function declared here"));
19400
19401 Tld *tld = find_decl(ira->codegen, &fn_entry->fndef_scope->base, &specified_return_type->name);
19402 if (tld != nullptr) {
19403 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("type declared here"));
19404 }
19405 return ira->codegen->invalid_inst_gen;
19406 }
19407
19395 if (fn_proto_node->data.fn_proto.auto_err_set) {19408 if (fn_proto_node->data.fn_proto.auto_err_set) {
19396 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn);19409 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn);
19397 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown)))19410 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown)))
test/compile_errors.zig+34-2
...@@ -6558,9 +6558,41 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6558,9 +6558,41 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6558 \\export fn bar() !FooType {6558 \\export fn bar() !FooType {
6559 \\ return error.InvalidValue;6559 \\ return error.InvalidValue;
6560 \\}6560 \\}
6561 \\export fn bav() !@TypeOf(null) {
6562 \\ return error.InvalidValue;
6563 \\}
6564 \\export fn baz() !@TypeOf(undefined) {
6565 \\ return error.InvalidValue;
6566 \\}
6561 , &[_][]const u8{6567 , &[_][]const u8{
6562 "tmp.zig:2:18: error: opaque return type 'FooType' not allowed",6568 "tmp.zig:2:18: error: Opaque return type 'FooType' not allowed",
6563 "tmp.zig:1:1: note: declared here",6569 "tmp.zig:1:1: note: type declared here",
6570 "tmp.zig:5:18: error: Null return type '(null)' not allowed",
6571 "tmp.zig:8:18: error: Undefined return type '(undefined)' not allowed",
6572 });
6573
6574 cases.add("generic function returning opaque type",
6575 \\const FooType = @OpaqueType();
6576 \\fn generic(comptime T: type) !T {
6577 \\ return undefined;
6578 \\}
6579 \\export fn bar() void {
6580 \\ _ = generic(FooType);
6581 \\}
6582 \\export fn bav() void {
6583 \\ _ = generic(@TypeOf(null));
6584 \\}
6585 \\export fn baz() void {
6586 \\ _ = generic(@TypeOf(undefined));
6587 \\}
6588 , &[_][]const u8{
6589 "tmp.zig:6:16: error: call to generic function with Opaque return type 'FooType' not allowed",
6590 "tmp.zig:2:1: note: function declared here",
6591 "tmp.zig:1:1: note: type declared here",
6592 "tmp.zig:9:16: error: call to generic function with Null return type '(null)' not allowed",
6593 "tmp.zig:2:1: note: function declared here",
6594 "tmp.zig:12:16: error: call to generic function with Undefined return type '(undefined)' not allowed",
6595 "tmp.zig:2:1: note: function declared here",
6564 });6596 });
65656597
6566 cases.add( // fixed bug #20326598 cases.add( // fixed bug #2032