| author | |
| committer | |
| log | 7782c76bee0201227be730ae131171939f728538 |
| tree | 9667fa7cc1ae51a61dd9fb4a5ad45579550b56e4 |
| parent | f90fe1f8f2be6ffa1c19997d123e12310d9e04b5 |
4 files changed, 50 insertions(+), 24 deletions(-)
src/analyze.cpp+20-22| ... | ... | @@ -1955,29 +1955,14 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 1955 | 1955 | return g->builtin_types.entry_invalid; |
| 1956 | 1956 | } |
| 1957 | 1957 | |
| 1958 | switch (specified_return_type->id) { | |
| 1959 | case ZigTypeIdInvalid: | |
| 1960 | zig_unreachable(); | |
| 1961 | ||
| 1962 | case ZigTypeIdUndefined: | |
| 1963 | case ZigTypeIdNull: | |
| 1964 | add_node_error(g, fn_proto->return_type, | |
| 1965 | buf_sprintf("return type '%s' not allowed", buf_ptr(&specified_return_type->name))); | |
| 1966 | return g->builtin_types.entry_invalid; | |
| 1967 | ||
| 1968 | case ZigTypeIdOpaque: | |
| 1969 | { | |
| 1970 | ErrorMsg* msg = add_node_error(g, fn_proto->return_type, | |
| 1971 | buf_sprintf("opaque return type '%s' not allowed", buf_ptr(&specified_return_type->name))); | |
| 1972 | Tld *tld = find_decl(g, &fn_entry->fndef_scope->base, &specified_return_type->name); | |
| 1973 | if (tld != nullptr) { | |
| 1974 | add_error_note(g, msg, tld->source_node, buf_sprintf("declared here")); | |
| 1975 | } | |
| 1976 | return g->builtin_types.entry_invalid; | |
| 1958 | if(!is_valid_return_type(specified_return_type)){ | |
| 1959 | ErrorMsg* msg = add_node_error(g, fn_proto->return_type, | |
| 1960 | buf_sprintf("return type '%s' not allowed", buf_ptr(&specified_return_type->name))); | |
| 1961 | Tld *tld = find_decl(g, &fn_entry->fndef_scope->base, &specified_return_type->name); | |
| 1962 | if (tld != nullptr) { | |
| 1963 | add_error_note(g, msg, tld->source_node, buf_sprintf("type declared here")); | |
| 1977 | 1964 | } |
| 1978 | ||
| 1979 | default: | |
| 1980 | break; | |
| 1965 | return g->builtin_types.entry_invalid; | |
| 1981 | 1966 | } |
| 1982 | 1967 | |
| 1983 | 1968 | if (fn_proto->auto_err_set) { |
| ... | ... | @@ -2049,6 +2034,19 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc |
| 2049 | 2034 | return get_fn_type(g, &fn_type_id); |
| 2050 | 2035 | } |
| 2051 | 2036 | |
| 2037 | bool is_valid_return_type(ZigType* type) { | |
| 2038 | switch (type->id) { | |
| 2039 | case ZigTypeIdInvalid: | |
| 2040 | case ZigTypeIdUndefined: | |
| 2041 | case ZigTypeIdNull: | |
| 2042 | case ZigTypeIdOpaque: | |
| 2043 | return false; | |
| 2044 | default: | |
| 2045 | return true; | |
| 2046 | } | |
| 2047 | zig_unreachable(); | |
| 2048 | } | |
| 2049 | ||
| 2052 | 2050 | bool type_is_invalid(ZigType *type_entry) { |
| 2053 | 2051 | switch (type_entry->id) { |
| 2054 | 2052 | case ZigTypeIdInvalid: |
src/analyze.hpp+1| ... | ... | @@ -265,6 +265,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType * |
| 265 | 265 | void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn); |
| 266 | 266 | bool fn_is_async(ZigFn *fn); |
| 267 | 267 | CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto); |
| 268 | bool is_valid_return_type(ZigType* type); | |
| 268 | 269 | |
| 269 | 270 | Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align); |
| 270 | 271 | Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val, |
src/ir.cpp+13| ... | ... | @@ -19339,6 +19339,19 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 19339 | 19339 | ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node); |
| 19340 | 19340 | if (type_is_invalid(specified_return_type)) |
| 19341 | 19341 | return ira->codegen->invalid_inst_gen; |
| 19342 | ||
| 19343 | if(!is_valid_return_type(specified_return_type)){ | |
| 19344 | ErrorMsg *msg = ir_add_error(ira, source_instr, | |
| 19345 | buf_sprintf("call to generic function with return type '%s' not allowed", buf_ptr(&specified_return_type->name))); | |
| 19346 | add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("function declared here")); | |
| 19347 | ||
| 19348 | Tld *tld = find_decl(ira->codegen, &fn_entry->fndef_scope->base, &specified_return_type->name); | |
| 19349 | if (tld != nullptr) { | |
| 19350 | add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("type declared here")); | |
| 19351 | } | |
| 19352 | return ira->codegen->invalid_inst_gen; | |
| 19353 | } | |
| 19354 | ||
| 19342 | 19355 | if (fn_proto_node->data.fn_proto.auto_err_set) { |
| 19343 | 19356 | ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); |
| 19344 | 19357 | if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) |
test/compile_errors.zig+16-2| ... | ... | @@ -6539,8 +6539,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6539 | 6539 | \\ return error.InvalidValue; |
| 6540 | 6540 | \\} |
| 6541 | 6541 | , &[_][]const u8{ |
| 6542 | "tmp.zig:2:18: error: opaque return type 'FooType' not allowed", | |
| 6543 | "tmp.zig:1:1: note: declared here", | |
| 6542 | "tmp.zig:2:18: error: return type 'FooType' not allowed", | |
| 6543 | "tmp.zig:1:1: note: type declared here", | |
| 6544 | }); | |
| 6545 | ||
| 6546 | cases.add("generic function returning opaque type", | |
| 6547 | \\const FooType = @OpaqueType(); | |
| 6548 | \\fn generic(comptime T: type) !T { | |
| 6549 | \\ return undefined; | |
| 6550 | \\} | |
| 6551 | \\export fn bar() void { | |
| 6552 | \\ _ = generic(FooType); | |
| 6553 | \\} | |
| 6554 | , &[_][]const u8{ | |
| 6555 | "tmp.zig:6:16: error: call to generic function with return type 'FooType' not allowed", | |
| 6556 | "tmp.zig:2:1: note: function declared here", | |
| 6557 | "tmp.zig:1:1: note: type declared here", | |
| 6544 | 6558 | }); |
| 6545 | 6559 | |
| 6546 | 6560 | cases.add( // fixed bug #2032 |