authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-06-07 16:19:21+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-06-07 21:27:06+03:00
logd5e3d5d74cefd64287b92d148f78353cdb84e447
tree1207244ba87dd2bbbfacb9ba7f031d40f3b6b868
parente9fc58eab77d60dfb02155ff17178b496d75d035

Sema: make `analyzeIsNonErr` even lazier for inferred error sets


2 files changed, 37 insertions(+), 0 deletions(-)

src/Sema.zig+22
......@@ -21870,6 +21870,28 @@ fn analyzeIsNonErrComptimeOnly(
2187021870 if (ies.is_anyerror) break :blk;
2187121871 if (ies.errors.count() != 0) break :blk;
2187221872 if (maybe_operand_val == null) {
21873 // Try to avoid resolving inferred error set if possible.
21874 if (ies.errors.count() != 0) break :blk;
21875 if (ies.is_anyerror) break :blk;
21876 var it = ies.inferred_error_sets.keyIterator();
21877 while (it.next()) |other_error_set_ptr| {
21878 const other_ies: *Module.Fn.InferredErrorSet = other_error_set_ptr.*;
21879 if (ies == other_ies) continue;
21880 try sema.resolveInferredErrorSet(block, src, other_ies);
21881 if (other_ies.is_anyerror) {
21882 ies.is_anyerror = true;
21883 ies.is_resolved = true;
21884 break :blk;
21885 }
21886
21887 if (other_ies.errors.count() != 0) break :blk;
21888 }
21889 if (ies.func == sema.owner_func) {
21890 // We're checking the inferred errorset of the current function and none of
21891 // its child inferred error sets contained any errors meaning that any value
21892 // so far with this type can't contain errors either.
21893 return Air.Inst.Ref.bool_true;
21894 }
2187321895 try sema.resolveInferredErrorSet(block, src, ies);
2187421896 if (ies.is_anyerror) break :blk;
2187521897 if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;
test/behavior/error.zig+15
......@@ -754,3 +754,18 @@ test "error union payload is properly aligned" {
754754 const blk = S.foo() catch unreachable;
755755 if (blk.a != 1) unreachable;
756756}
757
758test "ret_ptr doesn't cause own inferred error set to be resolved" {
759 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
760
761 const S = struct {
762 fn foo() !void {}
763
764 fn doTheTest() !void {
765 errdefer @compileError("bad");
766
767 return try @This().foo();
768 }
769 };
770 try S.doTheTest();
771}