diff --git a/src/Sema.zig b/src/Sema.zig index a3502726bb..a93a7a6079 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -29153,8 +29153,6 @@ fn analyzeIsNonErrComptimeOnly( if (ies.errors.count() != 0) break :blk; if (maybe_operand_val == null) { // Try to avoid resolving inferred error set if possible. - if (ies.errors.count() != 0) break :blk; - if (ies.is_anyerror) break :blk; for (ies.inferred_error_sets.keys()) |other_ies| { if (ies == other_ies) continue; try sema.resolveInferredErrorSet(block, src, other_ies); @@ -29166,11 +29164,10 @@ fn analyzeIsNonErrComptimeOnly( if (other_ies.errors.count() != 0) break :blk; } - if (ies.func == sema.owner_func) { - // We're checking the inferred errorset of the current function and none of - // its child inferred error sets contained any errors meaning that any value - // so far with this type can't contain errors either. - return Air.Inst.Ref.bool_true; + if (!ies.is_resolved and ies.func.state == .in_progress) { + // Calling resolveInferredErrorSet would immediately fail + // so we'll have to rely on runtime checks. + return Air.Inst.Ref.none; } try sema.resolveInferredErrorSet(block, src, ies); if (ies.is_anyerror) break :blk; diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 91b5561d62..acb4b8fb61 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -678,22 +678,6 @@ test "error union payload is properly aligned" { if (blk.a != 1) unreachable; } -test "ret_ptr doesn't cause own inferred error set to be resolved" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - - const S = struct { - fn foo() !void {} - - fn doTheTest() !void { - errdefer @compileError("bad"); - - return try @This().foo(); - } - }; - try S.doTheTest(); -} - test "simple else prong allowed even when all errors handled" { if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -889,3 +873,28 @@ test "optional error set return type" { try expect(null == S.foo(true)); try expect(E.A == S.foo(false).?); } + +test "try used in recursive function with inferred error set" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const Value = union(enum) { + values: []const @This(), + b, + + fn x(value: @This()) !void { + switch (value.values[0]) { + .values => return try x(value.values[0]), + .b => return error.a, + } + } + }; + const a = Value{ + .values = &[1]Value{ + .{ + .values = &[1]Value{.{ .b = {} }}, + }, + }, + }; + try expectError(error.a, Value.x(a)); +}