From 9ae43567a3ef14a815482ccaa2a5b412a716743e Mon Sep 17 00:00:00 2001 From: r00ster91 Date: Fri, 21 Jul 2023 03:22:59 +0200 Subject: [PATCH] Sema: improve error set/union discard/ignore errors Previously the error had a note suggesting to use `try`, `catch`, or `if`, even for error sets where none of those work. Instead, in case of an error set the way you can handle the error depends very much on the specific case. For example you might be in a `catch` where you are discarding or ignoring the error set capture value, in which case one way to handle the error might be to `return` the error. So, in that case, we do not attach that error note. Additionally, this makes the error tell you what kind of an error it is: is it an error set or an error union? This distinction is very relevant in how to handle the error. --- src/Sema.zig | 10 ++++++---- .../compile_errors/discarding_error_value.zig | 9 +++++++-- .../ignored_deferred_function_call.zig | 10 +++++++++- .../ignored_expression_in_while_continuation.zig | 14 +++++++++++--- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index f286b6385f13b5925447d5c3dc518c5fac43bda6..c55531d924d495a3ce72ca3de3d1d60abed6145b 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3568,9 +3568,10 @@ fn ensureResultUsed( const mod = sema.mod; switch (ty.zigTypeTag(mod)) { .Void, .NoReturn => return, - .ErrorSet, .ErrorUnion => { + .ErrorSet => return sema.fail(block, src, "error set is ignored", .{}), + .ErrorUnion => { const msg = msg: { - const msg = try sema.errMsg(block, src, "error is ignored", .{}); + const msg = try sema.errMsg(block, src, "error union is ignored", .{}); errdefer msg.destroy(sema.gpa); try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{}); break :msg msg; @@ -3600,9 +3601,10 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com const src = inst_data.src(); const operand_ty = sema.typeOf(operand); switch (operand_ty.zigTypeTag(mod)) { - .ErrorSet, .ErrorUnion => { + .ErrorSet => return sema.fail(block, src, "error set is discarded", .{}), + .ErrorUnion => { const msg = msg: { - const msg = try sema.errMsg(block, src, "error is discarded", .{}); + const msg = try sema.errMsg(block, src, "error union is discarded", .{}); errdefer msg.destroy(sema.gpa); try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{}); break :msg msg; diff --git a/test/cases/compile_errors/discarding_error_value.zig b/test/cases/compile_errors/discarding_error_value.zig index c24d517d3e3b39133b0e1ec9af2a79239a24df89..eab3ecaf984de84f21433a6e9450da71165ccdd5 100644 --- a/test/cases/compile_errors/discarding_error_value.zig +++ b/test/cases/compile_errors/discarding_error_value.zig @@ -1,13 +1,18 @@ -export fn entry() void { +export fn entry1() void { _ = foo(); } fn foo() !void { return error.OutOfMemory; } +export fn entry2() void { + const x: error{a} = undefined; + _ = x; +} // error // backend=stage2 // target=native // -// :2:12: error: error is discarded +// :2:12: error: error union is discarded // :2:12: note: consider using 'try', 'catch', or 'if' +// :9:9: error: error set is discarded diff --git a/test/cases/compile_errors/ignored_deferred_function_call.zig b/test/cases/compile_errors/ignored_deferred_function_call.zig index 9537255d33041ae1ae7a4822bf84a5a8a25bf79b..90c978b40fd26c8d51769a6aa4ea1d7bdb4446fa 100644 --- a/test/cases/compile_errors/ignored_deferred_function_call.zig +++ b/test/cases/compile_errors/ignored_deferred_function_call.zig @@ -5,9 +5,17 @@ fn bar() anyerror!i32 { return 0; } +export fn foo2() void { + defer bar2(); +} +fn bar2() anyerror { + return error.a; +} + // error // backend=stage2 // target=native // -// :2:14: error: error is ignored +// :2:14: error: error union is ignored // :2:14: note: consider using 'try', 'catch', or 'if' +// :9:15: error: error set is ignored diff --git a/test/cases/compile_errors/ignored_expression_in_while_continuation.zig b/test/cases/compile_errors/ignored_expression_in_while_continuation.zig index 4fa396190a58501cc9b65bc527113d3470e17225..ca1b60da5ecaf8c3dcf21f29d42cc0eaba7c82bb 100644 --- a/test/cases/compile_errors/ignored_expression_in_while_continuation.zig +++ b/test/cases/compile_errors/ignored_expression_in_while_continuation.zig @@ -15,13 +15,21 @@ fn bad() anyerror!void { return error.Bad; } +export fn d() void { + while (true) : (bad2()) {} +} +fn bad2() anyerror { + return error.Bad; +} + // error // backend=stage2 // target=native // -// :2:24: error: error is ignored +// :2:24: error: error union is ignored // :2:24: note: consider using 'try', 'catch', or 'if' -// :7:25: error: error is ignored +// :7:25: error: error union is ignored // :7:25: note: consider using 'try', 'catch', or 'if' -// :12:25: error: error is ignored +// :12:25: error: error union is ignored // :12:25: note: consider using 'try', 'catch', or 'if' +// :19:25: error: error set is ignored -- 2.54.0