Sema: make analyzeIsNonErr even lazier for inferred error sets

This commit is contained in:
Veikka Tuominen 2022-06-07 16:19:21 +03:00
parent e9fc58eab7
commit d5e3d5d74c
2 changed files with 37 additions and 0 deletions

View File

@ -21870,6 +21870,28 @@ fn analyzeIsNonErrComptimeOnly(
if (ies.is_anyerror) break :blk;
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;
var it = ies.inferred_error_sets.keyIterator();
while (it.next()) |other_error_set_ptr| {
const other_ies: *Module.Fn.InferredErrorSet = other_error_set_ptr.*;
if (ies == other_ies) continue;
try sema.resolveInferredErrorSet(block, src, other_ies);
if (other_ies.is_anyerror) {
ies.is_anyerror = true;
ies.is_resolved = true;
break :blk;
}
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;
}
try sema.resolveInferredErrorSet(block, src, ies);
if (ies.is_anyerror) break :blk;
if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;

View File

@ -754,3 +754,18 @@ test "error union payload is properly aligned" {
const blk = S.foo() catch unreachable;
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
const S = struct {
fn foo() !void {}
fn doTheTest() !void {
errdefer @compileError("bad");
return try @This().foo();
}
};
try S.doTheTest();
}