Merge pull request #4590 from xackus/fix-4587
fix failed assert on generic fn opaque return type
This commit is contained in:
commit
675f01f176
@ -1962,29 +1962,14 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
|||||||
return g->builtin_types.entry_invalid;
|
return g->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (specified_return_type->id) {
|
if(!is_valid_return_type(specified_return_type)){
|
||||||
case ZigTypeIdInvalid:
|
ErrorMsg* msg = add_node_error(g, fn_proto->return_type,
|
||||||
zig_unreachable();
|
buf_sprintf("%s return type '%s' not allowed", type_id_name(specified_return_type->id), buf_ptr(&specified_return_type->name)));
|
||||||
|
Tld *tld = find_decl(g, &fn_entry->fndef_scope->base, &specified_return_type->name);
|
||||||
case ZigTypeIdUndefined:
|
if (tld != nullptr) {
|
||||||
case ZigTypeIdNull:
|
add_error_note(g, msg, tld->source_node, buf_sprintf("type declared here"));
|
||||||
add_node_error(g, fn_proto->return_type,
|
|
||||||
buf_sprintf("return type '%s' not allowed", buf_ptr(&specified_return_type->name)));
|
|
||||||
return g->builtin_types.entry_invalid;
|
|
||||||
|
|
||||||
case ZigTypeIdOpaque:
|
|
||||||
{
|
|
||||||
ErrorMsg* msg = add_node_error(g, fn_proto->return_type,
|
|
||||||
buf_sprintf("opaque return type '%s' not allowed", buf_ptr(&specified_return_type->name)));
|
|
||||||
Tld *tld = find_decl(g, &fn_entry->fndef_scope->base, &specified_return_type->name);
|
|
||||||
if (tld != nullptr) {
|
|
||||||
add_error_note(g, msg, tld->source_node, buf_sprintf("declared here"));
|
|
||||||
}
|
|
||||||
return g->builtin_types.entry_invalid;
|
|
||||||
}
|
}
|
||||||
|
return g->builtin_types.entry_invalid;
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fn_proto->auto_err_set) {
|
if (fn_proto->auto_err_set) {
|
||||||
@ -2056,6 +2041,19 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
|
|||||||
return get_fn_type(g, &fn_type_id);
|
return get_fn_type(g, &fn_type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_valid_return_type(ZigType* type) {
|
||||||
|
switch (type->id) {
|
||||||
|
case ZigTypeIdInvalid:
|
||||||
|
case ZigTypeIdUndefined:
|
||||||
|
case ZigTypeIdNull:
|
||||||
|
case ZigTypeIdOpaque:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
bool type_is_invalid(ZigType *type_entry) {
|
bool type_is_invalid(ZigType *type_entry) {
|
||||||
switch (type_entry->id) {
|
switch (type_entry->id) {
|
||||||
case ZigTypeIdInvalid:
|
case ZigTypeIdInvalid:
|
||||||
|
@ -267,6 +267,7 @@ ZigValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *
|
|||||||
void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
|
void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn);
|
||||||
bool fn_is_async(ZigFn *fn);
|
bool fn_is_async(ZigFn *fn);
|
||||||
CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto);
|
CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto);
|
||||||
|
bool is_valid_return_type(ZigType* type);
|
||||||
|
|
||||||
Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align);
|
Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *type_val, uint32_t *abi_align);
|
||||||
Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,
|
Error type_val_resolve_abi_size(CodeGen *g, AstNode *source_node, ZigValue *type_val,
|
||||||
|
13
src/ir.cpp
13
src/ir.cpp
@ -19392,6 +19392,19 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
|||||||
ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node);
|
ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node);
|
||||||
if (type_is_invalid(specified_return_type))
|
if (type_is_invalid(specified_return_type))
|
||||||
return ira->codegen->invalid_inst_gen;
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
|
||||||
|
if(!is_valid_return_type(specified_return_type)){
|
||||||
|
ErrorMsg *msg = ir_add_error(ira, source_instr,
|
||||||
|
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)));
|
||||||
|
add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("function declared here"));
|
||||||
|
|
||||||
|
Tld *tld = find_decl(ira->codegen, &fn_entry->fndef_scope->base, &specified_return_type->name);
|
||||||
|
if (tld != nullptr) {
|
||||||
|
add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("type declared here"));
|
||||||
|
}
|
||||||
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
}
|
||||||
|
|
||||||
if (fn_proto_node->data.fn_proto.auto_err_set) {
|
if (fn_proto_node->data.fn_proto.auto_err_set) {
|
||||||
ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn);
|
ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn);
|
||||||
if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown)))
|
if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown)))
|
||||||
|
@ -6558,9 +6558,41 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
|||||||
\\export fn bar() !FooType {
|
\\export fn bar() !FooType {
|
||||||
\\ return error.InvalidValue;
|
\\ return error.InvalidValue;
|
||||||
\\}
|
\\}
|
||||||
|
\\export fn bav() !@TypeOf(null) {
|
||||||
|
\\ return error.InvalidValue;
|
||||||
|
\\}
|
||||||
|
\\export fn baz() !@TypeOf(undefined) {
|
||||||
|
\\ return error.InvalidValue;
|
||||||
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
"tmp.zig:2:18: error: opaque return type 'FooType' not allowed",
|
"tmp.zig:2:18: error: Opaque return type 'FooType' not allowed",
|
||||||
"tmp.zig:1:1: note: declared here",
|
"tmp.zig:1:1: note: type declared here",
|
||||||
|
"tmp.zig:5:18: error: Null return type '(null)' not allowed",
|
||||||
|
"tmp.zig:8:18: error: Undefined return type '(undefined)' not allowed",
|
||||||
|
});
|
||||||
|
|
||||||
|
cases.add("generic function returning opaque type",
|
||||||
|
\\const FooType = @OpaqueType();
|
||||||
|
\\fn generic(comptime T: type) !T {
|
||||||
|
\\ return undefined;
|
||||||
|
\\}
|
||||||
|
\\export fn bar() void {
|
||||||
|
\\ _ = generic(FooType);
|
||||||
|
\\}
|
||||||
|
\\export fn bav() void {
|
||||||
|
\\ _ = generic(@TypeOf(null));
|
||||||
|
\\}
|
||||||
|
\\export fn baz() void {
|
||||||
|
\\ _ = generic(@TypeOf(undefined));
|
||||||
|
\\}
|
||||||
|
, &[_][]const u8{
|
||||||
|
"tmp.zig:6:16: error: call to generic function with Opaque return type 'FooType' not allowed",
|
||||||
|
"tmp.zig:2:1: note: function declared here",
|
||||||
|
"tmp.zig:1:1: note: type declared here",
|
||||||
|
"tmp.zig:9:16: error: call to generic function with Null return type '(null)' not allowed",
|
||||||
|
"tmp.zig:2:1: note: function declared here",
|
||||||
|
"tmp.zig:12:16: error: call to generic function with Undefined return type '(undefined)' not allowed",
|
||||||
|
"tmp.zig:2:1: note: function declared here",
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.add( // fixed bug #2032
|
cases.add( // fixed bug #2032
|
||||||
|
Loading…
x
Reference in New Issue
Block a user