zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 3f2a4720b1ef057215c8240b3a377c523ee63e94 (tree)
parent b03d34429d059dc3f6056d7f780dc623c96523b4
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Mon, 17 Jul 2023 17:47:59 -0700

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.

Diffstat:
Msrc/Module.zig | 3++-
Msrc/Sema.zig | 6+++---
Msrc/link/Coff.zig | 2+-
Msrc/type.zig | 2+-
Msrc/value.zig | 5+++++
5 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/src/Module.zig b/src/Module.zig @@ -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 { 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_linksection_or_addrspace = has_linksection_or_addrspace; decl.zir_decl_index = @as(u32, @intCast(decl_sub_index)); - if (decl.getOwnedFunctionIndex() != .none) { + if (decl.getOwnedFunction(mod) != null) { switch (comp.bin_file.tag) { .coff, .elf, .macho, .plan9 => { // TODO Look into detecting when this would be unnecessary by storing enough state diff --git a/src/Sema.zig b/src/Sema.zig @@ -7140,7 +7140,7 @@ fn analyzeCall( if (should_memoize and is_comptime_call) { 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. const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned); @@ -7157,7 +7157,7 @@ fn analyzeCall( } 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); 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 // that the coercion below works correctly. 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); } const operand = sema.coerceExtra(block, sema.fn_ret_ty, uncasted_operand, src, .{ .is_ret = true }) catch |err| switch (err) { diff --git a/src/link/Coff.zig b/src/link/Coff.zig @@ -1424,7 +1424,7 @@ pub fn updateDeclExports( // detect the default subsystem. for (exports) |exp| { 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) { .x86 => std.builtin.CallingConvention.Stdcall, else => std.builtin.CallingConvention.C, diff --git a/src/type.zig b/src/type.zig @@ -2238,7 +2238,7 @@ pub const Type = struct { var ty = starting_ty; while (true) switch (ty.toIntern()) { - .anyerror_type => { + .anyerror_type, .adhoc_inferred_error_set_type => { // TODO revisit this when error sets support custom int types return .{ .signedness = .unsigned, .bits = 16 }; }, diff --git a/src/value.zig b/src/value.zig @@ -262,6 +262,11 @@ pub const Value = struct { 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 { if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern(); switch (val.tag()) {