authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-18 16:24:07-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-18 16:24:07-07:00
logad391ad399b26cf6a781e01c6daecf48bb764478
treeda72e64e5c6dd7cbe0c55a901037f4904b12d729
parent3d64ed0353ba7ec1ca46f4779fe5d32af8d17358

Revert "Sema: handle recursive inferred errors better in analyzeIsNonErrComptimeOnly"

This reverts commit 5aa9628de3c6637f45b9d8cf8cbd19c422a74f6f. This is a breaking language change and I do not agree with it. Please go through the proposal process on this one.

2 files changed, 23 insertions(+), 30 deletions(-)

src/Sema.zig+7-4
......@@ -29198,6 +29198,8 @@ fn analyzeIsNonErrComptimeOnly(
2919829198 if (ies.errors.count() != 0) break :blk;
2919929199 if (maybe_operand_val == null) {
2920029200 // Try to avoid resolving inferred error set if possible.
29201 if (ies.errors.count() != 0) break :blk;
29202 if (ies.is_anyerror) break :blk;
2920129203 for (ies.inferred_error_sets.keys()) |other_ies| {
2920229204 if (ies == other_ies) continue;
2920329205 try sema.resolveInferredErrorSet(block, src, other_ies);
......@@ -29209,10 +29211,11 @@ fn analyzeIsNonErrComptimeOnly(
2920929211
2921029212 if (other_ies.errors.count() != 0) break :blk;
2921129213 }
29212 if (!ies.is_resolved and ies.func.state == .in_progress) {
29213 // Calling resolveInferredErrorSet would immediately fail
29214 // so we'll have to rely on runtime checks.
29215 return Air.Inst.Ref.none;
29214 if (ies.func == sema.owner_func) {
29215 // We're checking the inferred errorset of the current function and none of
29216 // its child inferred error sets contained any errors meaning that any value
29217 // so far with this type can't contain errors either.
29218 return Air.Inst.Ref.bool_true;
2921629219 }
2921729220 try sema.resolveInferredErrorSet(block, src, ies);
2921829221 if (ies.is_anyerror) break :blk;
test/behavior/error.zig+16-26
......@@ -705,6 +705,22 @@ test "error union payload is properly aligned" {
705705 if (blk.a != 1) unreachable;
706706}
707707
708test "ret_ptr doesn't cause own inferred error set to be resolved" {
709 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
710 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
711
712 const S = struct {
713 fn foo() !void {}
714
715 fn doTheTest() !void {
716 errdefer @compileError("bad");
717
718 return try @This().foo();
719 }
720 };
721 try S.doTheTest();
722}
723
708724test "simple else prong allowed even when all errors handled" {
709725 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
710726 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
......@@ -912,29 +928,3 @@ test "optional error set return type" {
912928 try expect(null == S.foo(true));
913929 try expect(E.A == S.foo(false).?);
914930}
915
916test "try used in recursive function with inferred error set" {
917 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
918 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
919 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
920
921 const Value = union(enum) {
922 values: []const @This(),
923 b,
924
925 fn x(value: @This()) !void {
926 switch (value.values[0]) {
927 .values => return try x(value.values[0]),
928 .b => return error.a,
929 }
930 }
931 };
932 const a = Value{
933 .values = &[1]Value{
934 .{
935 .values = &[1]Value{.{ .b = {} }},
936 },
937 },
938 };
939 try expectError(error.a, Value.x(a));
940}