diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-07-22 19:58:52 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-07-22 19:58:52 -0700 |
| commit | 012cbdb422fd4d89fe24d272a22f21376a4ab884 (patch) | |
| tree | 5f453fd03c7561be9ccee04fb48fcbfb41ffa527 /src/Sema.zig | |
| parent | 076b54c8e7e8472556558543c6fb3eaa8967de78 (diff) | |
| download | zig-012cbdb422fd4d89fe24d272a22f21376a4ab884.tar.gz zig-012cbdb422fd4d89fe24d272a22f21376a4ab884.zip | |
Sema: fix adhoc inferred error sets in analyzeIsNonErrComptimeOnly
The logic incorrectly assumed that adhoc_inferred_error_set_type would
be part of the inferred_error_set InternPool.Key when it actually is
part of `simple_type`.
Regressed in the #16318 branch.
Found from compiling Bun. Unfortunately we do not have a behavior test
reduction for this bug.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 94 |
1 files changed, 63 insertions, 31 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 0fcc914596..577ca5b774 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -30706,6 +30706,41 @@ fn analyzeIsNonErrComptimeOnly( const set_ty = ip.errorUnionSet(operand_ty.toIntern()); switch (set_ty) { .anyerror_type => {}, + .adhoc_inferred_error_set_type => if (sema.fn_ret_ty_ies) |ies| blk: { + // If the error set is empty, we must return a comptime true or false. + // However we want to avoid unnecessarily resolving an inferred error set + // in case it is already non-empty. + switch (ies.resolved) { + .anyerror_type => break :blk, + .none => {}, + else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk, + } + + if (maybe_operand_val != null) break :blk; + + // Try to avoid resolving inferred error set if possible. + if (ies.errors.count() != 0) return .none; + switch (ies.resolved) { + .anyerror_type => return .none, + .none => {}, + else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) { + 0 => return .bool_true, + else => return .none, + }, + } + for (ies.inferred_error_sets.keys()) |other_ies_index| { + if (set_ty == other_ies_index) continue; + const other_resolved = + try sema.resolveInferredErrorSet(block, src, other_ies_index); + if (other_resolved == .anyerror_type) { + ies.resolved = .anyerror_type; + return .none; + } + if (ip.indexToKey(other_resolved).error_set_type.names.len != 0) + return .none; + } + return .bool_true; + }, else => switch (ip.indexToKey(set_ty)) { .error_set_type => |error_set_type| { if (error_set_type.names.len == 0) return .bool_true; @@ -30719,41 +30754,38 @@ fn analyzeIsNonErrComptimeOnly( .none => {}, else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk, } - if (maybe_operand_val == null) { - if (sema.fn_ret_ty_ies) |ies| { - if (set_ty == .adhoc_inferred_error_set_type or - ies.func == func_index) - { - // Try to avoid resolving inferred error set if possible. - if (ies.errors.count() != 0) return .none; - switch (ies.resolved) { - .anyerror_type => return .none, - .none => {}, - else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) { - 0 => return .bool_true, - else => return .none, - }, - } - for (ies.inferred_error_sets.keys()) |other_ies_index| { - if (set_ty == other_ies_index) continue; - const other_resolved = - try sema.resolveInferredErrorSet(block, src, other_ies_index); - if (other_resolved == .anyerror_type) { - ies.resolved = .anyerror_type; - return .none; - } - if (ip.indexToKey(other_resolved).error_set_type.names.len != 0) - return .none; + if (maybe_operand_val != null) break :blk; + if (sema.fn_ret_ty_ies) |ies| { + if (ies.func == func_index) { + // Try to avoid resolving inferred error set if possible. + if (ies.errors.count() != 0) return .none; + switch (ies.resolved) { + .anyerror_type => return .none, + .none => {}, + else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) { + 0 => return .bool_true, + else => return .none, + }, + } + for (ies.inferred_error_sets.keys()) |other_ies_index| { + if (set_ty == other_ies_index) continue; + const other_resolved = + try sema.resolveInferredErrorSet(block, src, other_ies_index); + if (other_resolved == .anyerror_type) { + ies.resolved = .anyerror_type; + return .none; } - return .bool_true; + if (ip.indexToKey(other_resolved).error_set_type.names.len != 0) + return .none; } - } - const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty); - if (resolved_ty == .anyerror_type) - break :blk; - if (ip.indexToKey(resolved_ty).error_set_type.names.len == 0) return .bool_true; + } } + const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty); + if (resolved_ty == .anyerror_type) + break :blk; + if (ip.indexToKey(resolved_ty).error_set_type.names.len == 0) + return .bool_true; }, else => unreachable, }, |
