compiler: fix branch regressions

* getOwnedFunctionIndex no longer checks if the value is actually a
   function.
 * The callsites to `intern` that I added want to avoid the `getCoerced`
   call, so I added `intern2`.
 * Adding to inferred error sets should not happen if the destination
   error set is not the inferred error set of the current Sema instance.
 * adhoc_inferred_error_set_type can be seen by the backend. Treat it
   like anyerror.
This commit is contained in:
Andrew Kelley 2023-07-17 17:47:59 -07:00
parent b03d34429d
commit 3f2a4720b1
5 changed files with 12 additions and 6 deletions

View File

@ -751,6 +751,7 @@ pub const Decl = struct {
}; };
} }
/// This returns an InternPool.Index even when the value is not a function.
pub fn getOwnedFunctionIndex(decl: Decl) InternPool.Index { pub fn getOwnedFunctionIndex(decl: Decl) InternPool.Index {
return if (decl.owns_tv) decl.val.toIntern() else .none; return if (decl.owns_tv) decl.val.toIntern() else .none;
} }
@ -4978,7 +4979,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
decl.has_align = has_align; decl.has_align = has_align;
decl.has_linksection_or_addrspace = has_linksection_or_addrspace; decl.has_linksection_or_addrspace = has_linksection_or_addrspace;
decl.zir_decl_index = @as(u32, @intCast(decl_sub_index)); decl.zir_decl_index = @as(u32, @intCast(decl_sub_index));
if (decl.getOwnedFunctionIndex() != .none) { if (decl.getOwnedFunction(mod) != null) {
switch (comp.bin_file.tag) { switch (comp.bin_file.tag) {
.coff, .elf, .macho, .plan9 => { .coff, .elf, .macho, .plan9 => {
// TODO Look into detecting when this would be unnecessary by storing enough state // TODO Look into detecting when this would be unnecessary by storing enough state

View File

@ -7140,7 +7140,7 @@ fn analyzeCall(
if (should_memoize and is_comptime_call) { if (should_memoize and is_comptime_call) {
const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, ""); const result_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, result, "");
const result_interned = try result_val.intern(sema.fn_ret_ty, mod); const result_interned = try result_val.intern2(sema.fn_ret_ty, mod);
// Transform ad-hoc inferred error set types into concrete error sets. // Transform ad-hoc inferred error set types into concrete error sets.
const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned); const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned);
@ -7157,7 +7157,7 @@ fn analyzeCall(
} }
if (try sema.resolveMaybeUndefVal(result)) |result_val| { if (try sema.resolveMaybeUndefVal(result)) |result_val| {
const result_interned = try result_val.intern(sema.fn_ret_ty, mod); const result_interned = try result_val.intern2(sema.fn_ret_ty, mod);
const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned); const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned);
break :res2 Air.internedToRef(result_transformed); break :res2 Air.internedToRef(result_transformed);
} }
@ -18319,7 +18319,7 @@ fn analyzeRet(
// add the error tag to the inferred error set of the in-scope function, so // add the error tag to the inferred error set of the in-scope function, so
// that the coercion below works correctly. // that the coercion below works correctly.
const mod = sema.mod; const mod = sema.mod;
if (sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) { if (sema.fn_ret_ty_ies != null and sema.fn_ret_ty.zigTypeTag(mod) == .ErrorUnion) {
try sema.addToInferredErrorSet(uncasted_operand); try sema.addToInferredErrorSet(uncasted_operand);
} }
const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, .{ .is_ret = true }) catch |err| switch (err) { const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, .{ .is_ret = true }) catch |err| switch (err) {

View File

@ -1424,7 +1424,7 @@ pub fn updateDeclExports(
// detect the default subsystem. // detect the default subsystem.
for (exports) |exp| { for (exports) |exp| {
const exported_decl = mod.declPtr(exp.exported_decl); const exported_decl = mod.declPtr(exp.exported_decl);
if (exported_decl.getOwnedFunctionIndex() == .none) continue; if (exported_decl.getOwnedFunction(mod) == null) continue;
const winapi_cc = switch (self.base.options.target.cpu.arch) { const winapi_cc = switch (self.base.options.target.cpu.arch) {
.x86 => std.builtin.CallingConvention.Stdcall, .x86 => std.builtin.CallingConvention.Stdcall,
else => std.builtin.CallingConvention.C, else => std.builtin.CallingConvention.C,

View File

@ -2238,7 +2238,7 @@ pub const Type = struct {
var ty = starting_ty; var ty = starting_ty;
while (true) switch (ty.toIntern()) { while (true) switch (ty.toIntern()) {
.anyerror_type => { .anyerror_type, .adhoc_inferred_error_set_type => {
// TODO revisit this when error sets support custom int types // TODO revisit this when error sets support custom int types
return .{ .signedness = .unsigned, .bits = 16 }; return .{ .signedness = .unsigned, .bits = 16 };
}, },

View File

@ -262,6 +262,11 @@ pub const Value = struct {
return ip.getOrPutTrailingString(gpa, len); return ip.getOrPutTrailingString(gpa, len);
} }
pub fn intern2(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
if (val.ip_index != .none) return val.ip_index;
return intern(val, ty, mod);
}
pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index { pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern(); if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern();
switch (val.tag()) { switch (val.tag()) {