mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
add helpful error note for when function cannot return an error
This has caused frequent confusion since it looks like you are handling errors correctly with a try but you forgot to change your return type.
This commit is contained in:
parent
b8e22d2002
commit
5f0bde6358
27
src/ir.cpp
27
src/ir.cpp
@ -20603,17 +20603,25 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
|
||||
ZigType *expected_return_type = result_loc->value->type->data.pointer.child_type;
|
||||
|
||||
IrInstGen *dummy_value = ir_const(ira, source_instr, return_type);
|
||||
dummy_value->value->special = ConstValSpecialRuntime;
|
||||
IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
|
||||
dummy_value, result_loc->value->type->data.pointer.child_type);
|
||||
if (type_is_invalid(dummy_result->value->type))
|
||||
dummy_value, expected_return_type);
|
||||
if (type_is_invalid(dummy_result->value->type)) {
|
||||
if ((return_type->id == ZigTypeIdErrorUnion || return_type->id == ZigTypeIdErrorSet) &&
|
||||
expected_return_type->id != ZigTypeIdErrorUnion && expected_return_type->id != ZigTypeIdErrorSet)
|
||||
{
|
||||
add_error_note(ira->codegen, ira->new_irb.exec->first_err_trace_msg,
|
||||
ira->explicit_return_type_source_node, buf_create_from_str("function cannot return an error"));
|
||||
}
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
ZigType *res_child_type = result_loc->value->type->data.pointer.child_type;
|
||||
if (res_child_type == ira->codegen->builtin_types.entry_anytype) {
|
||||
res_child_type = return_type;
|
||||
}
|
||||
if (!handle_is_ptr(ira->codegen, res_child_type)) {
|
||||
if (expected_return_type == ira->codegen->builtin_types.entry_anytype) {
|
||||
expected_return_type = return_type;
|
||||
}
|
||||
if (!handle_is_ptr(ira->codegen, expected_return_type)) {
|
||||
ir_reset_result(call_result_loc);
|
||||
result_loc = nullptr;
|
||||
}
|
||||
@ -30907,6 +30915,13 @@ static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndEx
|
||||
IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value,
|
||||
instruction->result_loc->allow_write_through_const);
|
||||
if (type_is_invalid(store_ptr->value->type)) {
|
||||
if (instruction->result_loc->id == ResultLocIdReturn &&
|
||||
(value->value->type->id == ZigTypeIdErrorUnion || value->value->type->id == ZigTypeIdErrorSet) &&
|
||||
ira->explicit_return_type->id != ZigTypeIdErrorUnion && ira->explicit_return_type->id != ZigTypeIdErrorSet)
|
||||
{
|
||||
add_error_note(ira->codegen, ira->new_irb.exec->first_err_trace_msg,
|
||||
ira->explicit_return_type_source_node, buf_create_from_str("function cannot return an error"));
|
||||
}
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,28 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
"tmp.zig:2:16: error: sentinels are only allowed on slices and unknown-length pointers",
|
||||
});
|
||||
|
||||
cases.addTest("helpful return type error message",
|
||||
\\export fn foo() u32 {
|
||||
\\ return error.Ohno;
|
||||
\\}
|
||||
\\fn bar() !u32 {
|
||||
\\ return error.Ohno;
|
||||
\\}
|
||||
\\export fn baz() void {
|
||||
\\ try bar();
|
||||
\\}
|
||||
\\export fn quux() u32 {
|
||||
\\ return bar();
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:2:17: error: expected type 'u32', found 'error{Ohno}'",
|
||||
"tmp.zig:1:17: note: function cannot return an error",
|
||||
"tmp.zig:8:5: error: expected type 'void', found '@TypeOf(bar).ReturnType.ErrorSet'",
|
||||
"tmp.zig:7:17: note: function cannot return an error",
|
||||
"tmp.zig:11:15: error: expected type 'u32', found '@TypeOf(bar).ReturnType.ErrorSet!u32'",
|
||||
"tmp.zig:10:18: note: function cannot return an error",
|
||||
});
|
||||
|
||||
cases.addTest("int/float conversion to comptime_int/float",
|
||||
\\export fn foo() void {
|
||||
\\ var a: f32 = 2;
|
||||
|
Loading…
Reference in New Issue
Block a user