authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-22 19:58:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-22 19:58:52-07:00
log012cbdb422fd4d89fe24d272a22f21376a4ab884
tree5f453fd03c7561be9ccee04fb48fcbfb41ffa527
parent076b54c8e7e8472556558543c6fb3eaa8967de78

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.

1 files changed, 63 insertions(+), 31 deletions(-)

src/Sema.zig+63-31
......@@ -30706,6 +30706,41 @@ fn analyzeIsNonErrComptimeOnly(
3070630706 const set_ty = ip.errorUnionSet(operand_ty.toIntern());
3070730707 switch (set_ty) {
3070830708 .anyerror_type => {},
30709 .adhoc_inferred_error_set_type => if (sema.fn_ret_ty_ies) |ies| blk: {
30710 // If the error set is empty, we must return a comptime true or false.
30711 // However we want to avoid unnecessarily resolving an inferred error set
30712 // in case it is already non-empty.
30713 switch (ies.resolved) {
30714 .anyerror_type => break :blk,
30715 .none => {},
30716 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,
30717 }
30718
30719 if (maybe_operand_val != null) break :blk;
30720
30721 // Try to avoid resolving inferred error set if possible.
30722 if (ies.errors.count() != 0) return .none;
30723 switch (ies.resolved) {
30724 .anyerror_type => return .none,
30725 .none => {},
30726 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {
30727 0 => return .bool_true,
30728 else => return .none,
30729 },
30730 }
30731 for (ies.inferred_error_sets.keys()) |other_ies_index| {
30732 if (set_ty == other_ies_index) continue;
30733 const other_resolved =
30734 try sema.resolveInferredErrorSet(block, src, other_ies_index);
30735 if (other_resolved == .anyerror_type) {
30736 ies.resolved = .anyerror_type;
30737 return .none;
30738 }
30739 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30740 return .none;
30741 }
30742 return .bool_true;
30743 },
3070930744 else => switch (ip.indexToKey(set_ty)) {
3071030745 .error_set_type => |error_set_type| {
3071130746 if (error_set_type.names.len == 0) return .bool_true;
......@@ -30719,41 +30754,38 @@ fn analyzeIsNonErrComptimeOnly(
3071930754 .none => {},
3072030755 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,
3072130756 }
30722 if (maybe_operand_val == null) {
30723 if (sema.fn_ret_ty_ies) |ies| {
30724 if (set_ty == .adhoc_inferred_error_set_type or
30725 ies.func == func_index)
30726 {
30727 // Try to avoid resolving inferred error set if possible.
30728 if (ies.errors.count() != 0) return .none;
30729 switch (ies.resolved) {
30730 .anyerror_type => return .none,
30731 .none => {},
30732 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {
30733 0 => return .bool_true,
30734 else => return .none,
30735 },
30736 }
30737 for (ies.inferred_error_sets.keys()) |other_ies_index| {
30738 if (set_ty == other_ies_index) continue;
30739 const other_resolved =
30740 try sema.resolveInferredErrorSet(block, src, other_ies_index);
30741 if (other_resolved == .anyerror_type) {
30742 ies.resolved = .anyerror_type;
30743 return .none;
30744 }
30745 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30746 return .none;
30757 if (maybe_operand_val != null) break :blk;
30758 if (sema.fn_ret_ty_ies) |ies| {
30759 if (ies.func == func_index) {
30760 // Try to avoid resolving inferred error set if possible.
30761 if (ies.errors.count() != 0) return .none;
30762 switch (ies.resolved) {
30763 .anyerror_type => return .none,
30764 .none => {},
30765 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {
30766 0 => return .bool_true,
30767 else => return .none,
30768 },
30769 }
30770 for (ies.inferred_error_sets.keys()) |other_ies_index| {
30771 if (set_ty == other_ies_index) continue;
30772 const other_resolved =
30773 try sema.resolveInferredErrorSet(block, src, other_ies_index);
30774 if (other_resolved == .anyerror_type) {
30775 ies.resolved = .anyerror_type;
30776 return .none;
3074730777 }
30748 return .bool_true;
30778 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30779 return .none;
3074930780 }
30750 }
30751 const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
30752 if (resolved_ty == .anyerror_type)
30753 break :blk;
30754 if (ip.indexToKey(resolved_ty).error_set_type.names.len == 0)
3075530781 return .bool_true;
30782 }
3075630783 }
30784 const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
30785 if (resolved_ty == .anyerror_type)
30786 break :blk;
30787 if (ip.indexToKey(resolved_ty).error_set_type.names.len == 0)
30788 return .bool_true;
3075730789 },
3075830790 else => unreachable,
3075930791 },