| author | |
| committer | |
| log | 675f01f1768aa08c307640b53e8a5240fa190fab |
| tree | 14702a748268e301cf5fc23a0d28221c487fae7e |
| parent | 1f44b29724b52433d84b43345a52da59f9220e62 |
| parent | e7cc45642138472c29e09cd10e31962426c1aba5 |
| signature |
fix failed assert on generic fn opaque return type4 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 | } |
| 1964 | 1964 | ||
| 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))); |
| 1968 | 1968 | 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 | } |
| 1985 | 1972 | return g->builtin_types.entry_invalid; | |
| 1986 | default: | ||
| 1987 | break; | ||
| 1988 | } | 1973 | } |
| 1989 | 1974 | ||
| 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 | } |
| 2058 | 2043 | ||
| 2044 | bool 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 | |||
| 2059 | bool type_is_invalid(ZigType *type_entry) { | 2057 | bool 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 * |
| 267 | void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); | 267 | void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); |
| 268 | bool fn_is_async(ZigFn *fn); | 268 | bool fn_is_async(ZigFn *fn); |
| 269 | CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto); | 269 | CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto); |
| 270 | bool is_valid_return_type(ZigType* type); | ||
| 270 | 271 | ||
| 271 | Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align); | 272 | Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align); |
| 272 | Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val, | 273 | Error 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 | }); |
| 6565 | 6597 | ||
| 6566 | cases.add( // fixed bug #2032 | 6598 | cases.add( // fixed bug #2032 |