From d37ebfcf231c68a0430840c4fbe649dd0076ae1e Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 12 Jun 2023 01:44:12 -0400 Subject: [PATCH] InternPool: avoid as many slices pointing to `string_bytes` as possible These are frequently invalidated whenever a string is interned, so avoid creating pointers to `string_bytes` wherever possible. This is an attempt to fix random CI failures. --- src/InternPool.zig | 46 ++- src/Module.zig | 122 +++---- src/Sema.zig | 802 +++++++++++++++++++++---------------------- src/TypedValue.zig | 66 ++-- src/codegen/c.zig | 8 +- src/codegen/llvm.zig | 37 +- src/link/C.zig | 2 +- src/link/Coff.zig | 25 +- src/link/Elf.zig | 8 +- src/link/MachO.zig | 12 +- src/link/Plan9.zig | 10 +- src/link/SpirV.zig | 2 +- src/link/Wasm.zig | 14 +- src/print_air.zig | 3 +- src/type.zig | 8 +- src/value.zig | 45 +-- 16 files changed, 572 insertions(+), 638 deletions(-) diff --git a/src/InternPool.zig b/src/InternPool.zig index 0f0b40ba4d..d5cf2d3fbf 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -156,6 +156,35 @@ pub const NullTerminatedString = enum(u32) { _ = ctx; return @enumToInt(a) < @enumToInt(b); } + + pub fn toUnsigned(self: NullTerminatedString, ip: *const InternPool) ?u32 { + const s = ip.stringToSlice(self); + if (s.len > 1 and s[0] == '0') return null; + if (std.mem.indexOfScalar(u8, s, '_')) |_| return null; + return std.fmt.parseUnsigned(u32, s, 10) catch null; + } + + const FormatData = struct { + string: NullTerminatedString, + ip: *const InternPool, + }; + fn format( + data: FormatData, + comptime specifier: []const u8, + _: std.fmt.FormatOptions, + writer: anytype, + ) @TypeOf(writer).Error!void { + const s = data.ip.stringToSlice(data.string); + if (comptime std.mem.eql(u8, specifier, "")) { + try writer.writeAll(s); + } else if (comptime std.mem.eql(u8, specifier, "i")) { + try writer.print("{}", .{std.zig.fmtId(s)}); + } else @compileError("invalid format string '" ++ specifier ++ "' for '" ++ @typeName(NullTerminatedString) ++ "'"); + } + + pub fn fmt(self: NullTerminatedString, ip: *const InternPool) std.fmt.Formatter(format) { + return .{ .data = .{ .string = self, .ip = ip } }; + } }; /// An index into `string_bytes` which might be `none`. @@ -5252,10 +5281,9 @@ pub fn getOrPutString( gpa: Allocator, s: []const u8, ) Allocator.Error!NullTerminatedString { - const string_bytes = &ip.string_bytes; - try string_bytes.ensureUnusedCapacity(gpa, s.len + 1); - string_bytes.appendSliceAssumeCapacity(s); - string_bytes.appendAssumeCapacity(0); + try ip.string_bytes.ensureUnusedCapacity(gpa, s.len + 1); + ip.string_bytes.appendSliceAssumeCapacity(s); + ip.string_bytes.appendAssumeCapacity(0); return ip.getOrPutTrailingString(gpa, s.len + 1); } @@ -5265,10 +5293,12 @@ pub fn getOrPutStringFmt( comptime format: []const u8, args: anytype, ) Allocator.Error!NullTerminatedString { - const start = ip.string_bytes.items.len; - try ip.string_bytes.writer(gpa).print(format, args); - try ip.string_bytes.append(gpa, 0); - return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start); + // ensure that references to string_bytes in args do not get invalidated + const len = std.fmt.count(format, args) + 1; + try ip.string_bytes.ensureUnusedCapacity(gpa, len); + ip.string_bytes.writer(undefined).print(format, args) catch unreachable; + ip.string_bytes.appendAssumeCapacity(0); + return ip.getOrPutTrailingString(gpa, len); } pub fn getOrPutStringOpt( diff --git a/src/Module.zig b/src/Module.zig index cb3e8884e3..61f39a327a 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -270,11 +270,7 @@ pub const GlobalEmitH = struct { pub const ErrorInt = u32; pub const Export = struct { - name: InternPool.NullTerminatedString, - linkage: std.builtin.GlobalLinkage, - section: InternPool.OptionalNullTerminatedString, - visibility: std.builtin.SymbolVisibility, - + opts: Options, src: LazySrcLoc, /// The Decl that performs the export. Note that this is *not* the Decl being exported. owner_decl: Decl.Index, @@ -292,6 +288,13 @@ pub const Export = struct { complete, }, + pub const Options = struct { + name: InternPool.NullTerminatedString, + linkage: std.builtin.GlobalLinkage = .Strong, + section: InternPool.OptionalNullTerminatedString = .none, + visibility: std.builtin.SymbolVisibility = .default, + }; + pub fn getSrcLoc(exp: Export, mod: *Module) SrcLoc { const src_decl = mod.declPtr(exp.src_decl); return .{ @@ -691,16 +694,15 @@ pub const Decl = struct { } pub fn renderFullyQualifiedName(decl: Decl, mod: *Module, writer: anytype) !void { - const unqualified_name = mod.intern_pool.stringToSlice(decl.name); if (decl.name_fully_qualified) { - return writer.writeAll(unqualified_name); + try writer.print("{}", .{decl.name.fmt(&mod.intern_pool)}); + } else { + try mod.namespacePtr(decl.src_namespace).renderFullyQualifiedName(mod, decl.name, writer); } - return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedName(mod, unqualified_name, writer); } pub fn renderFullyQualifiedDebugName(decl: Decl, mod: *Module, writer: anytype) !void { - const unqualified_name = mod.intern_pool.stringToSlice(decl.name); - return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, unqualified_name, writer); + return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, decl.name, writer); } pub fn getFullyQualifiedName(decl: Decl, mod: *Module) !InternPool.NullTerminatedString { @@ -712,8 +714,7 @@ pub const Decl = struct { var ns: Namespace.Index = decl.src_namespace; while (true) { const namespace = mod.namespacePtr(ns); - const ns_decl_index = namespace.getDeclIndex(mod); - const ns_decl = mod.declPtr(ns_decl_index); + const ns_decl = mod.declPtr(namespace.getDeclIndex(mod)); count += ip.stringToSlice(ns_decl.name).len + 1; ns = namespace.parent.unwrap() orelse { count += namespace.file_scope.sub_file_path.len; @@ -1722,44 +1723,34 @@ pub const Namespace = struct { pub fn renderFullyQualifiedName( ns: Namespace, mod: *Module, - name: []const u8, + name: InternPool.NullTerminatedString, writer: anytype, ) @TypeOf(writer).Error!void { if (ns.parent.unwrap()) |parent| { - const decl_index = ns.getDeclIndex(mod); - const decl = mod.declPtr(decl_index); - const decl_name = mod.intern_pool.stringToSlice(decl.name); - try mod.namespacePtr(parent).renderFullyQualifiedName(mod, decl_name, writer); + const decl = mod.declPtr(ns.getDeclIndex(mod)); + try mod.namespacePtr(parent).renderFullyQualifiedName(mod, decl.name, writer); } else { try ns.file_scope.renderFullyQualifiedName(writer); } - if (name.len != 0) { - try writer.writeAll("."); - try writer.writeAll(name); - } + if (name != .empty) try writer.print(".{}", .{name.fmt(&mod.intern_pool)}); } /// This renders e.g. "std/fs.zig:Dir.OpenOptions" pub fn renderFullyQualifiedDebugName( ns: Namespace, mod: *Module, - name: []const u8, + name: InternPool.NullTerminatedString, writer: anytype, ) @TypeOf(writer).Error!void { - var separator_char: u8 = '.'; - if (ns.parent.unwrap()) |parent| { - const decl_index = ns.getDeclIndex(mod); - const decl = mod.declPtr(decl_index); - const decl_name = mod.intern_pool.stringToSlice(decl.name); - try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, decl_name, writer); - } else { + const separator_char: u8 = if (ns.parent.unwrap()) |parent| sep: { + const decl = mod.declPtr(ns.getDeclIndex(mod)); + try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, decl.name, writer); + break :sep '.'; + } else sep: { try ns.file_scope.renderFullyQualifiedDebugName(writer); - separator_char = ':'; - } - if (name.len != 0) { - try writer.writeByte(separator_char); - try writer.writeAll(name); - } + break :sep ':'; + }; + if (name != .empty) try writer.print("{c}{}", .{ separator_char, name.fmt(&mod.intern_pool) }); } pub fn getDeclIndex(ns: Namespace, mod: *Module) Decl.Index { @@ -4185,10 +4176,10 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: Fn.Index) SemaError!void defer liveness.deinit(gpa); if (dump_air) { - const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); - std.debug.print("# Begin Function AIR: {s}:\n", .{fqn}); + const fqn = try decl.getFullyQualifiedName(mod); + std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(&mod.intern_pool)}); @import("print_air.zig").dump(mod, air, liveness); - std.debug.print("# End Function AIR: {s}\n\n", .{fqn}); + std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(&mod.intern_pool)}); } if (std.debug.runtime_safety) { @@ -4620,10 +4611,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { return sema.fail(&block_scope, export_src, "export of inline function", .{}); } // The scope needs to have the decl in it. - const options: std.builtin.ExportOptions = .{ - .name = mod.intern_pool.stringToSlice(decl.name), - }; - try sema.analyzeExport(&block_scope, export_src, options, decl_index); + try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index); } return type_changed or is_inline != prev_is_inline; } @@ -4720,10 +4708,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { if (decl.is_exported) { const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) }; // The scope needs to have the decl in it. - const options: std.builtin.ExportOptions = .{ - .name = mod.intern_pool.stringToSlice(decl.name), - }; - try sema.analyzeExport(&block_scope, export_src, options, decl_index); + try sema.analyzeExport(&block_scope, export_src, .{ .name = decl.name }, decl_index); } return type_changed; @@ -5222,12 +5207,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err .parent_decl_node = decl.src_node, .lazy = .{ .token_offset = 1 }, }; - const msg = try ErrorMsg.create( - gpa, - src_loc, - "duplicate test name: {s}", - .{ip.stringToSlice(decl_name)}, - ); + const msg = try ErrorMsg.create(gpa, src_loc, "duplicate test name: {}", .{ + decl_name.fmt(&mod.intern_pool), + }); errdefer msg.destroy(gpa); try mod.failed_decls.putNoClobber(gpa, decl_index, msg); const other_src_loc = SrcLoc{ @@ -5417,16 +5399,16 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void } } if (mod.comp.bin_file.cast(link.File.Elf)) |elf| { - elf.deleteDeclExport(decl_index, exp.name); + elf.deleteDeclExport(decl_index, exp.opts.name); } if (mod.comp.bin_file.cast(link.File.MachO)) |macho| { - try macho.deleteDeclExport(decl_index, exp.name); + try macho.deleteDeclExport(decl_index, exp.opts.name); } if (mod.comp.bin_file.cast(link.File.Wasm)) |wasm| { wasm.deleteDeclExport(decl_index); } if (mod.comp.bin_file.cast(link.File.Coff)) |coff| { - coff.deleteDeclExport(decl_index, exp.name); + coff.deleteDeclExport(decl_index, exp.opts.name); } if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| { failed_kv.value.destroy(mod.gpa); @@ -5810,12 +5792,9 @@ pub fn createAnonymousDeclFromDecl( ) !Decl.Index { const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope); errdefer mod.destroyDecl(new_decl_index); - const ip = &mod.intern_pool; - // This protects the getOrPutStringFmt from reallocating src decl name while reading it. - try ip.string_bytes.ensureUnusedCapacity(mod.gpa, ip.stringToSlice(src_decl.name).len + 20); - const name = ip.getOrPutStringFmt(mod.gpa, "{s}__anon_{d}", .{ - ip.stringToSlice(src_decl.name), @enumToInt(new_decl_index), - }) catch unreachable; + const name = try mod.intern_pool.getOrPutStringFmt(mod.gpa, "{}__anon_{d}", .{ + src_decl.name.fmt(&mod.intern_pool), @enumToInt(new_decl_index), + }); try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, tv, name); return new_decl_index; } @@ -6301,13 +6280,13 @@ pub fn processExports(mod: *Module) !void { const exported_decl = entry.key_ptr.*; const exports = entry.value_ptr.items; for (exports) |new_export| { - const gop = try symbol_exports.getOrPut(gpa, new_export.name); + const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name); if (gop.found_existing) { new_export.status = .failed_retryable; try mod.failed_exports.ensureUnusedCapacity(gpa, 1); const src_loc = new_export.getSrcLoc(mod); - const msg = try ErrorMsg.create(gpa, src_loc, "exported symbol collision: {s}", .{ - mod.intern_pool.stringToSlice(new_export.name), + const msg = try ErrorMsg.create(gpa, src_loc, "exported symbol collision: {}", .{ + new_export.opts.name.fmt(&mod.intern_pool), }); errdefer msg.destroy(gpa); const other_export = gop.value_ptr.*; @@ -6752,18 +6731,9 @@ pub fn errorUnionType(mod: *Module, error_set_ty: Type, payload_ty: Type) Alloca } })).toType(); } -pub fn singleErrorSetType(mod: *Module, name: []const u8) Allocator.Error!Type { - const gpa = mod.gpa; - const ip = &mod.intern_pool; - return singleErrorSetTypeNts(mod, try ip.getOrPutString(gpa, name)); -} - -pub fn singleErrorSetTypeNts(mod: *Module, name: InternPool.NullTerminatedString) Allocator.Error!Type { - const gpa = mod.gpa; - const ip = &mod.intern_pool; - const names = [1]InternPool.NullTerminatedString{name}; - const i = try ip.get(gpa, .{ .error_set_type = .{ .names = &names } }); - return i.toType(); +pub fn singleErrorSetType(mod: *Module, name: InternPool.NullTerminatedString) Allocator.Error!Type { + const names: *const [1]InternPool.NullTerminatedString = &name; + return (try mod.intern_pool.get(mod.gpa, .{ .error_set_type = .{ .names = names } })).toType(); } /// Sorts `names` in place. diff --git a/src/Sema.zig b/src/Sema.zig index 8d733dfb3c..cc79578931 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -309,17 +309,17 @@ pub const Block = struct { src_loc.lazy = .{ .node_offset_fn_type_ret_ty = 0 }; break :blk src_loc; } else blk: { - const src_decl = sema.mod.declPtr(rt.block.src_decl); + const src_decl = mod.declPtr(rt.block.src_decl); break :blk rt.func_src.toSrcLoc(src_decl, mod); }; if (rt.return_ty.isGenericPoison()) { - return sema.mod.errNoteNonLazy(src_loc, parent, prefix ++ "the generic function was instantiated with a comptime-only return type", .{}); + return mod.errNoteNonLazy(src_loc, parent, prefix ++ "the generic function was instantiated with a comptime-only return type", .{}); } - try sema.mod.errNoteNonLazy( + try mod.errNoteNonLazy( src_loc, parent, prefix ++ "the function returns a comptime-only type '{}'", - .{rt.return_ty.fmt(sema.mod)}, + .{rt.return_ty.fmt(mod)}, ); try sema.explainWhyTypeIsComptime(parent, src_loc, rt.return_ty); }, @@ -2825,7 +2825,6 @@ fn createAnonymousDeclTypeNamed( ) !Decl.Index { const mod = sema.mod; const gpa = sema.gpa; - const ip = &mod.intern_pool; const namespace = block.namespace; const src_scope = block.wip_capture_scope; const src_decl = mod.declPtr(block.src_decl); @@ -2842,12 +2841,8 @@ fn createAnonymousDeclTypeNamed( // This name is also used as the key in the parent namespace so it cannot be // renamed. - // This ensureUnusedCapacity protects against the src_decl slice from being - // reallocated during the call to `getOrPutStringFmt`. - try ip.string_bytes.ensureUnusedCapacity(gpa, ip.stringToSlice(src_decl.name).len + - anon_prefix.len + 20); - const name = ip.getOrPutStringFmt(gpa, "{s}__{s}_{d}", .{ - ip.stringToSlice(src_decl.name), anon_prefix, @enumToInt(new_decl_index), + const name = mod.intern_pool.getOrPutStringFmt(gpa, "{}__{s}_{d}", .{ + src_decl.name.fmt(&mod.intern_pool), anon_prefix, @enumToInt(new_decl_index), }) catch unreachable; try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name); return new_decl_index; @@ -2863,8 +2858,9 @@ fn createAnonymousDeclTypeNamed( var buf = std.ArrayList(u8).init(gpa); defer buf.deinit(); - try buf.appendSlice(ip.stringToSlice(mod.declPtr(block.src_decl).name)); - try buf.appendSlice("("); + + const writer = buf.writer(); + try writer.print("{}(", .{mod.declPtr(block.src_decl).name.fmt(&mod.intern_pool)}); var arg_i: usize = 0; for (fn_info.param_body) |zir_inst| switch (zir_tags[zir_inst]) { @@ -2878,8 +2874,8 @@ fn createAnonymousDeclTypeNamed( const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, "") catch return sema.createAnonymousDeclTypeNamed(block, src, typed_value, .anon, anon_prefix, null); - if (arg_i != 0) try buf.appendSlice(","); - try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)}); + if (arg_i != 0) try writer.writeByte(','); + try writer.print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)}); arg_i += 1; continue; @@ -2887,8 +2883,8 @@ fn createAnonymousDeclTypeNamed( else => continue, }; - try buf.appendSlice(")"); - const name = try ip.getOrPutString(gpa, buf.items); + try writer.writeByte(')'); + const name = try mod.intern_pool.getOrPutString(gpa, buf.items); try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name); return new_decl_index; }, @@ -2901,17 +2897,9 @@ fn createAnonymousDeclTypeNamed( .dbg_var_ptr, .dbg_var_val => { if (zir_data[i].str_op.operand != ref) continue; - // This ensureUnusedCapacity protects against the src_decl - // slice from being reallocated during the call to - // `getOrPutStringFmt`. - const zir_str = zir_data[i].str_op.getStr(sema.code); - try ip.string_bytes.ensureUnusedCapacity( - gpa, - ip.stringToSlice(src_decl.name).len + zir_str.len + 10, - ); - const name = ip.getOrPutStringFmt(gpa, "{s}.{s}", .{ - ip.stringToSlice(src_decl.name), zir_str, - }) catch unreachable; + const name = try mod.intern_pool.getOrPutStringFmt(gpa, "{}.{s}", .{ + src_decl.name.fmt(&mod.intern_pool), zir_data[i].str_op.getStr(sema.code), + }); try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name); return new_decl_index; @@ -4538,8 +4526,8 @@ fn validateStructInit( continue; } const field_name = struct_ty.structFieldName(i, mod); - const template = "missing struct field: {s}"; - const args = .{ip.stringToSlice(field_name)}; + const template = "missing struct field: {}"; + const args = .{field_name.fmt(ip)}; if (root_msg) |msg| { try sema.errNote(block, init_src, msg, template, args); } else { @@ -4560,12 +4548,12 @@ fn validateStructInit( if (root_msg) |msg| { if (mod.typeToStruct(struct_ty)) |struct_obj| { - const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod)); + const fqn = try struct_obj.getFullyQualifiedName(mod); try mod.errNoteNonLazy( struct_obj.srcLoc(mod), msg, - "struct '{s}' declared here", - .{fqn}, + "struct '{}' declared here", + .{fqn.fmt(ip)}, ); } root_msg = null; @@ -4682,8 +4670,8 @@ fn validateStructInit( continue; } const field_name = struct_ty.structFieldName(i, mod); - const template = "missing struct field: {s}"; - const args = .{ip.stringToSlice(field_name)}; + const template = "missing struct field: {}"; + const args = .{field_name.fmt(ip)}; if (root_msg) |msg| { try sema.errNote(block, init_src, msg, template, args); } else { @@ -4696,12 +4684,12 @@ fn validateStructInit( if (root_msg) |msg| { if (mod.typeToStruct(struct_ty)) |struct_obj| { - const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod)); - try sema.mod.errNoteNonLazy( + const fqn = try struct_obj.getFullyQualifiedName(mod); + try mod.errNoteNonLazy( struct_obj.srcLoc(mod), msg, - "struct '{s}' declared here", - .{fqn}, + "struct '{}' declared here", + .{fqn.fmt(ip)}, ); } root_msg = null; @@ -4942,11 +4930,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr const operand_ty = sema.typeOf(operand); if (operand_ty.zigTypeTag(mod) != .Pointer) { - return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(sema.mod)}); + return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(mod)}); } else switch (operand_ty.ptrSize(mod)) { .One, .C => {}, - .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(sema.mod)}), - .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}), + .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(mod)}), + .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(mod)}), } if ((try sema.typeHasOnePossibleValue(operand_ty.childType(mod))) != null) { @@ -4965,11 +4953,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr block, src, "values of type '{}' must be comptime-known, but operand value is runtime-known", - .{elem_ty.fmt(sema.mod)}, + .{elem_ty.fmt(mod)}, ); errdefer msg.destroy(sema.gpa); - const src_decl = sema.mod.declPtr(block.src_decl); + const src_decl = mod.declPtr(block.src_decl); try sema.explainWhyTypeIsComptime(msg, src.toSrcLoc(src_decl, mod), elem_ty); break :msg msg; }; @@ -4982,7 +4970,7 @@ fn failWithBadMemberAccess( block: *Block, agg_ty: Type, field_src: LazySrcLoc, - field_name_nts: InternPool.NullTerminatedString, + field_name: InternPool.NullTerminatedString, ) CompileError { const mod = sema.mod; const kw_name = switch (agg_ty.zigTypeTag(mod)) { @@ -4992,15 +4980,14 @@ fn failWithBadMemberAccess( .Enum => "enum", else => unreachable, }; - const field_name = mod.intern_pool.stringToSlice(field_name_nts); - if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (sema.mod.declIsRoot(some)) { - return sema.fail(block, field_src, "root struct of file '{}' has no member named '{s}'", .{ - agg_ty.fmt(sema.mod), field_name, + if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) { + return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{ + agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool), }); }; const msg = msg: { - const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{ - kw_name, agg_ty.fmt(sema.mod), field_name, + const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{}'", .{ + kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool), }); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, agg_ty); @@ -5018,16 +5005,15 @@ fn failWithBadStructFieldAccess( ) CompileError { const mod = sema.mod; const gpa = sema.gpa; - const ip = &mod.intern_pool; - const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod)); + const fqn = try struct_obj.getFullyQualifiedName(mod); const msg = msg: { const msg = try sema.errMsg( block, field_src, - "no field named '{s}' in struct '{s}'", - .{ ip.stringToSlice(field_name), fqn }, + "no field named '{}' in struct '{}'", + .{ field_name.fmt(&mod.intern_pool), fqn.fmt(&mod.intern_pool) }, ); errdefer msg.destroy(gpa); try mod.errNoteNonLazy(struct_obj.srcLoc(mod), msg, "struct declared here", .{}); @@ -5045,16 +5031,15 @@ fn failWithBadUnionFieldAccess( ) CompileError { const mod = sema.mod; const gpa = sema.gpa; - const ip = &mod.intern_pool; - const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod)); + const fqn = try union_obj.getFullyQualifiedName(mod); const msg = msg: { const msg = try sema.errMsg( block, field_src, - "no field named '{s}' in union '{s}'", - .{ ip.stringToSlice(field_name), fqn }, + "no field named '{}' in union '{}'", + .{ field_name.fmt(&mod.intern_pool), fqn.fmt(&mod.intern_pool) }, ); errdefer msg.destroy(gpa); try mod.errNoteNonLazy(union_obj.srcLoc(mod), msg, "union declared here", .{}); @@ -5334,7 +5319,9 @@ fn zirCompileLog( sema: *Sema, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { - var managed = sema.mod.compile_log_text.toManaged(sema.gpa); + const mod = sema.mod; + + var managed = mod.compile_log_text.toManaged(sema.gpa); defer sema.mod.compile_log_text = managed.moveToUnmanaged(); const writer = managed.writer(); @@ -5349,16 +5336,16 @@ fn zirCompileLog( const arg_ty = sema.typeOf(arg); if (try sema.resolveMaybeUndefLazyVal(arg)) |val| { try writer.print("@as({}, {})", .{ - arg_ty.fmt(sema.mod), val.fmtValue(arg_ty, sema.mod), + arg_ty.fmt(mod), val.fmtValue(arg_ty, mod), }); } else { - try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(sema.mod)}); + try writer.print("@as({}, [runtime value])", .{arg_ty.fmt(mod)}); } } try writer.print("\n", .{}); const decl_index = if (sema.func) |some| some.owner_decl else sema.owner_decl_index; - const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, decl_index); + const gop = try mod.compile_log_decls.getOrPut(sema.gpa, decl_index); if (!gop.found_existing) { gop.value_ptr.* = src_node; } @@ -5509,7 +5496,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr if (!mod.comp.bin_file.options.link_libc) try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{}); - const gop = try sema.mod.cimport_errors.getOrPut(sema.gpa, sema.owner_decl_index); + const gop = try mod.cimport_errors.getOrPut(sema.gpa, sema.owner_decl_index); if (!gop.found_existing) { var errs = try std.ArrayListUnmanaged(Module.CImportError).initCapacity(sema.gpa, c_import_res.errors.len); errdefer { @@ -5869,13 +5856,13 @@ pub fn analyzeExport( sema: *Sema, block: *Block, src: LazySrcLoc, - borrowed_options: std.builtin.ExportOptions, + options: Module.Export.Options, exported_decl_index: Decl.Index, ) !void { const Export = Module.Export; const mod = sema.mod; - if (borrowed_options.linkage == .Internal) { + if (options.linkage == .Internal) { return; } @@ -5884,10 +5871,10 @@ pub fn analyzeExport( if (!try sema.validateExternType(exported_decl.ty, .other)) { const msg = msg: { - const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(sema.mod)}); + const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(mod)}); errdefer msg.destroy(sema.gpa); - const src_decl = sema.mod.declPtr(block.src_decl); + const src_decl = mod.declPtr(block.src_decl); try sema.explainWhyTypeIsNotExtern(msg, src.toSrcLoc(src_decl, mod), exported_decl.ty, .other); try sema.addDeclaredHereNote(msg, exported_decl.ty); @@ -5913,14 +5900,8 @@ pub fn analyzeExport( const new_export = try gpa.create(Export); errdefer gpa.destroy(new_export); - const symbol_name = try mod.intern_pool.getOrPutString(gpa, borrowed_options.name); - const section = try mod.intern_pool.getOrPutStringOpt(gpa, borrowed_options.section); - new_export.* = .{ - .name = symbol_name, - .linkage = borrowed_options.linkage, - .section = section, - .visibility = borrowed_options.visibility, + .opts = options, .src = src, .owner_decl = sema.owner_decl_index, .src_decl = block.src_decl, @@ -6198,7 +6179,7 @@ fn lookupInNamespace( const namespace = mod.namespacePtr(namespace_index); const namespace_decl_index = namespace.getDeclIndex(mod); - const namespace_decl = sema.mod.declPtr(namespace_decl_index); + const namespace_decl = mod.declPtr(namespace_decl_index); if (namespace_decl.analysis == .file_failure) { try mod.declareDeclDependency(sema.owner_decl_index, namespace_decl_index); return error.AnalysisFail; @@ -6531,7 +6512,7 @@ fn zirCall( // AstGen ensures that a call instruction is always preceded by a dbg_stmt instruction. const call_dbg_node = inst - 1; - if (sema.mod.backendSupportsFeature(.error_return_trace) and sema.mod.comp.bin_file.options.error_return_tracing and + if (mod.backendSupportsFeature(.error_return_trace) and mod.comp.bin_file.options.error_return_tracing and !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace)) { const call_inst: Air.Inst.Ref = if (modifier == .always_tail) undefined else b: { @@ -6599,7 +6580,7 @@ fn checkCallArgumentCount( { const msg = msg: { const msg = try sema.errMsg(block, func_src, "cannot call optional type '{}'", .{ - callee_ty.fmt(sema.mod), + callee_ty.fmt(mod), }); errdefer msg.destroy(sema.gpa); try sema.errNote(block, func_src, msg, "consider using '.?', 'orelse' or 'if'", .{}); @@ -6610,7 +6591,7 @@ fn checkCallArgumentCount( }, else => {}, } - return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(sema.mod)}); + return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(mod)}); }; const func_ty_info = mod.typeToFunc(func_ty).?; @@ -6640,7 +6621,7 @@ fn checkCallArgumentCount( ); errdefer msg.destroy(sema.gpa); - if (maybe_decl) |fn_decl| try sema.mod.errNoteNonLazy(fn_decl.srcLoc(mod), msg, "function declared here", .{}); + if (maybe_decl) |fn_decl| try mod.errNoteNonLazy(fn_decl.srcLoc(mod), msg, "function declared here", .{}); break :msg msg; }; return sema.failWithOwnedErrorMsg(msg); @@ -6666,7 +6647,7 @@ fn callBuiltin( }, else => {}, } - std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(sema.mod)}); + std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(mod)}); }; const func_ty_info = mod.typeToFunc(func_ty).?; @@ -6942,7 +6923,7 @@ fn analyzeCall( ) catch |err| switch (err) { error.NeededSourceLocation => { _ = sema.inst_map.remove(inst); - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); try sema.analyzeInlineCallArg( block, &child_block, @@ -7111,7 +7092,7 @@ fn analyzeCall( opts, ) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); _ = try sema.analyzeCallArg( block, mod.argSrc(call_src.node_offset.x, decl, i, bound_arg_src), @@ -7126,7 +7107,7 @@ fn analyzeCall( } else { args[i] = sema.coerceVarArgParam(block, uncasted_arg, .unneeded) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); _ = try sema.coerceVarArgParam( block, uncasted_arg, @@ -7148,7 +7129,7 @@ fn analyzeCall( if (try sema.resolveMaybeUndefVal(func)) |func_val| { if (mod.intern_pool.indexToFunc(func_val.toIntern()).unwrap()) |func_index| { - try sema.mod.ensureFuncBodyAnalysisQueued(func_index); + try mod.ensureFuncBodyAnalysisQueued(func_index); } } @@ -7201,17 +7182,18 @@ fn analyzeCall( } fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref { - const target = sema.mod.getTarget(); - const backend = sema.mod.comp.getZigBackend(); + const mod = sema.mod; + const target = mod.getTarget(); + const backend = mod.comp.getZigBackend(); if (!target_util.supportsTailCall(target, backend)) { return sema.fail(block, call_src, "unable to perform tail call: compiler backend '{s}' does not support tail calls on target architecture '{s}' with the selected CPU feature flags", .{ @tagName(backend), @tagName(target.cpu.arch), }); } - const func_decl = sema.mod.declPtr(sema.owner_func.?.owner_decl); - if (!func_ty.eql(func_decl.ty, sema.mod)) { + const func_decl = mod.declPtr(sema.owner_func.?.owner_decl); + if (!func_ty.eql(func_decl.ty, mod)) { return sema.fail(block, call_src, "unable to perform tail call: type of function being called '{}' does not match type of calling function '{}'", .{ - func_ty.fmt(sema.mod), func_decl.ty.fmt(sema.mod), + func_ty.fmt(mod), func_decl.ty.fmt(mod), }); } _ = try block.addUnOp(.ret, result); @@ -7404,10 +7386,9 @@ fn instantiateGenericCall( ) CompileError!Air.Inst.Ref { const mod = sema.mod; const gpa = sema.gpa; - const ip = &mod.intern_pool; const func_val = try sema.resolveConstValue(block, func_src, func, "generic function being called must be comptime-known"); - const module_fn_index = switch (ip.indexToKey(func_val.toIntern())) { + const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) { .func => |function| function.index, .ptr => |ptr| mod.declPtr(ptr.addr.decl).val.getFunctionIndex(mod).unwrap().?, else => unreachable, @@ -7467,7 +7448,7 @@ fn instantiateGenericCall( if (is_comptime) { const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[arg_i]) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); const arg_src = mod.argSrc(call_src.node_offset.x, decl, arg_i, bound_arg_src); _ = try sema.analyzeGenericCallArgVal(block, arg_src, uncasted_args[arg_i]); unreachable; @@ -7491,7 +7472,7 @@ fn instantiateGenericCall( }; const casted_arg = sema.coerce(block, final_arg_ty.toType(), uncasted_args[arg_i], .unneeded) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); const arg_src = mod.argSrc(call_src.node_offset.x, decl, arg_i, bound_arg_src); _ = try sema.coerce(block, final_arg_ty.toType(), uncasted_args[arg_i], arg_src); unreachable; @@ -7500,7 +7481,7 @@ fn instantiateGenericCall( }; const casted_arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, casted_arg) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); const arg_src = mod.argSrc(call_src.node_offset.x, decl, arg_i, bound_arg_src); _ = try sema.analyzeGenericCallArgVal(block, arg_src, casted_arg); unreachable; @@ -7540,12 +7521,9 @@ fn instantiateGenericCall( const new_decl_index = try mod.allocateNewDecl(namespace_index, fn_owner_decl.src_node, src_decl.src_scope); const new_decl = mod.declPtr(new_decl_index); // TODO better names for generic function instantiations - // The ensureUnusedCapacity here protects against fn_owner_decl.name slice being - // reallocated during getOrPutStringFmt. - try ip.string_bytes.ensureUnusedCapacity(gpa, ip.stringToSlice(fn_owner_decl.name).len + 20); - const decl_name = ip.getOrPutStringFmt(gpa, "{s}__anon_{d}", .{ - ip.stringToSlice(fn_owner_decl.name), @enumToInt(new_decl_index), - }) catch unreachable; + const decl_name = try mod.intern_pool.getOrPutStringFmt(gpa, "{}__anon_{d}", .{ + fn_owner_decl.name.fmt(&mod.intern_pool), @enumToInt(new_decl_index), + }); new_decl.name = decl_name; new_decl.src_line = fn_owner_decl.src_line; new_decl.is_pub = fn_owner_decl.is_pub; @@ -7634,7 +7612,7 @@ fn instantiateGenericCall( &runtime_i, ) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); _ = try sema.analyzeGenericCallArg( block, mod.argSrc(call_src.node_offset.x, decl, total_i, bound_arg_src), @@ -7660,7 +7638,7 @@ fn instantiateGenericCall( sema.owner_func.?.calls_or_awaits_errorable_fn = true; } - try sema.mod.ensureFuncBodyAnalysisQueued(callee_index); + try mod.ensureFuncBodyAnalysisQueued(callee_index); try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Call).Struct.fields.len + runtime_args_len); @@ -7788,7 +7766,7 @@ fn resolveGenericInstantiationType( if (try sema.typeRequiresComptime(arg_ty)) { const arg_val = sema.resolveConstValue(block, .unneeded, arg, "") catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); const arg_src = mod.argSrc(call_src.node_offset.x, decl, arg_i, bound_arg_src); _ = try sema.resolveConstValue(block, arg_src, arg, "argument to parameter with comptime-only type must be comptime-known"); unreachable; @@ -7981,9 +7959,9 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node }; const child_type = try sema.resolveType(block, operand_src, inst_data.operand); if (child_type.zigTypeTag(mod) == .Opaque) { - return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(sema.mod)}); + return sema.fail(block, operand_src, "opaque type '{}' cannot be optional", .{child_type.fmt(mod)}); } else if (child_type.zigTypeTag(mod) == .Null) { - return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(sema.mod)}); + return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(mod)}); } const opt_type = try Type.optional(sema.arena, child_type, mod); @@ -8059,7 +8037,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil fn validateArrayElemType(sema: *Sema, block: *Block, elem_type: Type, elem_src: LazySrcLoc) !void { const mod = sema.mod; if (elem_type.zigTypeTag(mod) == .Opaque) { - return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(sema.mod)}); + return sema.fail(block, elem_src, "array of opaque type '{}' not allowed", .{elem_type.fmt(mod)}); } else if (elem_type.zigTypeTag(mod) == .NoReturn) { return sema.fail(block, elem_src, "array of 'noreturn' not allowed", .{}); } @@ -8095,7 +8073,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr if (error_set.zigTypeTag(mod) != .ErrorSet) { return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{ - error_set.fmt(sema.mod), + error_set.fmt(mod), }); } try sema.validateErrorUnionPayloadType(block, payload, rhs_src); @@ -8107,11 +8085,11 @@ fn validateErrorUnionPayloadType(sema: *Sema, block: *Block, payload_ty: Type, p const mod = sema.mod; if (payload_ty.zigTypeTag(mod) == .Opaque) { return sema.fail(block, payload_src, "error union with payload of opaque type '{}' not allowed", .{ - payload_ty.fmt(sema.mod), + payload_ty.fmt(mod), }); } else if (payload_ty.zigTypeTag(mod) == .ErrorSet) { return sema.fail(block, payload_src, "error union with payload of error set type '{}' not allowed", .{ - payload_ty.fmt(sema.mod), + payload_ty.fmt(mod), }); } } @@ -8123,7 +8101,7 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! const name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code)); _ = try mod.getErrorValue(name); // Create an error set type with only this error value, and return the value. - const error_set_type = try mod.singleErrorSetTypeNts(name); + const error_set_type = try mod.singleErrorSetType(name); return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{ .ty = error_set_type.toIntern(), .name = name, @@ -8231,9 +8209,9 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs); const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs); if (lhs_ty.zigTypeTag(mod) != .ErrorSet) - return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(sema.mod)}); + return sema.fail(block, lhs_src, "expected error set type, found '{}'", .{lhs_ty.fmt(mod)}); if (rhs_ty.zigTypeTag(mod) != .ErrorSet) - return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(sema.mod)}); + return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(mod)}); // Anything merged with anyerror is anyerror. if (lhs_ty.toIntern() == .anyerror_type or rhs_ty.toIntern() == .anyerror_type) { @@ -8296,7 +8274,7 @@ fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A }, else => { return sema.fail(block, operand_src, "expected enum or tagged union, found '{}'", .{ - operand_ty.fmt(sema.mod), + operand_ty.fmt(mod), }); }, }; @@ -8328,7 +8306,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const operand = try sema.resolveInst(extra.rhs); if (dest_ty.zigTypeTag(mod) != .Enum) { - return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)}); + return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(mod)}); } _ = try sema.checkIntType(block, operand_src, sema.typeOf(operand)); @@ -8343,7 +8321,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A block, src, "int value '{}' out of range of non-exhaustive enum '{}'", - .{ int_val.fmtValue(sema.typeOf(operand), sema.mod), dest_ty.fmt(sema.mod) }, + .{ int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod) }, ); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, dest_ty); @@ -8360,7 +8338,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A block, src, "enum '{}' has no tag with value '{}'", - .{ dest_ty.fmt(sema.mod), int_val.fmtValue(sema.typeOf(operand), sema.mod) }, + .{ dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod) }, ); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, dest_ty); @@ -8383,7 +8361,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A try sema.requireRuntimeBlock(block, src, operand_src); const result = try block.addTyOp(.intcast, dest_ty, operand); if (block.wantSafety() and !dest_ty.isNonexhaustiveEnum(mod) and - sema.mod.backendSupportsFeature(.is_named_enum_value)) + mod.backendSupportsFeature(.is_named_enum_value)) { const ok = try block.addUnOp(.is_named_enum_value, result); try sema.addSafetyCheck(block, ok, .invalid_enum_value); @@ -8422,11 +8400,11 @@ fn analyzeOptionalPayloadPtr( const opt_type = optional_ptr_ty.childType(mod); if (opt_type.zigTypeTag(mod) != .Optional) { - return sema.fail(block, src, "expected optional type, found '{}'", .{opt_type.fmt(sema.mod)}); + return sema.fail(block, src, "expected optional type, found '{}'", .{opt_type.fmt(mod)}); } const child_type = opt_type.optionalChild(mod); - const child_pointer = try Type.ptr(sema.arena, sema.mod, .{ + const child_pointer = try Type.ptr(sema.arena, mod, .{ .pointee_type = child_type, .mutable = !optional_ptr_ty.isConstPtr(mod), .@"addrspace" = optional_ptr_ty.ptrAddressSpace(mod), @@ -8493,7 +8471,7 @@ fn zirOptionalPayload( // TODO https://github.com/ziglang/zig/issues/6597 if (true) break :t operand_ty; const ptr_info = operand_ty.ptrInfo(mod); - break :t try Type.ptr(sema.arena, sema.mod, .{ + break :t try Type.ptr(sema.arena, mod, .{ .pointee_type = ptr_info.pointee_type, .@"align" = ptr_info.@"align", .@"addrspace" = ptr_info.@"addrspace", @@ -8538,7 +8516,7 @@ fn zirErrUnionPayload( const err_union_ty = sema.typeOf(operand); if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { return sema.fail(block, operand_src, "expected error union type, found '{}'", .{ - err_union_ty.fmt(sema.mod), + err_union_ty.fmt(mod), }); } return sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false); @@ -8556,8 +8534,8 @@ fn analyzeErrUnionPayload( const mod = sema.mod; const payload_ty = err_union_ty.errorUnionPayload(mod); if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { - if (val.getError(mod)) |name| { - return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); + if (val.getErrorName(mod).unwrap()) |name| { + return sema.fail(block, src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)}); } return sema.addConstant( payload_ty, @@ -8607,13 +8585,13 @@ fn analyzeErrUnionPayloadPtr( if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) { return sema.fail(block, src, "expected error union type, found '{}'", .{ - operand_ty.childType(mod).fmt(sema.mod), + operand_ty.childType(mod).fmt(mod), }); } const err_union_ty = operand_ty.childType(mod); const payload_ty = err_union_ty.errorUnionPayload(mod); - const operand_pointer_ty = try Type.ptr(sema.arena, sema.mod, .{ + const operand_pointer_ty = try Type.ptr(sema.arena, mod, .{ .pointee_type = payload_ty, .mutable = !operand_ty.isConstPtr(mod), .@"addrspace" = operand_ty.ptrAddressSpace(mod), @@ -8634,8 +8612,8 @@ fn analyzeErrUnionPayloadPtr( } })).toValue()); } if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| { - if (val.getError(mod)) |name| { - return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); + if (val.getErrorName(mod).unwrap()) |name| { + return sema.fail(block, src, "caught unexpected error '{}'", .{name.fmt(&mod.intern_pool)}); } return sema.addConstant(operand_pointer_ty, (try mod.intern(.{ .ptr = .{ .ty = operand_pointer_ty.toIntern(), @@ -8676,7 +8654,7 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air const operand_ty = sema.typeOf(operand); if (operand_ty.zigTypeTag(mod) != .ErrorUnion) { return sema.fail(block, src, "expected error union type, found '{}'", .{ - operand_ty.fmt(sema.mod), + operand_ty.fmt(mod), }); } @@ -8707,7 +8685,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) { return sema.fail(block, src, "expected error union type, found '{}'", .{ - operand_ty.childType(mod).fmt(sema.mod), + operand_ty.childType(mod).fmt(mod), }); } @@ -8715,7 +8693,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| { - assert(val.getError(mod) != null); + assert(val.getErrorName(mod) != .none); return sema.addConstant(result_ty, val); } } @@ -8968,7 +8946,7 @@ fn funcCommon( }; errdefer if (destroy_fn_on_error) mod.destroyFunc(new_func_index); - const target = sema.mod.getTarget(); + const target = mod.getTarget(); const fn_ty: Type = fn_ty: { // In the case of generic calling convention, or generic alignment, we use // default values which are only meaningful for the generic function, *not* @@ -8995,7 +8973,7 @@ fn funcCommon( is_noalias, ) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); try sema.analyzeParameter( block, Module.paramSrc(src_node_offset, mod, decl, i), @@ -9040,7 +9018,7 @@ fn funcCommon( const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else ""; const msg = msg: { const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{ - opaque_str, return_type.fmt(sema.mod), + opaque_str, return_type.fmt(mod), }); errdefer msg.destroy(gpa); @@ -9054,11 +9032,11 @@ fn funcCommon( { const msg = msg: { const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{ - return_type.fmt(sema.mod), @tagName(cc_resolved), + return_type.fmt(mod), @tagName(cc_resolved), }); errdefer msg.destroy(gpa); - const src_decl = sema.mod.declPtr(block.src_decl); + const src_decl = mod.declPtr(block.src_decl); try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src.toSrcLoc(src_decl, mod), return_type, .ret_ty); try sema.addDeclaredHereNote(msg, return_type); @@ -9077,7 +9055,7 @@ fn funcCommon( block, ret_ty_src, "function with comptime-only return type '{}' requires all parameters to be comptime", - .{return_type.fmt(sema.mod)}, + .{return_type.fmt(mod)}, ); try sema.explainWhyTypeIsComptime(msg, ret_ty_src.toSrcLoc(sema.owner_decl, mod), return_type); @@ -9102,7 +9080,7 @@ fn funcCommon( return sema.failWithOwnedErrorMsg(msg); } - const arch = sema.mod.getTarget().cpu.arch; + const arch = mod.getTarget().cpu.arch; if (switch (cc_resolved) { .Unspecified, .C, .Naked, .Async, .Inline => null, .Interrupt => switch (arch) { @@ -9542,7 +9520,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const ptr = try sema.resolveInst(inst_data.operand); const ptr_ty = sema.typeOf(ptr); if (!ptr_ty.isPtrAtRuntime(mod)) { - return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}); + return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(mod)}); } if (try sema.resolveMaybeUndefValIntable(ptr)) |ptr_val| { return sema.addConstant( @@ -9797,14 +9775,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air .Type, .Undefined, .Void, - => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)}), + => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)}), .Enum => { const msg = msg: { - const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)}); + const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)}); errdefer msg.destroy(sema.gpa); switch (operand_ty.zigTypeTag(mod)) { - .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum to cast from '{}'", .{operand_ty.fmt(sema.mod)}), + .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum to cast from '{}'", .{operand_ty.fmt(mod)}), else => {}, } @@ -9815,11 +9793,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air .Pointer => { const msg = msg: { - const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)}); + const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(mod)}); errdefer msg.destroy(sema.gpa); switch (operand_ty.zigTypeTag(mod)) { - .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToPtr to cast from '{}'", .{operand_ty.fmt(sema.mod)}), - .Pointer => try sema.errNote(block, dest_ty_src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(sema.mod)}), + .Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToPtr to cast from '{}'", .{operand_ty.fmt(mod)}), + .Pointer => try sema.errNote(block, dest_ty_src, msg, "use @ptrCast to cast from '{}'", .{operand_ty.fmt(mod)}), else => {}, } @@ -9834,7 +9812,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air else => unreachable, }; return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}'; {s} does not have a guaranteed in-memory layout", .{ - dest_ty.fmt(sema.mod), container, + dest_ty.fmt(mod), container, }); }, @@ -9861,14 +9839,14 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air .Type, .Undefined, .Void, - => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)}), + => return sema.fail(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)}), .Enum => { const msg = msg: { - const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)}); + const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)}); errdefer msg.destroy(sema.gpa); switch (dest_ty.zigTypeTag(mod)) { - .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @enumToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}), + .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @enumToInt to cast to '{}'", .{dest_ty.fmt(mod)}), else => {}, } @@ -9878,11 +9856,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air }, .Pointer => { const msg = msg: { - const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(sema.mod)}); + const msg = try sema.errMsg(block, operand_src, "cannot @bitCast from '{}'", .{operand_ty.fmt(mod)}); errdefer msg.destroy(sema.gpa); switch (dest_ty.zigTypeTag(mod)) { - .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @ptrToInt to cast to '{}'", .{dest_ty.fmt(sema.mod)}), - .Pointer => try sema.errNote(block, operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(sema.mod)}), + .Int, .ComptimeInt => try sema.errNote(block, operand_src, msg, "use @ptrToInt to cast to '{}'", .{dest_ty.fmt(mod)}), + .Pointer => try sema.errNote(block, operand_src, msg, "use @ptrCast to cast to '{}'", .{dest_ty.fmt(mod)}), else => {}, } @@ -9897,7 +9875,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air else => unreachable, }; return sema.fail(block, operand_src, "cannot @bitCast from '{}'; {s} does not have a guaranteed in-memory layout", .{ - operand_ty.fmt(sema.mod), container, + operand_ty.fmt(mod), container, }); }, @@ -9924,7 +9902,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs); const operand = try sema.resolveInst(extra.rhs); - const target = sema.mod.getTarget(); + const target = mod.getTarget(); const dest_is_comptime_float = switch (dest_ty.zigTypeTag(mod)) { .ComptimeFloat => true, .Float => false, @@ -9932,7 +9910,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A block, dest_ty_src, "expected float type, found '{}'", - .{dest_ty.fmt(sema.mod)}, + .{dest_ty.fmt(mod)}, ), }; @@ -9943,7 +9921,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A block, operand_src, "expected float type, found '{}'", - .{operand_ty.fmt(sema.mod)}, + .{operand_ty.fmt(mod)}, ), } @@ -10002,7 +9980,7 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const capture_src: LazySrcLoc = .{ .for_capture_from_input = inst_data.src_node }; const msg = msg: { const msg = try sema.errMsg(block, capture_src, "pointer capture of non pointer type '{}'", .{ - indexable_ty.fmt(sema.mod), + indexable_ty.fmt(mod), }); errdefer msg.destroy(sema.gpa); if (indexable_ty.zigTypeTag(mod) == .Array) { @@ -10143,12 +10121,12 @@ fn zirSwitchCapture( const item_val = sema.resolveConstValue(block, .unneeded, block.inline_case_capture, undefined) catch unreachable; const resolved_item_val = try sema.resolveLazyValue(item_val); if (operand_ty.zigTypeTag(mod) == .Union) { - const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(resolved_item_val, sema.mod).?); + const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(resolved_item_val, mod).?); const union_obj = mod.typeToUnion(operand_ty).?; const field_ty = union_obj.fields.values()[field_index].ty; if (try sema.resolveDefinedValue(block, sema.src, operand_ptr)) |union_val| { if (is_ref) { - const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ + const ptr_field_ty = try Type.ptr(sema.arena, mod, .{ .pointee_type = field_ty, .mutable = operand_ptr_ty.ptrIsMutable(mod), .@"volatile" = operand_ptr_ty.isVolatilePtr(mod), @@ -10168,7 +10146,7 @@ fn zirSwitchCapture( ); } if (is_ref) { - const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ + const ptr_field_ty = try Type.ptr(sema.arena, mod, .{ .pointee_type = field_ty, .mutable = operand_ptr_ty.ptrIsMutable(mod), .@"volatile" = operand_ptr_ty.isVolatilePtr(mod), @@ -10221,7 +10199,7 @@ fn zirSwitchCapture( // Previous switch validation ensured this will succeed const first_item_val = sema.resolveConstValue(block, .unneeded, first_item, "") catch unreachable; - const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, sema.mod).?); + const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, mod).?); const first_field = union_obj.fields.values()[first_field_index]; for (items[1..], 0..) |item, i| { @@ -10229,22 +10207,22 @@ fn zirSwitchCapture( // Previous switch validation ensured this will succeed const item_val = sema.resolveConstValue(block, .unneeded, item_ref, "") catch unreachable; - const field_index = operand_ty.unionTagFieldIndex(item_val, sema.mod).?; + const field_index = operand_ty.unionTagFieldIndex(item_val, mod).?; const field = union_obj.fields.values()[field_index]; - if (!field.ty.eql(first_field.ty, sema.mod)) { + if (!field.ty.eql(first_field.ty, mod)) { const msg = msg: { const raw_capture_src = Module.SwitchProngSrc{ .multi_capture = capture_info.prong_index }; - const capture_src = raw_capture_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first); + const capture_src = raw_capture_src.resolve(mod, mod.declPtr(block.src_decl), switch_info.src_node, .first); const msg = try sema.errMsg(block, capture_src, "capture group with incompatible types", .{}); errdefer msg.destroy(gpa); const raw_first_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 0 } }; - const first_item_src = raw_first_item_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first); + const first_item_src = raw_first_item_src.resolve(mod, mod.declPtr(block.src_decl), switch_info.src_node, .first); const raw_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 1 + @intCast(u32, i) } }; - const item_src = raw_item_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_info.src_node, .first); - try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(sema.mod)}); - try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(sema.mod)}); + const item_src = raw_item_src.resolve(mod, mod.declPtr(block.src_decl), switch_info.src_node, .first); + try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(mod)}); + try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(mod)}); break :msg msg; }; return sema.failWithOwnedErrorMsg(msg); @@ -10252,7 +10230,7 @@ fn zirSwitchCapture( } if (is_ref) { - const field_ty_ptr = try Type.ptr(sema.arena, sema.mod, .{ + const field_ty_ptr = try Type.ptr(sema.arena, mod, .{ .pointee_type = first_field.ty, .@"addrspace" = .generic, .mutable = operand_ptr_ty.ptrIsMutable(mod), @@ -10288,8 +10266,7 @@ fn zirSwitchCapture( const item_ref = try sema.resolveInst(item); // Previous switch validation ensured this will succeed const item_val = sema.resolveConstLazyValue(block, .unneeded, item_ref, "") catch unreachable; - const name_ip = try mod.intern_pool.getOrPutString(gpa, item_val.getError(mod).?); - names.putAssumeCapacityNoClobber(name_ip, {}); + names.putAssumeCapacityNoClobber(item_val.getErrorName(mod).unwrap().?, {}); } const else_error_ty = try mod.errorSetFromUnsortedNames(names.keys()); @@ -10299,7 +10276,7 @@ fn zirSwitchCapture( // Previous switch validation ensured this will succeed const item_val = sema.resolveConstLazyValue(block, .unneeded, item_ref, "") catch unreachable; - const item_ty = try mod.singleErrorSetType(item_val.getError(mod).?); + const item_ty = try mod.singleErrorSetType(item_val.getErrorName(mod).unwrap().?); return sema.bitCast(block, item_ty, operand, operand_src, null); } }, @@ -10331,7 +10308,7 @@ fn zirSwitchCaptureTag(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile if (operand_ty.zigTypeTag(mod) != .Union) { const msg = msg: { const msg = try sema.errMsg(block, src, "cannot capture tag of non-union type '{}'", .{ - operand_ty.fmt(sema.mod), + operand_ty.fmt(mod), }); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, operand_ty); @@ -10375,7 +10352,7 @@ fn zirSwitchCond( .Enum, => { if (operand_ty.isSlice(mod)) { - return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(sema.mod)}); + return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(mod)}); } if ((try sema.typeHasOnePossibleValue(operand_ty))) |opv| { return sema.addConstant(operand_ty, opv); @@ -10389,8 +10366,8 @@ fn zirSwitchCond( const msg = msg: { const msg = try sema.errMsg(block, src, "switch on union with no attached enum", .{}); errdefer msg.destroy(sema.gpa); - if (union_ty.declSrcLocOrNull(sema.mod)) |union_src| { - try sema.mod.errNoteNonLazy(union_src, msg, "consider 'union(enum)' here", .{}); + if (union_ty.declSrcLocOrNull(mod)) |union_src| { + try mod.errNoteNonLazy(union_src, msg, "consider 'union(enum)' here", .{}); } break :msg msg; }; @@ -10410,11 +10387,11 @@ fn zirSwitchCond( .Vector, .Frame, .AnyFrame, - => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(sema.mod)}), + => return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(mod)}), } } -const SwitchErrorSet = std.StringHashMap(Module.SwitchProngSrc); +const SwitchErrorSet = std.AutoHashMap(InternPool.NullTerminatedString, Module.SwitchProngSrc); fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -10593,8 +10570,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError operand_ty, i, msg, - "unhandled enumeration value: '{s}'", - .{ip.stringToSlice(field_name)}, + "unhandled enumeration value: '{}'", + .{field_name.fmt(&mod.intern_pool)}, ); } try mod.errNoteNonLazy( @@ -10677,8 +10654,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError var maybe_msg: ?*Module.ErrorMsg = null; errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa); - for (operand_ty.errorSetNames(mod)) |error_name_ip| { - const error_name = ip.stringToSlice(error_name_ip); + for (operand_ty.errorSetNames(mod)) |error_name| { if (!seen_errors.contains(error_name) and special_prong != .@"else") { const msg = maybe_msg orelse blk: { maybe_msg = try sema.errMsg( @@ -10694,8 +10670,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError block, src, msg, - "unhandled error value: 'error.{s}'", - .{error_name}, + "unhandled error value: 'error.{}'", + .{error_name.fmt(ip)}, ); } } @@ -10746,11 +10722,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError const error_names = operand_ty.errorSetNames(mod); var names: Module.Fn.InferredErrorSet.NameMap = .{}; try names.ensureUnusedCapacity(sema.arena, error_names.len); - for (error_names) |error_name_ip| { - const error_name = ip.stringToSlice(error_name_ip); + for (error_names) |error_name| { if (seen_errors.contains(error_name)) continue; - names.putAssumeCapacityNoClobber(error_name_ip, {}); + names.putAssumeCapacityNoClobber(error_name, {}); } // No need to keep the hash map metadata correct; here we // extract the (sorted) keys only. @@ -11500,14 +11475,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError }); } for (0..operand_ty.errorSetNames(mod).len) |i| { - const error_name_ip = operand_ty.errorSetNames(mod)[i]; - const error_name = mod.intern_pool.stringToSlice(error_name_ip); + const error_name = operand_ty.errorSetNames(mod)[i]; if (seen_errors.contains(error_name)) continue; cases_len += 1; const item_val = try mod.intern(.{ .err = .{ .ty = operand_ty.toIntern(), - .name = error_name_ip, + .name = error_name, } }); const item_ref = try sema.addConstant(operand_ty, item_val.toValue()); case_block.inline_case_capture = item_ref; @@ -11754,7 +11728,7 @@ fn resolveSwitchItemVal( return val.toIntern(); } else |err| switch (err) { error.NeededSourceLocation => { - const src = switch_prong_src.resolve(mod, sema.mod.declPtr(block.src_decl), switch_node_offset, range_expand); + const src = switch_prong_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, range_expand); _ = try sema.resolveConstValue(block, src, item, "switch prong values must be comptime-known"); unreachable; }, @@ -11827,7 +11801,7 @@ fn validateSwitchItemError( const ip = &sema.mod.intern_pool; const item = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); // TODO: Do i need to typecheck here? - const error_name = ip.stringToSlice(ip.indexToKey(item).err.name); + const error_name = ip.indexToKey(item).err.name; const maybe_prev_src = if (try seen_errors.fetchPut(error_name, switch_prong_src)) |prev| prev.value else @@ -11844,7 +11818,7 @@ fn validateSwitchDupe( ) CompileError!void { const prev_prong_src = maybe_prev_src orelse return; const mod = sema.mod; - const block_src_decl = sema.mod.declPtr(block.src_decl); + const block_src_decl = mod.declPtr(block.src_decl); const src = switch_prong_src.resolve(mod, block_src_decl, src_node_offset, .none); const prev_src = prev_prong_src.resolve(mod, block_src_decl, src_node_offset, .none); const msg = msg: { @@ -11884,7 +11858,7 @@ fn validateSwitchItemBool( false_count.* += 1; } if (true_count.* + false_count.* > 2) { - const block_src_decl = sema.mod.declPtr(block.src_decl); + const block_src_decl = mod.declPtr(block.src_decl); const src = switch_prong_src.resolve(mod, block_src_decl, src_node_offset, .none); return sema.fail(block, src, "duplicate switch value", .{}); } @@ -12020,7 +11994,7 @@ fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Ind } if (try sema.resolveDefinedValue(block, cond_src, err_operand)) |val| { if (!operand_ty.isError(mod)) return; - if (val.getError(mod) == null) return; + if (val.getErrorName(mod) == .none) return; try sema.maybeErrorUnwrapComptime(block, body, err_operand); } } @@ -12042,8 +12016,8 @@ fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.I const src = inst_data.src(); if (try sema.resolveDefinedValue(block, src, operand)) |val| { - if (val.getError(sema.mod)) |name| { - return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); + if (val.getErrorName(sema.mod).unwrap()) |name| { + return sema.fail(block, src, "caught unexpected error '{}'", .{name.fmt(&sema.mod.intern_pool)}); } } } @@ -12073,7 +12047,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai if (anon_struct.names.len != 0) { break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names, field_name) != null; } else { - const field_index = std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10) catch break :hf false; + const field_index = field_name.toUnsigned(ip) orelse break :hf false; break :hf field_index < ty.structFieldCount(mod); } }, @@ -12094,7 +12068,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai else => {}, } return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{ - ty.fmt(sema.mod), + ty.fmt(mod), }); }; if (has_field) { @@ -12209,7 +12183,7 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R const inst_data = sema.code.instructions.items(.data)[inst].str_tok; const name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code)); _ = try mod.getErrorValue(name); - const error_set_type = try mod.singleErrorSetTypeNts(name); + const error_set_type = try mod.singleErrorSetType(name); return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{ .ty = error_set_type.toIntern(), .name = name, @@ -12260,36 +12234,36 @@ fn zirShl( if (rhs_ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; while (i < rhs_ty.vectorLen(mod)) : (i += 1) { - const rhs_elem = try rhs_val.elemValue(sema.mod, i); + const rhs_elem = try rhs_val.elemValue(mod, i); if (rhs_elem.compareHetero(.gte, bit_value, mod)) { return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ - rhs_elem.fmtValue(scalar_ty, sema.mod), + rhs_elem.fmtValue(scalar_ty, mod), i, - scalar_ty.fmt(sema.mod), + scalar_ty.fmt(mod), }); } } } else if (rhs_val.compareHetero(.gte, bit_value, mod)) { return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ - rhs_val.fmtValue(scalar_ty, sema.mod), - scalar_ty.fmt(sema.mod), + rhs_val.fmtValue(scalar_ty, mod), + scalar_ty.fmt(mod), }); } } if (rhs_ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; while (i < rhs_ty.vectorLen(mod)) : (i += 1) { - const rhs_elem = try rhs_val.elemValue(sema.mod, i); + const rhs_elem = try rhs_val.elemValue(mod, i); if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) { return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ - rhs_elem.fmtValue(scalar_ty, sema.mod), + rhs_elem.fmtValue(scalar_ty, mod), i, }); } } } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ - rhs_val.fmtValue(scalar_ty, sema.mod), + rhs_val.fmtValue(scalar_ty, mod), }); } } @@ -12305,25 +12279,25 @@ fn zirShl( const val = switch (air_tag) { .shl_exact => val: { - const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, sema.mod); + const shifted = try lhs_val.shlWithOverflow(rhs_val, lhs_ty, sema.arena, mod); if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) { break :val shifted.wrapped_result; } - if (shifted.overflow_bit.compareAllWithZero(.eq, sema.mod)) { + if (shifted.overflow_bit.compareAllWithZero(.eq, mod)) { break :val shifted.wrapped_result; } return sema.fail(block, src, "operation caused overflow", .{}); }, .shl_sat => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) - try lhs_val.shl(rhs_val, lhs_ty, sema.arena, sema.mod) + try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod) else - try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, sema.mod), + try lhs_val.shlSat(rhs_val, lhs_ty, sema.arena, mod), .shl => if (scalar_ty.zigTypeTag(mod) == .ComptimeInt) - try lhs_val.shl(rhs_val, lhs_ty, sema.arena, sema.mod) + try lhs_val.shl(rhs_val, lhs_ty, sema.arena, mod) else - try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, sema.mod), + try lhs_val.shlTrunc(rhs_val, lhs_ty, sema.arena, mod), else => unreachable, }; @@ -12441,36 +12415,36 @@ fn zirShr( if (rhs_ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; while (i < rhs_ty.vectorLen(mod)) : (i += 1) { - const rhs_elem = try rhs_val.elemValue(sema.mod, i); + const rhs_elem = try rhs_val.elemValue(mod, i); if (rhs_elem.compareHetero(.gte, bit_value, mod)) { return sema.fail(block, rhs_src, "shift amount '{}' at index '{d}' is too large for operand type '{}'", .{ - rhs_elem.fmtValue(scalar_ty, sema.mod), + rhs_elem.fmtValue(scalar_ty, mod), i, - scalar_ty.fmt(sema.mod), + scalar_ty.fmt(mod), }); } } } else if (rhs_val.compareHetero(.gte, bit_value, mod)) { return sema.fail(block, rhs_src, "shift amount '{}' is too large for operand type '{}'", .{ - rhs_val.fmtValue(scalar_ty, sema.mod), - scalar_ty.fmt(sema.mod), + rhs_val.fmtValue(scalar_ty, mod), + scalar_ty.fmt(mod), }); } } if (rhs_ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; while (i < rhs_ty.vectorLen(mod)) : (i += 1) { - const rhs_elem = try rhs_val.elemValue(sema.mod, i); + const rhs_elem = try rhs_val.elemValue(mod, i); if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) { return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ - rhs_elem.fmtValue(scalar_ty, sema.mod), + rhs_elem.fmtValue(scalar_ty, mod), i, }); } } } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ - rhs_val.fmtValue(scalar_ty, sema.mod), + rhs_val.fmtValue(scalar_ty, mod), }); } if (maybe_lhs_val) |lhs_val| { @@ -12479,12 +12453,12 @@ fn zirShr( } if (air_tag == .shr_exact) { // Detect if any ones would be shifted out. - const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, sema.mod); + const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, mod); if (!(try truncated.compareAllWithZeroAdvanced(.eq, sema))) { return sema.fail(block, src, "exact shift shifted out 1 bits", .{}); } } - const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, sema.mod); + const val = try lhs_val.shr(rhs_val, lhs_ty, sema.arena, mod); return sema.addConstant(lhs_ty, val); } else { break :rs lhs_src; @@ -12580,9 +12554,9 @@ fn zirBitwise( if (try sema.resolveMaybeUndefValIntable(casted_lhs)) |lhs_val| { if (try sema.resolveMaybeUndefValIntable(casted_rhs)) |rhs_val| { const result_val = switch (air_tag) { - .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, sema.mod), - .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, sema.mod), - .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, sema.mod), + .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, mod), + .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, mod), + .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, mod), else => unreachable, }; return sema.addConstant(resolved_type, result_val); @@ -12613,7 +12587,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. if (scalar_type.zigTypeTag(mod) != .Int) { return sema.fail(block, src, "unable to perform binary not operation on type '{}'", .{ - operand_type.fmt(sema.mod), + operand_type.fmt(mod), }); } @@ -12624,15 +12598,15 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod)); const elems = try sema.arena.alloc(InternPool.Index, vec_len); for (elems, 0..) |*elem, i| { - const elem_val = try val.elemValue(sema.mod, i); - elem.* = try (try elem_val.bitwiseNot(scalar_type, sema.arena, sema.mod)).intern(scalar_type, mod); + const elem_val = try val.elemValue(mod, i); + elem.* = try (try elem_val.bitwiseNot(scalar_type, sema.arena, mod)).intern(scalar_type, mod); } return sema.addConstant(operand_type, (try mod.intern(.{ .aggregate = .{ .ty = operand_type.toIntern(), .storage = .{ .elems = elems }, } })).toValue()); } else { - const result_val = try val.bitwiseNot(operand_type, sema.arena, sema.mod); + const result_val = try val.bitwiseNot(operand_type, sema.arena, mod); return sema.addConstant(operand_type, result_val); } } @@ -12949,7 +12923,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins return Type.ArrayInfo{ .elem_type = ptr_info.pointee_type, .sentinel = ptr_info.sentinel, - .len = val.sliceLen(sema.mod), + .len = val.sliceLen(mod), }; }, .One => { @@ -13195,14 +13169,14 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. .Int, .ComptimeInt, .Float, .ComptimeFloat => false, else => true, }) { - return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(sema.mod)}); + return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(mod)}); } if (rhs_scalar_ty.isAnyFloat()) { // We handle float negation here to ensure negative zero is represented in the bits. if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| { if (rhs_val.isUndef(mod)) return sema.addConstUndef(rhs_ty); - return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, sema.mod)); + return sema.addConstant(rhs_ty, try rhs_val.floatNeg(rhs_ty, sema.arena, mod)); } try sema.requireRuntimeBlock(block, src, null); return block.addUnOp(if (block.float_mode == .Optimized) .neg_optimized else .neg, rhs); @@ -13225,7 +13199,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! switch (rhs_scalar_ty.zigTypeTag(mod)) { .Int, .ComptimeInt, .Float, .ComptimeFloat => {}, - else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(sema.mod)}), + else => return sema.fail(block, src, "negation of type '{}'", .{rhs_ty.fmt(mod)}), } const lhs = try sema.addConstant(rhs_ty, try sema.splat(rhs_ty, try mod.intValue(rhs_scalar_ty, 0))); @@ -14099,8 +14073,8 @@ fn intRem( const result_data = try sema.arena.alloc(InternPool.Index, ty.vectorLen(mod)); const scalar_ty = ty.scalarType(mod); for (result_data, 0..) |*scalar, i| { - const lhs_elem = try lhs.elemValue(sema.mod, i); - const rhs_elem = try rhs.elemValue(sema.mod, i); + const lhs_elem = try lhs.elemValue(mod, i); + const rhs_elem = try rhs.elemValue(mod, i); scalar.* = try (try sema.intRemScalar(lhs_elem, rhs_elem, scalar_ty)).intern(scalar_ty, mod); } return (try mod.intern(.{ .aggregate = .{ @@ -14499,7 +14473,7 @@ fn zirOverflowArithmetic( break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; } - const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, sema.mod); + const result = try lhs_val.shlWithOverflow(rhs_val, dest_ty, sema.arena, mod); break :result .{ .overflow_bit = result.overflow_bit, .wrapped = result.wrapped_result }; } } @@ -14917,7 +14891,7 @@ fn analyzeArithmetic( } if (is_int) { var overflow_idx: ?usize = null; - const product = try lhs_val.intMul(rhs_val, resolved_type, &overflow_idx, sema.arena, sema.mod); + const product = try lhs_val.intMul(rhs_val, resolved_type, &overflow_idx, sema.arena, mod); if (overflow_idx) |vec_idx| { return sema.failWithIntegerOverflow(block, src, resolved_type, product, vec_idx); } @@ -14925,7 +14899,7 @@ fn analyzeArithmetic( } else { return sema.addConstant( resolved_type, - try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, sema.mod), + try lhs_val.floatMul(rhs_val, resolved_type, sema.arena, mod), ); } } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; @@ -14975,7 +14949,7 @@ fn analyzeArithmetic( } return sema.addConstant( resolved_type, - try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, sema.mod), + try lhs_val.numberMulWrap(rhs_val, resolved_type, sema.arena, mod), ); } else break :rs .{ .src = lhs_src, .air_tag = air_tag }; } else break :rs .{ .src = rhs_src, .air_tag = air_tag }; @@ -15023,9 +14997,9 @@ fn analyzeArithmetic( } const val = if (scalar_tag == .ComptimeInt) - try lhs_val.intMul(rhs_val, resolved_type, undefined, sema.arena, sema.mod) + try lhs_val.intMul(rhs_val, resolved_type, undefined, sema.arena, mod) else - try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, sema.mod); + try lhs_val.intMulSat(rhs_val, resolved_type, sema.arena, mod); return sema.addConstant(resolved_type, val); } else break :rs .{ .src = lhs_src, .air_tag = .mul_sat }; @@ -15118,7 +15092,7 @@ fn analyzePtrArithmetic( // non zero). const new_align = @as(u32, 1) << @intCast(u5, @ctz(addend | ptr_info.@"align")); - break :t try Type.ptr(sema.arena, sema.mod, .{ + break :t try Type.ptr(sema.arena, mod, .{ .pointee_type = ptr_info.pointee_type, .sentinel = ptr_info.sentinel, .@"align" = new_align, @@ -15150,7 +15124,7 @@ fn analyzePtrArithmetic( if (air_tag == .ptr_sub) { return sema.fail(block, op_src, "TODO implement Sema comptime pointer subtraction", .{}); } - const new_ptr_val = try ptr_val.elemPtr(new_ptr_ty, offset_int, sema.mod); + const new_ptr_val = try ptr_val.elemPtr(new_ptr_ty, offset_int, mod); return sema.addConstant(new_ptr_ty, new_ptr_val); } else break :rs offset_src; } else break :rs ptr_src; @@ -15382,7 +15356,7 @@ fn zirCmpEq( if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) { const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty; - return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(sema.mod)}); + return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type.fmt(mod)}); } if (lhs_ty_tag == .Union and (rhs_ty_tag == .EnumLiteral or rhs_ty_tag == .Enum)) { @@ -15419,7 +15393,7 @@ fn zirCmpEq( if (lhs_ty_tag == .Type and rhs_ty_tag == .Type) { const lhs_as_type = try sema.analyzeAsType(block, lhs_src, lhs); const rhs_as_type = try sema.analyzeAsType(block, rhs_src, rhs); - if (lhs_as_type.eql(rhs_as_type, sema.mod) == (op == .eq)) { + if (lhs_as_type.eql(rhs_as_type, mod) == (op == .eq)) { return Air.Inst.Ref.bool_true; } else { return Air.Inst.Ref.bool_false; @@ -15444,7 +15418,7 @@ fn analyzeCmpUnionTag( const msg = msg: { const msg = try sema.errMsg(block, un_src, "comparison of union and enum literal is only valid for tagged union types", .{}); errdefer msg.destroy(sema.gpa); - try sema.mod.errNoteNonLazy(union_ty.declSrcLoc(sema.mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(sema.mod)}); + try mod.errNoteNonLazy(union_ty.declSrcLoc(mod), msg, "union '{}' is not a tagged union", .{union_ty.fmt(mod)}); break :msg msg; }; return sema.failWithOwnedErrorMsg(msg); @@ -15456,7 +15430,7 @@ fn analyzeCmpUnionTag( if (try sema.resolveMaybeUndefVal(coerced_tag)) |enum_val| { if (enum_val.isUndef(mod)) return sema.addConstUndef(Type.bool); - const field_ty = union_ty.unionFieldType(enum_val, sema.mod); + const field_ty = union_ty.unionFieldType(enum_val, mod); if (field_ty.zigTypeTag(mod) == .NoReturn) { return Air.Inst.Ref.bool_false; } @@ -15524,7 +15498,7 @@ fn analyzeCmp( const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src } }); if (!resolved_type.isSelfComparable(mod, is_equality_cmp)) { return sema.fail(block, src, "operator {s} not allowed for type '{}'", .{ - compareOperatorName(op), resolved_type.fmt(sema.mod), + compareOperatorName(op), resolved_type.fmt(mod), }); } const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); @@ -15634,7 +15608,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. .Undefined, .Null, .Opaque, - => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(sema.mod)}), + => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(mod)}), .Type, .EnumLiteral, @@ -15677,7 +15651,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A .Undefined, .Null, .Opaque, - => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(sema.mod)}), + => return sema.fail(block, operand_src, "no size available for type '{}'", .{operand_ty.fmt(mod)}), .Type, .EnumLiteral, @@ -17163,7 +17137,7 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi block, src, "bit shifting operation expected integer type, found '{}'", - .{operand.fmt(sema.mod)}, + .{operand.fmt(mod)}, ); } @@ -17395,7 +17369,7 @@ fn checkErrorType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { switch (ty.zigTypeTag(mod)) { .ErrorSet, .ErrorUnion, .Undefined => return, else => return sema.fail(block, src, "expected error union type, found '{}'", .{ - ty.fmt(sema.mod), + ty.fmt(mod), }), } } @@ -17521,7 +17495,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! const mod = sema.mod; if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ - err_union_ty.fmt(sema.mod), + err_union_ty.fmt(mod), }); } const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); @@ -17568,7 +17542,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr const mod = sema.mod; if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ - err_union_ty.fmt(sema.mod), + err_union_ty.fmt(mod), }); } const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); @@ -17590,7 +17564,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr const operand_ty = sema.typeOf(operand); const ptr_info = operand_ty.ptrInfo(mod); - const res_ty = try Type.ptr(sema.arena, sema.mod, .{ + const res_ty = try Type.ptr(sema.arena, mod, .{ .pointee_type = err_union_ty.errorUnionPayload(mod), .@"addrspace" = ptr_info.@"addrspace", .mutable = ptr_info.mutable, @@ -17693,7 +17667,7 @@ fn zirRetErrValue( _ = try mod.getErrorValue(err_name); const src = inst_data.src(); // Return the error code from the function. - const error_set_type = try mod.singleErrorSetTypeNts(err_name); + const error_set_type = try mod.singleErrorSetType(err_name); const result_inst = try sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{ .ty = error_set_type.toIntern(), .name = err_name, @@ -18003,7 +17977,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air if (elem_ty.zigTypeTag(mod) == .NoReturn) return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{}); - const target = sema.mod.getTarget(); + const target = mod.getTarget(); var extra_i = extra.end; @@ -18073,10 +18047,10 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air } else if (inst_data.size == .C) { if (!try sema.validateExternType(elem_ty, .other)) { const msg = msg: { - const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)}); + const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(mod)}); errdefer msg.destroy(sema.gpa); - const src_decl = sema.mod.declPtr(block.src_decl); + const src_decl = mod.declPtr(block.src_decl); try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src.toSrcLoc(src_decl, mod), elem_ty, .other); try sema.addDeclaredHereNote(msg, elem_ty); @@ -18273,7 +18247,7 @@ fn zirStructInit( return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known"); }; - if (!init_val.eql(default_value, resolved_ty.structFieldType(field_index, mod), sema.mod)) { + if (!init_val.eql(default_value, resolved_ty.structFieldType(field_index, mod), mod)) { return sema.failWithInvalidComptimeFieldStore(block, field_src, resolved_ty, field_index); } }; @@ -18307,8 +18281,8 @@ fn zirStructInit( } if (is_ref) { - const target = sema.mod.getTarget(); - const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{ + const target = mod.getTarget(); + const alloc_ty = try Type.ptr(sema.arena, mod, .{ .pointee_type = resolved_ty, .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); @@ -18359,8 +18333,8 @@ fn finishStructInit( } } else { const field_name = anon_struct.names[i]; - const template = "missing struct field: {s}"; - const args = .{ip.stringToSlice(field_name)}; + const template = "missing struct field: {}"; + const args = .{field_name.fmt(ip)}; if (root_msg) |msg| { try sema.errNote(block, init_src, msg, template, args); } else { @@ -18379,8 +18353,8 @@ fn finishStructInit( if (field.default_val == .none) { const field_name = struct_obj.fields.keys()[i]; - const template = "missing struct field: {s}"; - const args = .{ip.stringToSlice(field_name)}; + const template = "missing struct field: {}"; + const args = .{field_name.fmt(ip)}; if (root_msg) |msg| { try sema.errNote(block, init_src, msg, template, args); } else { @@ -18396,12 +18370,12 @@ fn finishStructInit( if (root_msg) |msg| { if (mod.typeToStruct(struct_ty)) |struct_obj| { - const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod)); + const fqn = try struct_obj.getFullyQualifiedName(mod); try mod.errNoteNonLazy( struct_obj.srcLoc(mod), msg, - "struct '{s}' declared here", - .{fqn}, + "struct '{}' declared here", + .{fqn.fmt(ip)}, ); } root_msg = null; @@ -18431,7 +18405,7 @@ fn finishStructInit( if (is_ref) { try sema.resolveStructLayout(struct_ty); const target = sema.mod.getTarget(); - const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{ + const alloc_ty = try Type.ptr(sema.arena, mod, .{ .pointee_type = struct_ty, .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); @@ -18489,7 +18463,7 @@ fn zirStructInitAnon( const gop = fields.getOrPutAssumeCapacity(name_ip); if (gop.found_existing) { const msg = msg: { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); const field_src = mod.initSrc(src.node_offset.x, decl, i); const msg = try sema.errMsg(block, field_src, "duplicate field", .{}); errdefer msg.destroy(gpa); @@ -18506,7 +18480,7 @@ fn zirStructInitAnon( field_ty.* = sema.typeOf(init).toIntern(); if (field_ty.toType().zigTypeTag(mod) == .Opaque) { const msg = msg: { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); const field_src = mod.initSrc(src.node_offset.x, decl, i); const msg = try sema.errMsg(block, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); errdefer msg.destroy(sema.gpa); @@ -18542,7 +18516,7 @@ fn zirStructInitAnon( sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); const field_src = mod.initSrc(src.node_offset.x, decl, runtime_index); try sema.requireRuntimeBlock(block, src, field_src); unreachable; @@ -18551,8 +18525,8 @@ fn zirStructInitAnon( }; if (is_ref) { - const target = sema.mod.getTarget(); - const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{ + const target = mod.getTarget(); + const alloc_ty = try Type.ptr(sema.arena, mod, .{ .pointee_type = tuple_ty.toType(), .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); @@ -18563,7 +18537,7 @@ fn zirStructInitAnon( const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index); extra_index = item.end; - const field_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ + const field_ptr_ty = try Type.ptr(sema.arena, mod, .{ .mutable = true, .@"addrspace" = target_util.defaultAddressSpace(target, .local), .pointee_type = field_ty.toType(), @@ -18617,7 +18591,7 @@ fn zirArrayInit( array_ty.elemType2(mod); resolved_args[i] = sema.coerce(block, elem_ty, resolved_arg, .unneeded) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); const elem_src = mod.initSrc(src.node_offset.x, decl, i); _ = try sema.coerce(block, elem_ty, resolved_arg, elem_src); unreachable; @@ -18653,7 +18627,7 @@ fn zirArrayInit( sema.requireRuntimeBlock(block, .unneeded, null) catch |err| switch (err) { error.NeededSourceLocation => { - const decl = sema.mod.declPtr(block.src_decl); + const decl = mod.declPtr(block.src_decl); const elem_src = mod.initSrc(src.node_offset.x, decl, runtime_index); try sema.requireRuntimeBlock(block, src, elem_src); unreachable; @@ -18663,8 +18637,8 @@ fn zirArrayInit( try sema.queueFullTypeResolution(array_ty); if (is_ref) { - const target = sema.mod.getTarget(); - const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{ + const target = mod.getTarget(); + const alloc_ty = try Type.ptr(sema.arena, mod, .{ .pointee_type = array_ty, .@"addrspace" = target_util.defaultAddressSpace(target, .local), }); @@ -18672,7 +18646,7 @@ fn zirArrayInit( if (array_ty.isTuple(mod)) { for (resolved_args, 0..) |arg, i| { - const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ + const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{ .mutable = true, .@"addrspace" = target_util.defaultAddressSpace(target, .local), .pointee_type = array_ty.structFieldType(i, mod), @@ -18686,7 +18660,7 @@ fn zirArrayInit( return sema.makePtrConst(block, alloc); } - const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ + const elem_ptr_ty = try Type.ptr(sema.arena, mod, .{ .mutable = true, .@"addrspace" = target_util.defaultAddressSpace(target, .local), .pointee_type = array_ty.elemType2(mod), @@ -18959,8 +18933,7 @@ fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { const err_name = sema.mod.intern_pool.indexToKey(val.toIntern()).err.name; - const bytes = sema.mod.intern_pool.stringToSlice(err_name); - return sema.addStrLit(block, bytes); + return sema.addStrLit(block, sema.mod.intern_pool.stringToSlice(err_name)); } // Similar to zirTagName, we have special AIR instruction for the error name in case an optimimzation pass @@ -19051,8 +19024,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air .EnumLiteral => { const val = try sema.resolveConstValue(block, .unneeded, operand, ""); const tag_name = ip.indexToKey(val.toIntern()).enum_literal; - const bytes = ip.stringToSlice(tag_name); - return sema.addStrLit(block, bytes); + return sema.addStrLit(block, ip.stringToSlice(tag_name)); }, .Enum => operand_ty, .Union => operand_ty.unionTagType(mod) orelse { @@ -19083,8 +19055,8 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const field_index = enum_ty.enumTagFieldIndex(val, mod) orelse { const enum_decl = mod.declPtr(enum_decl_index); const msg = msg: { - const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{s}'", .{ - val.fmtValue(enum_ty, sema.mod), ip.stringToSlice(enum_decl.name), + const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{}'", .{ + val.fmtValue(enum_ty, sema.mod), enum_decl.name.fmt(ip), }); errdefer msg.destroy(sema.gpa); try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{}); @@ -19374,8 +19346,8 @@ fn zirReify( _ = try mod.getErrorValue(name); const gop = names.getOrPutAssumeCapacity(name); if (gop.found_existing) { - return sema.fail(block, src, "duplicate error '{s}'", .{ - ip.stringToSlice(name), + return sema.fail(block, src, "duplicate error '{}'", .{ + name.fmt(ip), }); } } @@ -19487,8 +19459,8 @@ fn zirReify( if (!try sema.intFitsInType(value_val, int_tag_ty, null)) { // TODO: better source location - return sema.fail(block, src, "field '{s}' with enumeration value '{}' is too large for backing int type '{}'", .{ - ip.stringToSlice(field_name), + return sema.fail(block, src, "field '{}' with enumeration value '{}' is too large for backing int type '{}'", .{ + field_name.fmt(ip), value_val.fmtValue(Type.comptime_int, mod), int_tag_ty.fmt(mod), }); @@ -19496,8 +19468,8 @@ fn zirReify( if (try incomplete_enum.addFieldName(ip, gpa, field_name)) |other_index| { const msg = msg: { - const msg = try sema.errMsg(block, src, "duplicate enum field '{s}'", .{ - ip.stringToSlice(field_name), + const msg = try sema.errMsg(block, src, "duplicate enum field '{}'", .{ + field_name.fmt(ip), }); errdefer msg.destroy(gpa); _ = other_index; // TODO: this note is incorrect @@ -19690,7 +19662,10 @@ fn zirReify( const tag_info = ip.indexToKey(union_obj.tag_ty.toIntern()).enum_type; const enum_index = tag_info.nameIndex(ip, field_name) orelse { const msg = msg: { - const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ ip.stringToSlice(field_name), union_obj.tag_ty.fmt(mod) }); + const msg = try sema.errMsg(block, src, "no field named '{}' in enum '{}'", .{ + field_name.fmt(ip), + union_obj.tag_ty.fmt(mod), + }); errdefer msg.destroy(gpa); try sema.addDeclaredHereNote(msg, union_obj.tag_ty); break :msg msg; @@ -19706,7 +19681,7 @@ fn zirReify( const gop = union_obj.fields.getOrPutAssumeCapacity(field_name); if (gop.found_existing) { // TODO: better source location - return sema.fail(block, src, "duplicate union field {s}", .{ip.stringToSlice(field_name)}); + return sema.fail(block, src, "duplicate union field {}", .{field_name.fmt(ip)}); } const field_ty = type_val.toType(); @@ -19762,8 +19737,8 @@ fn zirReify( const enum_ty = union_obj.tag_ty; for (tag_info.names, 0..) |field_name, field_index| { if (explicit_tags_seen[field_index]) continue; - try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{ - ip.stringToSlice(field_name), + try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{}' missing, declared here", .{ + field_name.fmt(ip), }); } try sema.addDeclaredHereNote(msg, union_obj.tag_ty); @@ -19981,14 +19956,12 @@ fn reifyStruct( const field_name = try name_val.toIpString(Type.slice_const_u8, mod); if (is_tuple) { - const field_index = std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10) catch { - return sema.fail( - block, - src, - "tuple cannot have non-numeric field '{s}'", - .{ip.stringToSlice(field_name)}, - ); - }; + const field_index = field_name.toUnsigned(ip) orelse return sema.fail( + block, + src, + "tuple cannot have non-numeric field '{}'", + .{field_name.fmt(ip)}, + ); if (field_index >= fields_len) { return sema.fail( @@ -20002,7 +19975,7 @@ fn reifyStruct( const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name); if (gop.found_existing) { // TODO: better source location - return sema.fail(block, src, "duplicate struct field {s}", .{ip.stringToSlice(field_name)}); + return sema.fail(block, src, "duplicate struct field {}", .{field_name.fmt(ip)}); } const field_ty = type_val.toType(); @@ -20443,14 +20416,14 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat if (maybe_operand_val) |val| { if (!dest_ty.isAnyError(mod)) { - const error_name = mod.intern_pool.stringToSlice(mod.intern_pool.indexToKey(val.toIntern()).err.name); - if (!dest_ty.errorSetHasField(error_name, mod)) { + const error_name = mod.intern_pool.indexToKey(val.toIntern()).err.name; + if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) { const msg = msg: { const msg = try sema.errMsg( block, src, - "'error.{s}' not a member of error set '{}'", - .{ error_name, dest_ty.fmt(sema.mod) }, + "'error.{}' not a member of error set '{}'", + .{ error_name.fmt(ip), dest_ty.fmt(sema.mod) }, ); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, dest_ty); @@ -21448,7 +21421,7 @@ fn resolveExportOptions( block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, -) CompileError!std.builtin.ExportOptions { +) CompileError!Module.Export.Options { const mod = sema.mod; const gpa = sema.gpa; const ip = &mod.intern_pool; @@ -21492,10 +21465,10 @@ fn resolveExportOptions( }); } - return std.builtin.ExportOptions{ - .name = name, + return .{ + .name = try ip.getOrPutString(gpa, name), .linkage = linkage, - .section = section, + .section = try ip.getOrPutStringOpt(gpa, section), .visibility = visibility, }; } @@ -22391,9 +22364,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr const msg = try sema.errMsg( block, src, - "field '{s}' has index '{d}' but pointer value is index '{d}' of struct '{}'", + "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{ - ip.stringToSlice(field_name), + field_name.fmt(ip), field_index, field.index, parent_ty.fmt(sema.mod), @@ -23440,7 +23413,12 @@ fn resolveExternOptions( block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, -) CompileError!std.builtin.ExternOptions { +) CompileError!struct { + name: InternPool.NullTerminatedString, + library_name: InternPool.OptionalNullTerminatedString = .none, + linkage: std.builtin.GlobalLinkage = .Strong, + is_thread_local: bool = false, +} { const mod = sema.mod; const gpa = sema.gpa; const ip = &mod.intern_pool; @@ -23483,9 +23461,9 @@ fn resolveExternOptions( return sema.fail(block, linkage_src, "extern symbol must use strong or weak linkage", .{}); } - return std.builtin.ExternOptions{ - .name = name, - .library_name = library_name, + return .{ + .name = try ip.getOrPutString(gpa, name), + .library_name = try ip.getOrPutStringOpt(gpa, library_name), .linkage = linkage, .is_thread_local = is_thread_local_val.toBool(), }; @@ -23533,7 +23511,7 @@ fn zirBuiltinExtern( const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node, null); errdefer mod.destroyDecl(new_decl_index); const new_decl = mod.declPtr(new_decl_index); - new_decl.name = try mod.intern_pool.getOrPutString(sema.gpa, options.name); + new_decl.name = options.name; { const new_var = try mod.intern(.{ .variable = .{ @@ -24459,8 +24437,8 @@ fn fieldVal( return sema.fail( block, field_name_src, - "no member named '{s}' in '{}'", - .{ ip.stringToSlice(field_name), object_ty.fmt(mod) }, + "no member named '{}' in '{}'", + .{ field_name.fmt(ip), object_ty.fmt(mod) }, ); } }, @@ -24483,8 +24461,8 @@ fn fieldVal( return sema.fail( block, field_name_src, - "no member named '{s}' in '{}'", - .{ ip.stringToSlice(field_name), object_ty.fmt(mod) }, + "no member named '{}' in '{}'", + .{ field_name.fmt(ip), object_ty.fmt(mod) }, ); } } @@ -24504,8 +24482,8 @@ fn fieldVal( .error_set_type => |error_set_type| blk: { if (error_set_type.nameIndex(ip, field_name) != null) break :blk; const msg = msg: { - const msg = try sema.errMsg(block, src, "no error named '{s}' in '{}'", .{ - ip.stringToSlice(field_name), child_type.fmt(mod), + const msg = try sema.errMsg(block, src, "no error named '{}' in '{}'", .{ + field_name.fmt(ip), child_type.fmt(mod), }); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, child_type); @@ -24526,7 +24504,7 @@ fn fieldVal( const error_set_type = if (!child_type.isAnyError(mod)) child_type else - try mod.singleErrorSetTypeNts(field_name); + try mod.singleErrorSetType(field_name); return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{ .ty = error_set_type.toIntern(), .name = field_name, @@ -24646,8 +24624,8 @@ fn fieldPtr( return sema.fail( block, field_name_src, - "no member named '{s}' in '{}'", - .{ ip.stringToSlice(field_name), object_ty.fmt(mod) }, + "no member named '{}' in '{}'", + .{ field_name.fmt(ip), object_ty.fmt(mod) }, ); } }, @@ -24705,8 +24683,8 @@ fn fieldPtr( return sema.fail( block, field_name_src, - "no member named '{s}' in '{}'", - .{ ip.stringToSlice(field_name), object_ty.fmt(mod) }, + "no member named '{}' in '{}'", + .{ field_name.fmt(ip), object_ty.fmt(mod) }, ); } }, @@ -24728,8 +24706,8 @@ fn fieldPtr( if (error_set_type.nameIndex(ip, field_name) != null) { break :blk; } - return sema.fail(block, src, "no error named '{s}' in '{}'", .{ - ip.stringToSlice(field_name), child_type.fmt(mod), + return sema.fail(block, src, "no error named '{}' in '{}'", .{ + field_name.fmt(ip), child_type.fmt(mod), }); }, .inferred_error_set_type => { @@ -24747,7 +24725,7 @@ fn fieldPtr( const error_set_type = if (!child_type.isAnyError(mod)) child_type else - try mod.singleErrorSetTypeNts(field_name); + try mod.singleErrorSetType(field_name); return sema.analyzeDeclRef(try anon_decl.finish( error_set_type, (try mod.intern(.{ .err = .{ @@ -24880,10 +24858,10 @@ fn fieldCallBind( if (ip.stringEqlSlice(field_name, "len")) { return .{ .direct = try sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount(mod)) }; } - if (std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10)) |field_index| { + if (field_name.toUnsigned(ip)) |field_index| { if (field_index >= struct_ty.structFieldCount(mod)) break :find_field; return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(field_index, mod), field_index, object_ptr); - } else |_| {} + } } else { const max = struct_ty.structFieldCount(mod); for (0..max) |i_usize| { @@ -24982,12 +24960,15 @@ fn fieldCallBind( }; const msg = msg: { - const msg = try sema.errMsg(block, src, "no field or member function named '{s}' in '{}'", .{ ip.stringToSlice(field_name), concrete_ty.fmt(mod) }); + const msg = try sema.errMsg(block, src, "no field or member function named '{}' in '{}'", .{ + field_name.fmt(ip), + concrete_ty.fmt(mod), + }); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, concrete_ty); if (found_decl) |decl_idx| { const decl = mod.declPtr(decl_idx); - try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "'{s}' is not a member function", .{ip.stringToSlice(field_name)}); + try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "'{}' is not a member function", .{field_name.fmt(ip)}); } break :msg msg; }; @@ -25047,8 +25028,8 @@ fn namespaceLookup( const decl = mod.declPtr(decl_index); if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) { const msg = msg: { - const msg = try sema.errMsg(block, src, "'{s}' is not marked 'pub'", .{ - mod.intern_pool.stringToSlice(decl_name), + const msg = try sema.errMsg(block, src, "'{}' is not marked 'pub'", .{ + decl_name.fmt(&mod.intern_pool), }); errdefer msg.destroy(gpa); try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "declared here", .{}); @@ -25299,21 +25280,20 @@ fn tupleFieldIndex( sema: *Sema, block: *Block, tuple_ty: Type, - field_name_ip: InternPool.NullTerminatedString, + field_name: InternPool.NullTerminatedString, field_name_src: LazySrcLoc, ) CompileError!u32 { const mod = sema.mod; - const field_name = mod.intern_pool.stringToSlice(field_name_ip); - assert(!std.mem.eql(u8, field_name, "len")); - if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| { + assert(!mod.intern_pool.stringEqlSlice(field_name, "len")); + if (field_name.toUnsigned(&mod.intern_pool)) |field_index| { if (field_index < tuple_ty.structFieldCount(mod)) return field_index; - return sema.fail(block, field_name_src, "index '{s}' out of bounds of tuple '{}'", .{ - field_name, tuple_ty.fmt(mod), + return sema.fail(block, field_name_src, "index '{}' out of bounds of tuple '{}'", .{ + field_name.fmt(&mod.intern_pool), tuple_ty.fmt(mod), }); - } else |_| {} + } - return sema.fail(block, field_name_src, "no field named '{s}' in tuple '{}'", .{ - field_name, tuple_ty.fmt(mod), + return sema.fail(block, field_name_src, "no field named '{}' in tuple '{}'", .{ + field_name.fmt(&mod.intern_pool), tuple_ty.fmt(mod), }); } @@ -25389,8 +25369,8 @@ fn unionFieldPtr( const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{}); errdefer msg.destroy(sema.gpa); - try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{ - ip.stringToSlice(field_name), + try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' declared here", .{ + field_name.fmt(ip), }); try sema.addDeclaredHereNote(msg, union_ty); break :msg msg; @@ -25413,9 +25393,9 @@ fn unionFieldPtr( const msg = msg: { const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?; const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod); - const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ - ip.stringToSlice(field_name), - ip.stringToSlice(active_field_name), + const msg = try sema.errMsg(block, src, "access of union field '{}' while field '{}' is active", .{ + field_name.fmt(ip), + active_field_name.fmt(ip), }); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, union_ty); @@ -25486,8 +25466,8 @@ fn unionFieldVal( const msg = msg: { const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?; const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod); - const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ - ip.stringToSlice(field_name), ip.stringToSlice(active_field_name), + const msg = try sema.errMsg(block, src, "access of union field '{}' while field '{}' is active", .{ + field_name.fmt(ip), active_field_name.fmt(ip), }); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, union_ty); @@ -26595,8 +26575,8 @@ fn coerceExtra( const msg = try sema.errMsg( block, inst_src, - "no field named '{s}' in enum '{}'", - .{ mod.intern_pool.stringToSlice(string), dest_ty.fmt(mod) }, + "no field named '{}' in enum '{}'", + .{ string.fmt(&mod.intern_pool), dest_ty.fmt(mod) }, ); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, dest_ty); @@ -27051,9 +27031,8 @@ const InMemoryCoercionResult = union(enum) { break; }, .missing_error => |missing_errors| { - for (missing_errors) |err_index| { - const err = mod.intern_pool.stringToSlice(err_index); - try sema.errNote(block, src, msg, "'error.{s}' not a member of destination error set", .{err}); + for (missing_errors) |err| { + try sema.errNote(block, src, msg, "'error.{}' not a member of destination error set", .{err.fmt(&mod.intern_pool)}); } break; }, @@ -28016,7 +27995,12 @@ fn storePtrVal( .bad_decl_ty, .bad_ptr_ty => { // TODO show the decl declaration site in a note and explain whether the decl // or the pointer is the problematic type - return sema.fail(block, src, "comptime mutation of a reinterpreted pointer requires type '{}' to have a well-defined memory layout", .{mut_kit.ty.fmt(mod)}); + return sema.fail( + block, + src, + "comptime mutation of a reinterpreted pointer requires type '{}' to have a well-defined memory layout", + .{mut_kit.ty.fmt(mod)}, + ); }, } } @@ -28678,7 +28662,12 @@ fn beginComptimePtrLoad( .null_value => return sema.fail(block, src, "attempt to use null value", .{}), else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) { .error_union => |error_union| switch (error_union.val) { - .err_name => |err_name| return sema.fail(block, src, "attempt to unwrap error: {s}", .{mod.intern_pool.stringToSlice(err_name)}), + .err_name => |err_name| return sema.fail( + block, + src, + "attempt to unwrap error: {}", + .{err_name.fmt(&mod.intern_pool)}, + ), .payload => |payload| payload, }, .opt => |opt| switch (opt.val) { @@ -29077,8 +29066,8 @@ fn coerceEnumToUnion( errdefer msg.destroy(sema.gpa); const field_name = union_obj.fields.keys()[field_index]; - try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{ - ip.stringToSlice(field_name), + try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' declared here", .{ + field_name.fmt(ip), }); try sema.addDeclaredHereNote(msg, union_ty); break :msg msg; @@ -29088,14 +29077,14 @@ fn coerceEnumToUnion( const opv = (try sema.typeHasOnePossibleValue(field_ty)) orelse { const msg = msg: { const field_name = union_obj.fields.keys()[field_index]; - const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{s}'", .{ + const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{ inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod), - field_ty.fmt(sema.mod), ip.stringToSlice(field_name), + field_ty.fmt(sema.mod), field_name.fmt(ip), }); errdefer msg.destroy(sema.gpa); - try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{ - ip.stringToSlice(field_name), + try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' declared here", .{ + field_name.fmt(ip), }); try sema.addDeclaredHereNote(msg, union_ty); break :msg msg; @@ -29165,8 +29154,8 @@ fn coerceEnumToUnion( const field_name = field.key_ptr.*; const field_ty = field.value_ptr.ty; if (!(try sema.typeHasRuntimeBits(field_ty))) continue; - try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{ - ip.stringToSlice(field_name), + try sema.addFieldErrNote(union_ty, field_index, msg, "field '{}' has type '{}'", .{ + field_name.fmt(ip), field_ty.fmt(sema.mod), }); } @@ -29522,8 +29511,8 @@ fn coerceTupleToStruct( const field = fields.values()[i]; const field_src = inst_src; // TODO better source location if (field.default_val == .none) { - const template = "missing struct field: {s}"; - const args = .{ip.stringToSlice(field_name)}; + const template = "missing struct field: {}"; + const args = .{field_name.fmt(ip)}; if (root_msg) |msg| { try sema.errNote(block, field_src, msg, template, args); } else { @@ -29666,8 +29655,8 @@ fn coerceTupleToTuple( } continue; } - const template = "missing struct field: {s}"; - const args = .{ip.stringToSlice(tuple_ty.structFieldName(i, mod))}; + const template = "missing struct field: {}"; + const args = .{tuple_ty.structFieldName(i, mod).fmt(ip)}; if (root_msg) |msg| { try sema.errNote(block, field_src, msg, template, args); } else { @@ -30097,7 +30086,7 @@ fn analyzeIsNonErrComptimeOnly( if (err_union.isUndef(mod)) { return sema.addConstUndef(Type.bool); } - if (err_union.getError(mod) == null) { + if (err_union.getErrorName(mod) == .none) { return Air.Inst.Ref.bool_true; } else { return Air.Inst.Ref.bool_false; @@ -32824,15 +32813,16 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void extra_index += 1; // This string needs to outlive the ZIR code. - const field_name = try ip.getOrPutString(gpa, if (field_name_zir) |s| s else try std.fmt.allocPrint(sema.arena, "{d}", .{ - field_i, - })); + const field_name = try ip.getOrPutString(gpa, if (field_name_zir) |s| + s + else + try std.fmt.allocPrint(sema.arena, "{d}", .{field_i})); const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name); if (gop.found_existing) { const msg = msg: { const field_src = mod.fieldSrcLoc(struct_obj.owner_decl, .{ .index = field_i }).lazy; - const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{ip.stringToSlice(field_name)}); + const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{}'", .{field_name.fmt(ip)}); errdefer msg.destroy(gpa); const prev_field_index = struct_obj.fields.getIndex(field_name).?; @@ -33297,8 +33287,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { if (gop.found_existing) { const msg = msg: { const field_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ .index = field_i }).lazy; - const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{ - ip.stringToSlice(field_name), + const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{}'", .{ + field_name.fmt(ip), }); errdefer msg.destroy(gpa); @@ -33319,8 +33309,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { .index = field_i, .range = .type, }).lazy; - const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{s}' in enum '{}'", .{ - ip.stringToSlice(field_name), union_obj.tag_ty.fmt(mod), + const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{}' in enum '{}'", .{ + field_name.fmt(ip), union_obj.tag_ty.fmt(mod), }); errdefer msg.destroy(sema.gpa); try sema.addDeclaredHereNote(msg, union_obj.tag_ty); @@ -33412,8 +33402,8 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { const enum_ty = union_obj.tag_ty; for (tag_info.names, 0..) |field_name, field_index| { if (explicit_tags_seen[field_index]) continue; - try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{ - ip.stringToSlice(field_name), + try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{}' missing, declared here", .{ + field_name.fmt(ip), }); } try sema.addDeclaredHereNote(msg, union_obj.tag_ty); @@ -33442,22 +33432,12 @@ fn generateUnionTagTypeNumbered( ) !Type { const mod = sema.mod; const gpa = sema.gpa; - const ip = &mod.intern_pool; const src_decl = mod.declPtr(block.src_decl); const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope); errdefer mod.destroyDecl(new_decl_index); - const name = name: { - const prefix = "@typeInfo("; - const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod)); - const suffix = ").Union.tag_type.?"; - const start = ip.string_bytes.items.len; - try ip.string_bytes.ensureUnusedCapacity(gpa, prefix.len + suffix.len + fqn.len); - ip.string_bytes.appendSliceAssumeCapacity(prefix); - ip.string_bytes.appendSliceAssumeCapacity(fqn); - ip.string_bytes.appendSliceAssumeCapacity(suffix); - break :name try ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start); - }; + const fqn = try union_obj.getFullyQualifiedName(mod); + const name = try mod.intern_pool.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(&mod.intern_pool)}); try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{ .ty = Type.noreturn, .val = Value.@"unreachable", @@ -33496,7 +33476,6 @@ fn generateUnionTagTypeSimple( ) !Type { const mod = sema.mod; const gpa = sema.gpa; - const ip = &mod.intern_pool; const new_decl_index = new_decl_index: { const union_obj = maybe_union_obj orelse { @@ -33508,17 +33487,8 @@ fn generateUnionTagTypeSimple( const src_decl = mod.declPtr(block.src_decl); const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope); errdefer mod.destroyDecl(new_decl_index); - const name = name: { - const prefix = "@typeInfo("; - const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod)); - const suffix = ").Union.tag_type.?"; - const start = ip.string_bytes.items.len; - try ip.string_bytes.ensureUnusedCapacity(gpa, prefix.len + suffix.len + fqn.len); - ip.string_bytes.appendSliceAssumeCapacity(prefix); - ip.string_bytes.appendSliceAssumeCapacity(fqn); - ip.string_bytes.appendSliceAssumeCapacity(suffix); - break :name try ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start); - }; + const fqn = try union_obj.getFullyQualifiedName(mod); + const name = try mod.intern_pool.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(&mod.intern_pool)}); try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{ .ty = Type.noreturn, .val = Value.@"unreachable", @@ -34456,8 +34426,8 @@ fn anonStructFieldIndex( }, else => unreachable, } - return sema.fail(block, field_src, "no field named '{s}' in anonymous struct '{}'", .{ - mod.intern_pool.stringToSlice(field_name), struct_ty.fmt(sema.mod), + return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{ + field_name.fmt(&mod.intern_pool), struct_ty.fmt(sema.mod), }); } diff --git a/src/TypedValue.zig b/src/TypedValue.zig index 7faff3af01..ec76b52d20 100644 --- a/src/TypedValue.zig +++ b/src/TypedValue.zig @@ -76,6 +76,7 @@ pub fn print( ) (@TypeOf(writer).Error || Allocator.Error)!void { var val = tv.val; var ty = tv.ty; + const ip = &mod.intern_pool; while (true) switch (val.ip_index) { .none => switch (val.tag()) { .aggregate => return printAggregate(ty, val, writer, level, mod), @@ -87,7 +88,7 @@ pub fn print( try writer.writeAll(".{ "); try print(.{ - .ty = mod.unionPtr(mod.intern_pool.indexToKey(ty.toIntern()).union_type.index).tag_ty, + .ty = mod.unionPtr(ip.indexToKey(ty.toIntern()).union_type.index).tag_ty, .val = union_val.tag, }, writer, level - 1, mod); try writer.writeAll(" = "); @@ -174,7 +175,7 @@ pub fn print( ty = ty.optionalChild(mod); }, }, - else => switch (mod.intern_pool.indexToKey(val.toIntern())) { + else => switch (ip.indexToKey(val.toIntern())) { .int_type, .ptr_type, .array_type, @@ -200,11 +201,11 @@ pub fn print( else => return writer.writeAll(@tagName(simple_value)), }, .variable => return writer.writeAll("(variable)"), - .extern_func => |extern_func| return writer.print("(extern function '{s}')", .{ - mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name), + .extern_func => |extern_func| return writer.print("(extern function '{}')", .{ + mod.declPtr(extern_func.decl).name.fmt(ip), }), - .func => |func| return writer.print("(function '{s}')", .{ - mod.intern_pool.stringToSlice(mod.declPtr(mod.funcPtr(func.index).owner_decl).name), + .func => |func| return writer.print("(function '{}')", .{ + mod.declPtr(mod.funcPtr(func.index).owner_decl).name.fmt(ip), }), .int => |int| switch (int.storage) { inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}), @@ -215,29 +216,28 @@ pub fn print( lazy_ty.toType().abiSize(mod), }), }, - .err => |err| return writer.print("error.{s}", .{ - mod.intern_pool.stringToSlice(err.name), + .err => |err| return writer.print("error.{}", .{ + err.name.fmt(ip), }), .error_union => |error_union| switch (error_union.val) { - .err_name => |err_name| return writer.print("error.{s}", .{ - mod.intern_pool.stringToSlice(err_name), + .err_name => |err_name| return writer.print("error.{}", .{ + err_name.fmt(ip), }), .payload => |payload| { val = payload.toValue(); ty = ty.errorUnionPayload(mod); }, }, - .enum_literal => |enum_literal| return writer.print(".{s}", .{ - mod.intern_pool.stringToSlice(enum_literal), + .enum_literal => |enum_literal| return writer.print(".{}", .{ + enum_literal.fmt(ip), }), .enum_tag => |enum_tag| { if (level == 0) { return writer.writeAll("(enum)"); } - const enum_type = mod.intern_pool.indexToKey(ty.toIntern()).enum_type; - if (enum_type.tagValueIndex(&mod.intern_pool, val.toIntern())) |tag_index| { - const tag_name = mod.intern_pool.stringToSlice(enum_type.names[tag_index]); - try writer.print(".{}", .{std.zig.fmtId(tag_name)}); + const enum_type = ip.indexToKey(ty.toIntern()).enum_type; + if (enum_type.tagValueIndex(ip, val.toIntern())) |tag_index| { + try writer.print(".{i}", .{enum_type.names[tag_index].fmt(ip)}); return; } try writer.writeAll("@intToEnum("); @@ -247,7 +247,7 @@ pub fn print( }, writer, level - 1, mod); try writer.writeAll(", "); try print(.{ - .ty = mod.intern_pool.typeOf(enum_tag.int).toType(), + .ty = ip.typeOf(enum_tag.int).toType(), .val = enum_tag.int.toValue(), }, writer, level - 1, mod); try writer.writeAll(")"); @@ -259,13 +259,13 @@ pub fn print( }, .ptr => |ptr| { if (ptr.addr == .int) { - const i = mod.intern_pool.indexToKey(ptr.addr.int).int; + const i = ip.indexToKey(ptr.addr.int).int; switch (i.storage) { inline else => |addr| return writer.print("{x:0>8}", .{addr}), } } - const ptr_ty = mod.intern_pool.indexToKey(ty.toIntern()).ptr_type; + const ptr_ty = ip.indexToKey(ty.toIntern()).ptr_type; if (ptr_ty.flags.size == .Slice) { if (level == 0) { return writer.writeAll(".{ ... }"); @@ -301,7 +301,7 @@ pub fn print( switch (ptr.addr) { .decl => |decl_index| { const decl = mod.declPtr(decl_index); - if (level == 0) return writer.print("(decl '{s}')", .{mod.intern_pool.stringToSlice(decl.name)}); + if (level == 0) return writer.print("(decl '{}')", .{decl.name.fmt(ip)}); return print(.{ .ty = decl.ty, .val = decl.val, @@ -309,7 +309,7 @@ pub fn print( }, .mut_decl => |mut_decl| { const decl = mod.declPtr(mut_decl.decl); - if (level == 0) return writer.print("(mut decl '{s}')", .{mod.intern_pool.stringToSlice(decl.name)}); + if (level == 0) return writer.print("(mut decl '{}')", .{decl.name.fmt(ip)}); return print(.{ .ty = decl.ty, .val = decl.val, @@ -317,7 +317,7 @@ pub fn print( }, .comptime_field => |field_val_ip| { return print(.{ - .ty = mod.intern_pool.typeOf(field_val_ip).toType(), + .ty = ip.typeOf(field_val_ip).toType(), .val = field_val_ip.toValue(), }, writer, level - 1, mod); }, @@ -325,27 +325,27 @@ pub fn print( .eu_payload => |eu_ip| { try writer.writeAll("(payload of "); try print(.{ - .ty = mod.intern_pool.typeOf(eu_ip).toType(), + .ty = ip.typeOf(eu_ip).toType(), .val = eu_ip.toValue(), }, writer, level - 1, mod); try writer.writeAll(")"); }, .opt_payload => |opt_ip| { try print(.{ - .ty = mod.intern_pool.typeOf(opt_ip).toType(), + .ty = ip.typeOf(opt_ip).toType(), .val = opt_ip.toValue(), }, writer, level - 1, mod); try writer.writeAll(".?"); }, .elem => |elem| { try print(.{ - .ty = mod.intern_pool.typeOf(elem.base).toType(), + .ty = ip.typeOf(elem.base).toType(), .val = elem.base.toValue(), }, writer, level - 1, mod); try writer.print("[{}]", .{elem.index}); }, .field => |field| { - const container_ty = mod.intern_pool.typeOf(field.base).toType(); + const container_ty = ip.typeOf(field.base).toType(); try print(.{ .ty = container_ty, .val = field.base.toValue(), @@ -356,14 +356,12 @@ pub fn print( if (container_ty.isTuple(mod)) { try writer.print("[{d}]", .{field.index}); } - const field_name_ip = container_ty.structFieldName(@intCast(usize, field.index), mod); - const field_name = mod.intern_pool.stringToSlice(field_name_ip); - try writer.print(".{}", .{std.zig.fmtId(field_name)}); + const field_name = container_ty.structFieldName(@intCast(usize, field.index), mod); + try writer.print(".{i}", .{field_name.fmt(ip)}); }, .Union => { - const field_name_ip = container_ty.unionFields(mod).keys()[@intCast(usize, field.index)]; - const field_name = mod.intern_pool.stringToSlice(field_name_ip); - try writer.print(".{}", .{std.zig.fmtId(field_name)}); + const field_name = container_ty.unionFields(mod).keys()[@intCast(usize, field.index)]; + try writer.print(".{i}", .{field_name.fmt(ip)}); }, .Pointer => { std.debug.assert(container_ty.isSlice(mod)); @@ -440,9 +438,7 @@ fn printAggregate( else => unreachable, }; - if (field_name.unwrap()) |name_ip| try writer.print(".{s} = ", .{ - mod.intern_pool.stringToSlice(name_ip), - }); + if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(&mod.intern_pool)}); try print(.{ .ty = ty.structFieldType(i, mod), .val = try val.fieldValue(mod, i), diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 8d2ba2bbb8..c1b7bd72b1 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1850,9 +1850,9 @@ pub const DeclGen = struct { try mod.markDeclAlive(decl); if (mod.decl_exports.get(decl_index)) |exports| { - try writer.writeAll(mod.intern_pool.stringToSlice(exports.items[export_index].name)); + try writer.print("{}", .{exports.items[export_index].opts.name.fmt(&mod.intern_pool)}); } else if (decl.isExtern(mod)) { - try writer.writeAll(mod.intern_pool.stringToSlice(decl.name)); + try writer.print("{}", .{decl.name.fmt(&mod.intern_pool)}); } else { // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case), // expand to 3x the length of its input, but let's cut it off at a much shorter limit. @@ -2481,8 +2481,8 @@ fn genExports(o: *Object) !void { try fwd_decl_writer.writeAll("zig_export("); try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @intCast(u32, i) }); try fwd_decl_writer.print(", {s}, {s});\n", .{ - fmtStringLiteral(ip.stringToSlice(exports.items[0].name), null), - fmtStringLiteral(ip.stringToSlice(@"export".name), null), + fmtStringLiteral(ip.stringToSlice(exports.items[0].opts.name), null), + fmtStringLiteral(ip.stringToSlice(@"export".opts.name), null), }); } } diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 8eb5f8c683..47be4148d3 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -687,11 +687,9 @@ pub const Object = struct { for (export_list.items) |exp| { // Detect if the LLVM global has already been created as an extern. In such // case, we need to replace all uses of it with this exported global. - // TODO update std.builtin.ExportOptions to have the name be a - // null-terminated slice. - const exp_name_z = mod.intern_pool.stringToSlice(exp.name); + const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); - const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue; + const other_global = object.getLlvmGlobal(exp_name.ptr) orelse continue; if (other_global == llvm_global) continue; other_global.replaceAllUsesWith(llvm_global); @@ -1320,7 +1318,7 @@ pub const Object = struct { } } } else if (exports.len != 0) { - const exp_name = mod.intern_pool.stringToSlice(exports[0].name); + const exp_name = mod.intern_pool.stringToSlice(exports[0].opts.name); llvm_global.setValueName2(exp_name.ptr, exp_name.len); llvm_global.setUnnamedAddr(.False); if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport); @@ -1335,18 +1333,18 @@ pub const Object = struct { di_global.replaceLinkageName(linkage_name); } } - switch (exports[0].linkage) { + switch (exports[0].opts.linkage) { .Internal => unreachable, .Strong => llvm_global.setLinkage(.External), .Weak => llvm_global.setLinkage(.WeakODR), .LinkOnce => llvm_global.setLinkage(.LinkOnceODR), } - switch (exports[0].visibility) { + switch (exports[0].opts.visibility) { .default => llvm_global.setVisibility(.Default), .hidden => llvm_global.setVisibility(.Hidden), .protected => llvm_global.setVisibility(.Protected), } - if (mod.intern_pool.stringToSliceUnwrap(exports[0].section)) |section| { + if (mod.intern_pool.stringToSliceUnwrap(exports[0].opts.section)) |section| { llvm_global.setSection(section); } if (decl.val.getVariable(mod)) |variable| { @@ -1362,7 +1360,7 @@ pub const Object = struct { // Until then we iterate over existing aliases and make them point // to the correct decl, or otherwise add a new alias. Old aliases are leaked. for (exports[1..]) |exp| { - const exp_name_z = mod.intern_pool.stringToSlice(exp.name); + const exp_name_z = mod.intern_pool.stringToSlice(exp.opts.name); if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| { alias.setAliasee(llvm_global); @@ -2539,10 +2537,10 @@ pub const DeclGen = struct { const fn_type = try dg.lowerType(zig_fn_type); - const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); + const fqn = try decl.getFullyQualifiedName(mod); const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target); - const llvm_fn = dg.llvmModule().addFunctionInAddressSpace(fqn, fn_type, llvm_addrspace); + const llvm_fn = dg.llvmModule().addFunctionInAddressSpace(mod.intern_pool.stringToSlice(fqn), fn_type, llvm_addrspace); gop.value_ptr.* = llvm_fn; const is_extern = decl.isExtern(mod); @@ -2693,7 +2691,7 @@ pub const DeclGen = struct { const mod = dg.module; const decl = mod.declPtr(decl_index); - const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); + const fqn = try decl.getFullyQualifiedName(mod); const target = mod.getTarget(); @@ -2702,7 +2700,7 @@ pub const DeclGen = struct { const llvm_global = dg.object.llvm_module.addGlobalInAddressSpace( llvm_type, - fqn, + mod.intern_pool.stringToSlice(fqn), llvm_actual_addrspace, ); gop.value_ptr.* = llvm_global; @@ -5942,6 +5940,8 @@ pub const FuncGen = struct { .base_line = self.base_line, }); + const fqn = try decl.getFullyQualifiedName(mod); + const is_internal_linkage = !mod.decl_exports.contains(decl_index); const fn_ty = try mod.funcType(.{ .param_types = &.{}, @@ -5959,11 +5959,10 @@ pub const FuncGen = struct { .addrspace_is_generic = false, }); const fn_di_ty = try self.dg.object.lowerDebugType(fn_ty, .full); - const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)); const subprogram = dib.createFunction( di_file.toScope(), mod.intern_pool.stringToSlice(decl.name), - fqn, + mod.intern_pool.stringToSlice(fqn), di_file, line_number, fn_di_ty, @@ -8661,8 +8660,8 @@ pub const FuncGen = struct { defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); - const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod)); - const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn}); + const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod); + const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)}); const param_types = [_]*llvm.Type{try self.dg.lowerType(enum_type.tag_ty.toType())}; @@ -8733,8 +8732,8 @@ pub const FuncGen = struct { defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); - const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod)); - const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn}); + const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod); + const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)}); const slice_ty = Type.slice_const_u8_sentinel_0; const llvm_ret_ty = try self.dg.lowerType(slice_ty); diff --git a/src/link/C.zig b/src/link/C.zig index 8bfaf1553c..9a42daa061 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -294,7 +294,7 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo defer export_names.deinit(gpa); try export_names.ensureTotalCapacity(gpa, @intCast(u32, module.decl_exports.entries.len)); for (module.decl_exports.values()) |exports| for (exports.items) |@"export"| - try export_names.put(gpa, @"export".name, {}); + try export_names.put(gpa, @"export".opts.name, {}); while (f.remaining_decls.popOrNull()) |kv| { const decl_index = kv.key; diff --git a/src/link/Coff.zig b/src/link/Coff.zig index fec6a86b91..f7785858dd 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1430,20 +1430,20 @@ pub fn updateDeclExports( else => std.builtin.CallingConvention.C, }; const decl_cc = exported_decl.ty.fnCallingConvention(mod); - if (decl_cc == .C and ip.stringEqlSlice(exp.name, "main") and + if (decl_cc == .C and ip.stringEqlSlice(exp.opts.name, "main") and self.base.options.link_libc) { mod.stage1_flags.have_c_main = true; } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) { - if (ip.stringEqlSlice(exp.name, "WinMain")) { + if (ip.stringEqlSlice(exp.opts.name, "WinMain")) { mod.stage1_flags.have_winmain = true; - } else if (ip.stringEqlSlice(exp.name, "wWinMain")) { + } else if (ip.stringEqlSlice(exp.opts.name, "wWinMain")) { mod.stage1_flags.have_wwinmain = true; - } else if (ip.stringEqlSlice(exp.name, "WinMainCRTStartup")) { + } else if (ip.stringEqlSlice(exp.opts.name, "WinMainCRTStartup")) { mod.stage1_flags.have_winmain_crt_startup = true; - } else if (ip.stringEqlSlice(exp.name, "wWinMainCRTStartup")) { + } else if (ip.stringEqlSlice(exp.opts.name, "wWinMainCRTStartup")) { mod.stage1_flags.have_wwinmain_crt_startup = true; - } else if (ip.stringEqlSlice(exp.name, "DllMainCRTStartup")) { + } else if (ip.stringEqlSlice(exp.opts.name, "DllMainCRTStartup")) { mod.stage1_flags.have_dllmain_crt_startup = true; } } @@ -1461,10 +1461,9 @@ pub fn updateDeclExports( const decl_metadata = self.decls.getPtr(decl_index).?; for (exports) |exp| { - const exp_name = mod.intern_pool.stringToSlice(exp.name); - log.debug("adding new export '{s}'", .{exp_name}); + log.debug("adding new export '{}'", .{exp.opts.name.fmt(&mod.intern_pool)}); - if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| { + if (mod.intern_pool.stringToSliceUnwrap(exp.opts.section)) |section_name| { if (!mem.eql(u8, section_name, ".text")) { try mod.failed_exports.putNoClobber( gpa, @@ -1480,7 +1479,7 @@ pub fn updateDeclExports( } } - if (exp.linkage == .LinkOnce) { + if (exp.opts.linkage == .LinkOnce) { try mod.failed_exports.putNoClobber( gpa, exp, @@ -1494,19 +1493,19 @@ pub fn updateDeclExports( continue; } - const sym_index = decl_metadata.getExport(self, exp_name) orelse blk: { + const sym_index = decl_metadata.getExport(self, mod.intern_pool.stringToSlice(exp.opts.name)) orelse blk: { const sym_index = try self.allocateSymbol(); try decl_metadata.exports.append(gpa, sym_index); break :blk sym_index; }; const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; const sym = self.getSymbolPtr(sym_loc); - try self.setSymbolName(sym, exp_name); + try self.setSymbolName(sym, mod.intern_pool.stringToSlice(exp.opts.name)); sym.value = decl_sym.value; sym.section_number = @intToEnum(coff.SectionNumber, self.text_section_index.? + 1); sym.type = .{ .complex_type = .FUNCTION, .base_type = .NULL }; - switch (exp.linkage) { + switch (exp.opts.linkage) { .Strong => { sym.storage_class = .EXTERNAL; }, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 5ac90d4cae..409eca6e7a 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2879,9 +2879,9 @@ pub fn updateDeclExports( try self.global_symbols.ensureUnusedCapacity(gpa, exports.len); for (exports) |exp| { - const exp_name = mod.intern_pool.stringToSlice(exp.name); - if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| { - if (!mem.eql(u8, section_name, ".text")) { + const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); + if (exp.opts.section.unwrap()) |section_name| { + if (!mod.intern_pool.stringEqlSlice(section_name, ".text")) { try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1); mod.failed_exports.putAssumeCapacityNoClobber( exp, @@ -2890,7 +2890,7 @@ pub fn updateDeclExports( continue; } } - const stb_bits: u8 = switch (exp.linkage) { + const stb_bits: u8 = switch (exp.opts.linkage) { .Internal => elf.STB_LOCAL, .Strong => blk: { const entry_name = self.base.options.entry orelse "_start"; diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 70993e8dc6..a3f67bc70a 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -2401,15 +2401,15 @@ pub fn updateDeclExports( const decl_metadata = self.decls.getPtr(decl_index).?; for (exports) |exp| { - const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{ - mod.intern_pool.stringToSlice(exp.name), + const exp_name = try std.fmt.allocPrint(gpa, "_{}", .{ + exp.opts.name.fmt(&mod.intern_pool), }); defer gpa.free(exp_name); log.debug("adding new export '{s}'", .{exp_name}); - if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| { - if (!mem.eql(u8, section_name, "__text")) { + if (exp.opts.section.unwrap()) |section_name| { + if (!mod.intern_pool.stringEqlSlice(section_name, "__text")) { try mod.failed_exports.putNoClobber( mod.gpa, exp, @@ -2424,7 +2424,7 @@ pub fn updateDeclExports( } } - if (exp.linkage == .LinkOnce) { + if (exp.opts.linkage == .LinkOnce) { try mod.failed_exports.putNoClobber( mod.gpa, exp, @@ -2453,7 +2453,7 @@ pub fn updateDeclExports( .n_value = decl_sym.n_value, }; - switch (exp.linkage) { + switch (exp.opts.linkage) { .Internal => { // Symbol should be hidden, or in MachO lingo, private extern. // We should also mark the symbol as Weak: n_desc == N_WEAK_DEF. diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 5cf2add528..2606dd7aac 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -725,10 +725,10 @@ fn addDeclExports( const decl_block = self.getDeclBlock(metadata.index); for (exports) |exp| { - const exp_name = mod.intern_pool.stringToSlice(exp.name); + const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); // plan9 does not support custom sections - if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| { - if (!mem.eql(u8, section_name, ".text") or !mem.eql(u8, section_name, ".data")) { + if (exp.opts.section.unwrap()) |section_name| { + if (!mod.intern_pool.stringEqlSlice(section_name, ".text") and !mod.intern_pool.stringEqlSlice(section_name, ".data")) { try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create( self.base.allocator, mod.declPtr(decl_index).srcLoc(mod), @@ -972,7 +972,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { const sym = self.syms.items[decl_block.sym_index.?]; try self.writeSym(writer, sym); if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| { - for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.name))) |exp_i| { + for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.opts.name))) |exp_i| { try self.writeSym(writer, self.syms.items[exp_i]); }; } @@ -998,7 +998,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { const sym = self.syms.items[decl_block.sym_index.?]; try self.writeSym(writer, sym); if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| { - for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.name))) |exp_i| { + for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.opts.name))) |exp_i| { const s = self.syms.items[exp_i]; if (mem.eql(u8, s.name, "_start")) self.entry_val = s.value; diff --git a/src/link/SpirV.zig b/src/link/SpirV.zig index fbde464c54..5bbd5ebdc0 100644 --- a/src/link/SpirV.zig +++ b/src/link/SpirV.zig @@ -147,7 +147,7 @@ pub fn updateDeclExports( const spv_decl_index = entry.value_ptr.*; for (exports) |exp| { - try self.spv.declareEntryPoint(spv_decl_index, mod.intern_pool.stringToSlice(exp.name)); + try self.spv.declareEntryPoint(spv_decl_index, mod.intern_pool.stringToSlice(exp.opts.name)); } } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 35972d2fec..fdac7dfa63 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1706,7 +1706,7 @@ pub fn updateDeclExports( const gpa = mod.gpa; for (exports) |exp| { - if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section| { + if (mod.intern_pool.stringToSliceUnwrap(exp.opts.section)) |section| { try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create( gpa, decl.srcLoc(mod), @@ -1716,12 +1716,12 @@ pub fn updateDeclExports( continue; } - const export_name = try wasm.string_table.put(wasm.base.allocator, mod.intern_pool.stringToSlice(exp.name)); + const export_name = try wasm.string_table.put(wasm.base.allocator, mod.intern_pool.stringToSlice(exp.opts.name)); if (wasm.globals.getPtr(export_name)) |existing_loc| { if (existing_loc.index == atom.sym_index) continue; const existing_sym: Symbol = existing_loc.getSymbol(wasm).*; - const exp_is_weak = exp.linkage == .Internal or exp.linkage == .Weak; + const exp_is_weak = exp.opts.linkage == .Internal or exp.opts.linkage == .Weak; // When both the to-be-exported symbol and the already existing symbol // are strong symbols, we have a linker error. // In the other case we replace one with the other. @@ -1729,11 +1729,11 @@ pub fn updateDeclExports( try mod.failed_exports.put(gpa, exp, try Module.ErrorMsg.create( gpa, decl.srcLoc(mod), - \\LinkError: symbol '{s}' defined multiple times + \\LinkError: symbol '{}' defined multiple times \\ first definition in '{s}' \\ next definition in '{s}' , - .{ mod.intern_pool.stringToSlice(exp.name), wasm.name, wasm.name }, + .{ exp.opts.name.fmt(&mod.intern_pool), wasm.name, wasm.name }, )); continue; } else if (exp_is_weak) { @@ -1750,7 +1750,7 @@ pub fn updateDeclExports( const exported_atom = wasm.getAtom(exported_atom_index); const sym_loc = exported_atom.symbolLoc(); const symbol = sym_loc.getSymbol(wasm); - switch (exp.linkage) { + switch (exp.opts.linkage) { .Internal => { symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); }, @@ -1769,7 +1769,7 @@ pub fn updateDeclExports( }, } // Ensure the symbol will be exported using the given name - if (!mod.intern_pool.stringEqlSlice(exp.name, sym_loc.getName(wasm))) { + if (!mod.intern_pool.stringEqlSlice(exp.opts.name, sym_loc.getName(wasm))) { try wasm.export_names.put(wasm.base.allocator, sym_loc, export_name); } diff --git a/src/print_air.zig b/src/print_air.zig index eb10477292..f963ecdd95 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -685,9 +685,8 @@ const Writer = struct { fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { const ty_fn = w.air.instructions.items(.data)[inst].ty_fn; const func_index = ty_fn.func; - const ip = &w.module.intern_pool; const owner_decl = w.module.declPtr(w.module.funcPtr(func_index).owner_decl); - try s.print("{s}", .{ip.stringToSlice(owner_decl.name)}); + try s.print("{}", .{owner_decl.name.fmt(&w.module.intern_pool)}); } fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { diff --git a/src/type.zig b/src/type.zig index f9065a2e39..4269ee56d3 100644 --- a/src/type.zig +++ b/src/type.zig @@ -284,7 +284,7 @@ pub const Type = struct { try writer.writeAll("error{"); for (names, 0..) |name, i| { if (i != 0) try writer.writeByte(','); - try writer.writeAll(mod.intern_pool.stringToSlice(name)); + try writer.print("{}", .{name.fmt(&mod.intern_pool)}); } try writer.writeAll("}"); }, @@ -341,7 +341,7 @@ pub const Type = struct { try decl.renderFullyQualifiedName(mod, writer); } else if (struct_type.namespace.unwrap()) |namespace_index| { const namespace = mod.namespacePtr(namespace_index); - try namespace.renderFullyQualifiedName(mod, "", writer); + try namespace.renderFullyQualifiedName(mod, .empty, writer); } else { try writer.writeAll("@TypeOf(.{})"); } @@ -357,9 +357,7 @@ pub const Type = struct { try writer.writeAll("comptime "); } if (anon_struct.names.len != 0) { - const name = mod.intern_pool.stringToSlice(anon_struct.names[i]); - try writer.writeAll(name); - try writer.writeAll(": "); + try writer.print("{}: ", .{anon_struct.names[i].fmt(&mod.intern_pool)}); } try print(field_ty.toType(), writer, mod); diff --git a/src/value.zig b/src/value.zig index dbf25324e5..d3f15121b8 100644 --- a/src/value.zig +++ b/src/value.zig @@ -525,23 +525,6 @@ pub const Value = struct { }; } - pub fn tagName(val: Value, mod: *Module) []const u8 { - const ip = &mod.intern_pool; - const enum_tag = switch (ip.indexToKey(val.toIntern())) { - .un => |un| ip.indexToKey(un.tag).enum_tag, - .enum_tag => |x| x, - .enum_literal => |name| return ip.stringToSlice(name), - else => unreachable, - }; - const enum_type = ip.indexToKey(enum_tag.ty).enum_type; - const field_index = field_index: { - const field_index = enum_type.tagValueIndex(ip, val.toIntern()).?; - break :field_index @intCast(u32, field_index); - }; - const field_name = enum_type.names[field_index]; - return ip.stringToSlice(field_name); - } - /// Asserts the value is an integer. pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *Module) BigIntConst { return val.toBigIntAdvanced(space, mod, null) catch unreachable; @@ -2092,33 +2075,23 @@ pub const Value = struct { }; } - /// Valid only for error (union) types. Asserts the value is not undefined and not - /// unreachable. For error unions, prefer `errorUnionIsPayload` to find out whether - /// something is an error or not because it works without having to figure out the - /// string. - pub fn getError(val: Value, mod: *const Module) ?[]const u8 { - return switch (getErrorName(val, mod)) { - .empty => null, - else => |s| mod.intern_pool.stringToSlice(s), - }; - } - - pub fn getErrorName(val: Value, mod: *const Module) InternPool.NullTerminatedString { + /// Valid only for error (union) types. Asserts the value is not undefined and not unreachable. + pub fn getErrorName(val: Value, mod: *const Module) InternPool.OptionalNullTerminatedString { return switch (mod.intern_pool.indexToKey(val.toIntern())) { - .err => |err| err.name, + .err => |err| err.name.toOptional(), .error_union => |error_union| switch (error_union.val) { - .err_name => |err_name| err_name, - .payload => .empty, + .err_name => |err_name| err_name.toOptional(), + .payload => .none, }, else => unreachable, }; } pub fn getErrorInt(val: Value, mod: *const Module) Module.ErrorInt { - return switch (getErrorName(val, mod)) { - .empty => 0, - else => |s| @intCast(Module.ErrorInt, mod.global_error_set.getIndex(s).?), - }; + return if (getErrorName(val, mod).unwrap()) |err_name| + @intCast(Module.ErrorInt, mod.global_error_set.getIndex(err_name).?) + else + 0; } /// Assumes the type is an error union. Returns true if and only if the value is