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(...@@ -30706,6 +30706,41 @@ fn analyzeIsNonErrComptimeOnly(
30706 const set_ty = ip.errorUnionSet(operand_ty.toIntern());30706 const set_ty = ip.errorUnionSet(operand_ty.toIntern());
30707 switch (set_ty) {30707 switch (set_ty) {
30708 .anyerror_type => {},30708 .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 },
30709 else => switch (ip.indexToKey(set_ty)) {30744 else => switch (ip.indexToKey(set_ty)) {
30710 .error_set_type => |error_set_type| {30745 .error_set_type => |error_set_type| {
30711 if (error_set_type.names.len == 0) return .bool_true;30746 if (error_set_type.names.len == 0) return .bool_true;
...@@ -30719,41 +30754,38 @@ fn analyzeIsNonErrComptimeOnly(...@@ -30719,41 +30754,38 @@ fn analyzeIsNonErrComptimeOnly(
30719 .none => {},30754 .none => {},
30720 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,30755 else => |i| if (ip.indexToKey(i).error_set_type.names.len != 0) break :blk,
30721 }30756 }
30722 if (maybe_operand_val == null) {30757 if (maybe_operand_val != null) break :blk;
30723 if (sema.fn_ret_ty_ies) |ies| {30758 if (sema.fn_ret_ty_ies) |ies| {
30724 if (set_ty == .adhoc_inferred_error_set_type or30759 if (ies.func == func_index) {
30725 ies.func == func_index)30760 // Try to avoid resolving inferred error set if possible.
30726 {30761 if (ies.errors.count() != 0) return .none;
30727 // Try to avoid resolving inferred error set if possible.30762 switch (ies.resolved) {
30728 if (ies.errors.count() != 0) return .none;30763 .anyerror_type => return .none,
30729 switch (ies.resolved) {30764 .none => {},
30730 .anyerror_type => return .none,30765 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {
30731 .none => {},30766 0 => return .bool_true,
30732 else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) {30767 else => return .none,
30733 0 => return .bool_true,30768 },
30734 else => return .none,30769 }
30735 },30770 for (ies.inferred_error_sets.keys()) |other_ies_index| {
30736 }30771 if (set_ty == other_ies_index) continue;
30737 for (ies.inferred_error_sets.keys()) |other_ies_index| {30772 const other_resolved =
30738 if (set_ty == other_ies_index) continue;30773 try sema.resolveInferredErrorSet(block, src, other_ies_index);
30739 const other_resolved =30774 if (other_resolved == .anyerror_type) {
30740 try sema.resolveInferredErrorSet(block, src, other_ies_index);30775 ies.resolved = .anyerror_type;
30741 if (other_resolved == .anyerror_type) {30776 return .none;
30742 ies.resolved = .anyerror_type;
30743 return .none;
30744 }
30745 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30746 return .none;
30747 }30777 }
30748 return .bool_true;30778 if (ip.indexToKey(other_resolved).error_set_type.names.len != 0)
30779 return .none;
30749 }30780 }
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)
30755 return .bool_true;30781 return .bool_true;
30782 }
30756 }30783 }
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;
30757 },30789 },
30758 else => unreachable,30790 else => unreachable,
30759 },30791 },