authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-01 23:46:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:58-07:00
log69b7b910929e84248671377e1743477757e66837
tree4e6b8295de849dc066e6da9c1a8a35ab37b837c3
parent34dae73005baa3be54e0d9e0725ab31cb0723a06

compiler: eliminate Decl.value_arena and Sema.perm_arena

The main motivation for this commit is eliminating Decl.value_arena. Everything else is dominoes. Decl.name used to be stored in the GPA, now it is stored in InternPool. It ended up being simpler to migrate other strings to be interned as well, such as struct field names, union field names, and a few others. This ended up requiring a big diff, sorry about that. But the changes are pretty nice, we finally start to take advantage of InternPool's existence. global_error_set and error_name_list are simplified. Now it is a single ArrayHashMap(NullTerminatedString, void) and the index is the error tag value. Module.tmp_hack_arena is re-introduced (it was removed in eeff407941560ce8eb5b737b2436dfa93cfd3a0c) in order to deal with comptime_args, optimized_order, and struct and union fields. After structs and unions get moved into InternPool properly, tmp_hack_arena can be deleted again.

26 files changed, 1160 insertions(+), 1132 deletions(-)

src/Compilation.zig+11-10
......@@ -1317,7 +1317,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
13171317 .global_zir_cache = global_zir_cache,
13181318 .local_zir_cache = local_zir_cache,
13191319 .emit_h = emit_h,
1320 .error_name_list = .{},
1320 .tmp_hack_arena = std.heap.ArenaAllocator.init(gpa),
13211321 };
13221322 try module.init();
13231323
......@@ -2627,7 +2627,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
26272627 var it = module.failed_files.iterator();
26282628 while (it.next()) |entry| {
26292629 if (entry.value_ptr.*) |msg| {
2630 try addModuleErrorMsg(&bundle, msg.*);
2630 try addModuleErrorMsg(module, &bundle, msg.*);
26312631 } else {
26322632 // Must be ZIR errors. Note that this may include AST errors.
26332633 // addZirErrorMessages asserts that the tree is loaded.
......@@ -2640,7 +2640,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
26402640 var it = module.failed_embed_files.iterator();
26412641 while (it.next()) |entry| {
26422642 const msg = entry.value_ptr.*;
2643 try addModuleErrorMsg(&bundle, msg.*);
2643 try addModuleErrorMsg(module, &bundle, msg.*);
26442644 }
26452645 }
26462646 {
......@@ -2650,7 +2650,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
26502650 // Skip errors for Decls within files that had a parse failure.
26512651 // We'll try again once parsing succeeds.
26522652 if (module.declFileScope(decl_index).okToReportErrors()) {
2653 try addModuleErrorMsg(&bundle, entry.value_ptr.*.*);
2653 try addModuleErrorMsg(module, &bundle, entry.value_ptr.*.*);
26542654 if (module.cimport_errors.get(entry.key_ptr.*)) |cimport_errors| for (cimport_errors) |c_error| {
26552655 try bundle.addRootErrorMessage(.{
26562656 .msg = try bundle.addString(std.mem.span(c_error.msg)),
......@@ -2675,12 +2675,12 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
26752675 // Skip errors for Decls within files that had a parse failure.
26762676 // We'll try again once parsing succeeds.
26772677 if (module.declFileScope(decl_index).okToReportErrors()) {
2678 try addModuleErrorMsg(&bundle, entry.value_ptr.*.*);
2678 try addModuleErrorMsg(module, &bundle, entry.value_ptr.*.*);
26792679 }
26802680 }
26812681 }
26822682 for (module.failed_exports.values()) |value| {
2683 try addModuleErrorMsg(&bundle, value.*);
2683 try addModuleErrorMsg(module, &bundle, value.*);
26842684 }
26852685 }
26862686
......@@ -2728,7 +2728,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
27282728 };
27292729 }
27302730
2731 try addModuleErrorMsg(&bundle, err_msg);
2731 try addModuleErrorMsg(module, &bundle, err_msg);
27322732 }
27332733 }
27342734
......@@ -2784,8 +2784,9 @@ pub const ErrorNoteHashContext = struct {
27842784 }
27852785};
27862786
2787pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg) !void {
2787pub fn addModuleErrorMsg(mod: *Module, eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg) !void {
27882788 const gpa = eb.gpa;
2789 const ip = &mod.intern_pool;
27892790 const err_source = module_err_msg.src_loc.file_scope.getSource(gpa) catch |err| {
27902791 const file_path = try module_err_msg.src_loc.file_scope.fullPath(gpa);
27912792 defer gpa.free(file_path);
......@@ -2811,7 +2812,7 @@ pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg)
28112812 .src_loc = .none,
28122813 });
28132814 break;
2814 } else if (module_reference.decl == null) {
2815 } else if (module_reference.decl == .none) {
28152816 try ref_traces.append(gpa, .{
28162817 .decl_name = 0,
28172818 .src_loc = .none,
......@@ -2824,7 +2825,7 @@ pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg)
28242825 const rt_file_path = try module_reference.src_loc.file_scope.fullPath(gpa);
28252826 defer gpa.free(rt_file_path);
28262827 try ref_traces.append(gpa, .{
2827 .decl_name = try eb.addString(std.mem.sliceTo(module_reference.decl.?, 0)),
2828 .decl_name = try eb.addString(ip.stringToSliceUnwrap(module_reference.decl).?),
28282829 .src_loc = try eb.addSourceLocation(.{
28292830 .src_path = try eb.addString(rt_file_path),
28302831 .span_start = span.start,
src/InternPool.zig+33
......@@ -124,6 +124,8 @@ pub const String = enum(u32) {
124124
125125/// An index into `string_bytes`.
126126pub const NullTerminatedString = enum(u32) {
127 /// This is distinct from `none` - it is a valid index that represents empty string.
128 empty = 0,
127129 _,
128130
129131 pub fn toString(self: NullTerminatedString) String {
......@@ -157,6 +159,8 @@ pub const NullTerminatedString = enum(u32) {
157159
158160/// An index into `string_bytes` which might be `none`.
159161pub const OptionalNullTerminatedString = enum(u32) {
162 /// This is distinct from `none` - it is a valid index that represents empty string.
163 empty = 0,
160164 none = std.math.maxInt(u32),
161165 _,
162166
......@@ -2447,6 +2451,9 @@ pub const MemoizedCall = struct {
24472451pub fn init(ip: *InternPool, gpa: Allocator) !void {
24482452 assert(ip.items.len == 0);
24492453
2454 // Reserve string index 0 for an empty string.
2455 assert((try ip.getOrPutString(gpa, "")) == .empty);
2456
24502457 // So that we can use `catch unreachable` below.
24512458 try ip.items.ensureUnusedCapacity(gpa, static_keys.len);
24522459 try ip.map.ensureUnusedCapacity(gpa, static_keys.len);
......@@ -5222,6 +5229,28 @@ pub fn getOrPutString(
52225229 return ip.getOrPutTrailingString(gpa, s.len + 1);
52235230}
52245231
5232pub fn getOrPutStringFmt(
5233 ip: *InternPool,
5234 gpa: Allocator,
5235 comptime format: []const u8,
5236 args: anytype,
5237) Allocator.Error!NullTerminatedString {
5238 const start = ip.string_bytes.items.len;
5239 try ip.string_bytes.writer(gpa).print(format, args);
5240 try ip.string_bytes.append(gpa, 0);
5241 return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
5242}
5243
5244pub fn getOrPutStringOpt(
5245 ip: *InternPool,
5246 gpa: Allocator,
5247 optional_string: ?[]const u8,
5248) Allocator.Error!OptionalNullTerminatedString {
5249 const s = optional_string orelse return .none;
5250 const interned = try getOrPutString(ip, gpa, s);
5251 return interned.toOptional();
5252}
5253
52255254/// Uses the last len bytes of ip.string_bytes as the key.
52265255pub fn getOrPutTrailingString(
52275256 ip: *InternPool,
......@@ -5273,6 +5302,10 @@ pub fn stringToSliceUnwrap(ip: *const InternPool, s: OptionalNullTerminatedStrin
52735302 return ip.stringToSlice(s.unwrap() orelse return null);
52745303}
52755304
5305pub fn stringEqlSlice(ip: *const InternPool, a: NullTerminatedString, b: []const u8) bool {
5306 return std.mem.eql(u8, stringToSlice(ip, a), b);
5307}
5308
52765309pub fn typeOf(ip: *const InternPool, index: Index) Index {
52775310 // This optimization of static keys is required so that typeOf can be called
52785311 // on static keys that haven't been added yet during static key initialization.
src/Module.zig+115-217
......@@ -88,6 +88,14 @@ embed_table: std.StringHashMapUnmanaged(*EmbedFile) = .{},
8888/// Stores all Type and Value objects; periodically garbage collected.
8989intern_pool: InternPool = .{},
9090
91/// To be eliminated in a future commit by moving more data into InternPool.
92/// Current uses that must be eliminated:
93/// * Struct comptime_args
94/// * Struct optimized_order
95/// * Union fields
96/// This memory lives until the Module is destroyed.
97tmp_hack_arena: std.heap.ArenaAllocator,
98
9199/// This is currently only used for string literals.
92100memoized_decls: std.AutoHashMapUnmanaged(InternPool.Index, Decl.Index) = .{},
93101
......@@ -125,13 +133,8 @@ cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, []CImportError) = .{},
125133/// contains Decls that need to be deleted if they end up having no references to them.
126134deletion_set: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
127135
128/// Error tags and their values, tag names are duped with mod.gpa.
129/// Corresponds with `error_name_list`.
130global_error_set: std.StringHashMapUnmanaged(ErrorInt) = .{},
131
132/// ErrorInt -> []const u8 for fast lookups for @intToError at comptime
133/// Corresponds with `global_error_set`.
134error_name_list: ArrayListUnmanaged([]const u8),
136/// Key is the error name, index is the error tag value. Index 0 has a length-0 string.
137global_error_set: GlobalErrorSet = .{},
135138
136139/// Incrementing integer used to compare against the corresponding Decl
137140/// field to determine whether a Decl's status applies to an ongoing update, or a
......@@ -182,6 +185,8 @@ reference_table: std.AutoHashMapUnmanaged(Decl.Index, struct {
182185 src: LazySrcLoc,
183186}) = .{},
184187
188pub const GlobalErrorSet = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);
189
185190pub const CImportError = struct {
186191 offset: u32,
187192 line: u32,
......@@ -248,7 +253,11 @@ pub const GlobalEmitH = struct {
248253pub const ErrorInt = u32;
249254
250255pub const Export = struct {
251 options: std.builtin.ExportOptions,
256 name: InternPool.NullTerminatedString,
257 linkage: std.builtin.GlobalLinkage,
258 section: InternPool.OptionalNullTerminatedString,
259 visibility: std.builtin.SymbolVisibility,
260
252261 src: LazySrcLoc,
253262 /// The Decl that performs the export. Note that this is *not* the Decl being exported.
254263 owner_decl: Decl.Index,
......@@ -392,8 +401,7 @@ const ValueArena = struct {
392401};
393402
394403pub const Decl = struct {
395 /// Allocated with Module's allocator; outlives the ZIR code.
396 name: [*:0]const u8,
404 name: InternPool.NullTerminatedString,
397405 /// The most recent Type of the Decl after a successful semantic analysis.
398406 /// Populated when `has_tv`.
399407 ty: Type,
......@@ -401,15 +409,11 @@ pub const Decl = struct {
401409 /// Populated when `has_tv`.
402410 val: Value,
403411 /// Populated when `has_tv`.
404 /// Points to memory inside value_arena.
405 @"linksection": ?[*:0]const u8,
412 @"linksection": InternPool.OptionalNullTerminatedString,
406413 /// Populated when `has_tv`.
407414 @"align": u32,
408415 /// Populated when `has_tv`.
409416 @"addrspace": std.builtin.AddressSpace,
410 /// The memory for ty, val, align, linksection, and captures.
411 /// If this is `null` then there is no memory management needed.
412 value_arena: ?*ValueArena = null,
413417 /// The direct parent namespace of the Decl.
414418 /// Reference to externally owned memory.
415419 /// In the case of the Decl corresponding to a file, this is
......@@ -564,13 +568,7 @@ pub const Decl = struct {
564568 function_body,
565569 };
566570
567 pub fn clearName(decl: *Decl, gpa: Allocator) void {
568 gpa.free(mem.sliceTo(decl.name, 0));
569 decl.name = undefined;
570 }
571
572571 pub fn clearValues(decl: *Decl, mod: *Module) void {
573 const gpa = mod.gpa;
574572 if (decl.getOwnedFunctionIndex(mod).unwrap()) |func| {
575573 _ = mod.align_stack_fns.remove(func);
576574 if (mod.funcPtr(func).comptime_args != null) {
......@@ -579,19 +577,6 @@ pub const Decl = struct {
579577 mod.destroyFunc(func);
580578 }
581579 _ = mod.memoized_decls.remove(decl.val.ip_index);
582 if (decl.value_arena) |value_arena| {
583 value_arena.deinit(gpa);
584 decl.value_arena = null;
585 decl.has_tv = false;
586 decl.owns_tv = false;
587 }
588 }
589
590 pub fn finalizeNewArena(decl: *Decl, arena: *std.heap.ArenaAllocator) !void {
591 assert(decl.value_arena == null);
592 const value_arena = try arena.allocator().create(ValueArena);
593 value_arena.* = .{ .state = arena.state };
594 decl.value_arena = value_arena;
595580 }
596581
597582 /// This name is relative to the containing namespace of the decl.
......@@ -692,7 +677,7 @@ pub const Decl = struct {
692677 }
693678
694679 pub fn renderFullyQualifiedName(decl: Decl, mod: *Module, writer: anytype) !void {
695 const unqualified_name = mem.sliceTo(decl.name, 0);
680 const unqualified_name = mod.intern_pool.stringToSlice(decl.name);
696681 if (decl.name_fully_qualified) {
697682 return writer.writeAll(unqualified_name);
698683 }
......@@ -700,24 +685,27 @@ pub const Decl = struct {
700685 }
701686
702687 pub fn renderFullyQualifiedDebugName(decl: Decl, mod: *Module, writer: anytype) !void {
703 const unqualified_name = mem.sliceTo(decl.name, 0);
688 const unqualified_name = mod.intern_pool.stringToSlice(decl.name);
704689 return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, unqualified_name, writer);
705690 }
706691
707 pub fn getFullyQualifiedName(decl: Decl, mod: *Module) ![:0]u8 {
708 var buffer = std.ArrayList(u8).init(mod.gpa);
709 defer buffer.deinit();
710 try decl.renderFullyQualifiedName(mod, buffer.writer());
692 pub fn getFullyQualifiedName(decl: Decl, mod: *Module) !InternPool.NullTerminatedString {
693 const gpa = mod.gpa;
694 const ip = &mod.intern_pool;
695 const start = ip.string_bytes.items.len;
696 try decl.renderFullyQualifiedName(mod, ip.string_bytes.writer(gpa));
711697
712698 // Sanitize the name for nvptx which is more restrictive.
699 // TODO This should be handled by the backend, not the frontend. Have a
700 // look at how the C backend does it for inspiration.
713701 if (mod.comp.bin_file.options.target.cpu.arch.isNvptx()) {
714 for (buffer.items) |*byte| switch (byte.*) {
702 for (ip.string_bytes.items[start..]) |*byte| switch (byte.*) {
715703 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
716704 else => {},
717705 };
718706 }
719707
720 return buffer.toOwnedSliceSentinel(0);
708 return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
721709 }
722710
723711 pub fn typedValue(decl: Decl) error{AnalysisFail}!TypedValue {
......@@ -804,11 +792,11 @@ pub const Decl = struct {
804792
805793 pub fn dump(decl: *Decl) void {
806794 const loc = std.zig.findLineColumn(decl.scope.source.bytes, decl.src);
807 std.debug.print("{s}:{d}:{d} name={s} status={s}", .{
795 std.debug.print("{s}:{d}:{d} name={d} status={s}", .{
808796 decl.scope.sub_file_path,
809797 loc.line + 1,
810798 loc.column + 1,
811 mem.sliceTo(decl.name, 0),
799 @enumToInt(decl.name),
812800 @tagName(decl.analysis),
813801 });
814802 if (decl.has_tv) {
......@@ -922,15 +910,15 @@ pub const Struct = struct {
922910 }
923911 };
924912
925 pub const Fields = std.StringArrayHashMapUnmanaged(Field);
913 pub const Fields = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, Field);
926914
927915 /// The `Type` and `Value` memory is owned by the arena of the Struct's owner_decl.
928916 pub const Field = struct {
929917 /// Uses `noreturn` to indicate `anytype`.
930918 /// undefined until `status` is >= `have_field_types`.
931919 ty: Type,
932 /// Uses `unreachable_value` to indicate no default.
933 default_val: Value,
920 /// Uses `none` to indicate no default.
921 default_val: InternPool.Index,
934922 /// Zero means to use the ABI alignment of the type.
935923 abi_align: u32,
936924 /// undefined until `status` is `have_layout`.
......@@ -982,7 +970,7 @@ pub const Struct = struct {
982970 /// runtime version of the struct.
983971 pub const omitted_field = std.math.maxInt(u32);
984972
985 pub fn getFullyQualifiedName(s: *Struct, mod: *Module) ![:0]u8 {
973 pub fn getFullyQualifiedName(s: *Struct, mod: *Module) !InternPool.NullTerminatedString {
986974 return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
987975 }
988976
......@@ -1141,9 +1129,9 @@ pub const Union = struct {
11411129 }
11421130 };
11431131
1144 pub const Fields = std.StringArrayHashMapUnmanaged(Field);
1132 pub const Fields = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, Field);
11451133
1146 pub fn getFullyQualifiedName(s: *Union, mod: *Module) ![:0]u8 {
1134 pub fn getFullyQualifiedName(s: *Union, mod: *Module) !InternPool.NullTerminatedString {
11471135 return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
11481136 }
11491137
......@@ -1569,15 +1557,15 @@ pub const Fn = struct {
15691557pub const DeclAdapter = struct {
15701558 mod: *Module,
15711559
1572 pub fn hash(self: @This(), s: []const u8) u32 {
1560 pub fn hash(self: @This(), s: InternPool.NullTerminatedString) u32 {
15731561 _ = self;
1574 return @truncate(u32, std.hash.Wyhash.hash(0, s));
1562 return std.hash.uint32(@enumToInt(s));
15751563 }
15761564
1577 pub fn eql(self: @This(), a: []const u8, b_decl_index: Decl.Index, b_index: usize) bool {
1565 pub fn eql(self: @This(), a: InternPool.NullTerminatedString, b_decl_index: Decl.Index, b_index: usize) bool {
15781566 _ = b_index;
15791567 const b_decl = self.mod.declPtr(b_decl_index);
1580 return mem.eql(u8, a, mem.sliceTo(b_decl.name, 0));
1568 return a == b_decl.name;
15811569 }
15821570};
15831571
......@@ -1628,16 +1616,14 @@ pub const Namespace = struct {
16281616
16291617 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {
16301618 const decl = ctx.module.declPtr(decl_index);
1631 return @truncate(u32, std.hash.Wyhash.hash(0, mem.sliceTo(decl.name, 0)));
1619 return std.hash.uint32(@enumToInt(decl.name));
16321620 }
16331621
16341622 pub fn eql(ctx: @This(), a_decl_index: Decl.Index, b_decl_index: Decl.Index, b_index: usize) bool {
16351623 _ = b_index;
16361624 const a_decl = ctx.module.declPtr(a_decl_index);
16371625 const b_decl = ctx.module.declPtr(b_decl_index);
1638 const a_name = mem.sliceTo(a_decl.name, 0);
1639 const b_name = mem.sliceTo(b_decl.name, 0);
1640 return mem.eql(u8, a_name, b_name);
1626 return a_decl.name == b_decl.name;
16411627 }
16421628 };
16431629
......@@ -1649,8 +1635,6 @@ pub const Namespace = struct {
16491635 pub fn destroyDecls(ns: *Namespace, mod: *Module) void {
16501636 const gpa = mod.gpa;
16511637
1652 log.debug("destroyDecls {*}", .{ns});
1653
16541638 var decls = ns.decls;
16551639 ns.decls = .{};
16561640
......@@ -1676,8 +1660,6 @@ pub const Namespace = struct {
16761660 ) !void {
16771661 const gpa = mod.gpa;
16781662
1679 log.debug("deleteAllDecls {*}", .{ns});
1680
16811663 var decls = ns.decls;
16821664 ns.decls = .{};
16831665
......@@ -1712,7 +1694,8 @@ pub const Namespace = struct {
17121694 if (ns.parent.unwrap()) |parent| {
17131695 const decl_index = ns.getDeclIndex(mod);
17141696 const decl = mod.declPtr(decl_index);
1715 try mod.namespacePtr(parent).renderFullyQualifiedName(mod, mem.sliceTo(decl.name, 0), writer);
1697 const decl_name = mod.intern_pool.stringToSlice(decl.name);
1698 try mod.namespacePtr(parent).renderFullyQualifiedName(mod, decl_name, writer);
17161699 } else {
17171700 try ns.file_scope.renderFullyQualifiedName(writer);
17181701 }
......@@ -1733,7 +1716,8 @@ pub const Namespace = struct {
17331716 if (ns.parent.unwrap()) |parent| {
17341717 const decl_index = ns.getDeclIndex(mod);
17351718 const decl = mod.declPtr(decl_index);
1736 try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, mem.sliceTo(decl.name, 0), writer);
1719 const decl_name = mod.intern_pool.stringToSlice(decl.name);
1720 try mod.namespacePtr(parent).renderFullyQualifiedDebugName(mod, decl_name, writer);
17371721 } else {
17381722 try ns.file_scope.renderFullyQualifiedDebugName(writer);
17391723 separator_char = ':';
......@@ -1927,11 +1911,11 @@ pub const File = struct {
19271911 };
19281912 }
19291913
1930 pub fn fullyQualifiedNameZ(file: File, gpa: Allocator) ![:0]u8 {
1931 var buf = std.ArrayList(u8).init(gpa);
1932 defer buf.deinit();
1933 try file.renderFullyQualifiedName(buf.writer());
1934 return buf.toOwnedSliceSentinel(0);
1914 pub fn fullyQualifiedName(file: File, mod: *Module) !InternPool.NullTerminatedString {
1915 const ip = &mod.intern_pool;
1916 const start = ip.string_bytes.items.len;
1917 try file.renderFullyQualifiedName(ip.string_bytes.writer(mod.gpa));
1918 return ip.getOrPutTrailingString(mod.gpa, ip.string_bytes.items.len - start);
19351919 }
19361920
19371921 /// Returns the full path to this file relative to its package.
......@@ -2055,7 +2039,7 @@ pub const ErrorMsg = struct {
20552039 reference_trace: []Trace = &.{},
20562040
20572041 pub const Trace = struct {
2058 decl: ?[*:0]const u8,
2042 decl: InternPool.OptionalNullTerminatedString,
20592043 src_loc: SrcLoc,
20602044 hidden: u32 = 0,
20612045 };
......@@ -3180,8 +3164,8 @@ pub const CompileError = error{
31803164
31813165pub fn init(mod: *Module) !void {
31823166 const gpa = mod.gpa;
3183 try mod.error_name_list.append(gpa, "(no error)");
31843167 try mod.intern_pool.init(gpa);
3168 try mod.global_error_set.put(gpa, .empty, {});
31853169}
31863170
31873171pub fn deinit(mod: *Module) void {
......@@ -3282,15 +3266,8 @@ pub fn deinit(mod: *Module) void {
32823266 }
32833267 mod.export_owners.deinit(gpa);
32843268
3285 {
3286 var it = mod.global_error_set.keyIterator();
3287 while (it.next()) |key| {
3288 gpa.free(key.*);
3289 }
3290 mod.global_error_set.deinit(gpa);
3291 }
3269 mod.global_error_set.deinit(gpa);
32923270
3293 mod.error_name_list.deinit(gpa);
32943271 mod.test_functions.deinit(gpa);
32953272 mod.align_stack_fns.deinit(gpa);
32963273 mod.monomorphed_funcs.deinit(gpa);
......@@ -3305,13 +3282,13 @@ pub fn deinit(mod: *Module) void {
33053282
33063283 mod.memoized_decls.deinit(gpa);
33073284 mod.intern_pool.deinit(gpa);
3285 mod.tmp_hack_arena.deinit();
33083286}
33093287
33103288pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
33113289 const gpa = mod.gpa;
33123290 {
33133291 const decl = mod.declPtr(decl_index);
3314 log.debug("destroy {*} ({s})", .{ decl, decl.name });
33153292 _ = mod.test_functions.swapRemove(decl_index);
33163293 if (decl.deletion_flag) {
33173294 assert(mod.deletion_set.swapRemove(decl_index));
......@@ -3329,7 +3306,6 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
33293306 decl.clearValues(mod);
33303307 decl.dependants.deinit(gpa);
33313308 decl.dependencies.deinit(gpa);
3332 decl.clearName(gpa);
33333309 decl.* = undefined;
33343310 }
33353311 mod.decls_free_list.append(gpa, decl_index) catch {
......@@ -3391,11 +3367,7 @@ pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {
33913367}
33923368
33933369fn freeExportList(gpa: Allocator, export_list: *ArrayListUnmanaged(*Export)) void {
3394 for (export_list.items) |exp| {
3395 gpa.free(exp.options.name);
3396 if (exp.options.section) |s| gpa.free(s);
3397 gpa.destroy(exp);
3398 }
3370 for (export_list.items) |exp| gpa.destroy(exp);
33993371 export_list.deinit(gpa);
34003372}
34013373
......@@ -3814,9 +3786,6 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
38143786 if (decl.zir_decl_index != 0) {
38153787 const old_zir_decl_index = decl.zir_decl_index;
38163788 const new_zir_decl_index = extra_map.get(old_zir_decl_index) orelse {
3817 log.debug("updateZirRefs {s}: delete {*} ({s})", .{
3818 file.sub_file_path, decl, decl.name,
3819 });
38203789 try file.deleted_decls.append(gpa, decl_index);
38213790 continue;
38223791 };
......@@ -3824,14 +3793,7 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
38243793 decl.zir_decl_index = new_zir_decl_index;
38253794 const new_hash = decl.contentsHashZir(new_zir);
38263795 if (!std.zig.srcHashEql(old_hash, new_hash)) {
3827 log.debug("updateZirRefs {s}: outdated {*} ({s}) {d} => {d}", .{
3828 file.sub_file_path, decl, decl.name, old_zir_decl_index, new_zir_decl_index,
3829 });
38303796 try file.outdated_decls.append(gpa, decl_index);
3831 } else {
3832 log.debug("updateZirRefs {s}: unchanged {*} ({s}) {d} => {d}", .{
3833 file.sub_file_path, decl, decl.name, old_zir_decl_index, new_zir_decl_index,
3834 });
38353797 }
38363798 }
38373799
......@@ -4031,8 +3993,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
40313993 .complete => return,
40323994
40333995 .outdated => blk: {
4034 log.debug("re-analyzing {*} ({s})", .{ decl, decl.name });
4035
40363996 // The exports this Decl performs will be re-discovered, so we remove them here
40373997 // prior to re-analysis.
40383998 try mod.deleteDeclExports(decl_index);
......@@ -4047,9 +4007,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
40474007 const dep = mod.declPtr(dep_index);
40484008 dep.removeDependant(decl_index);
40494009 if (dep.dependants.count() == 0 and !dep.deletion_flag) {
4050 log.debug("insert {*} ({s}) dependant {*} ({s}) into deletion set", .{
4051 decl, decl.name, dep, dep.name,
4052 });
40534010 try mod.markDeclForDeletion(dep_index);
40544011 }
40554012 }
......@@ -4061,7 +4018,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
40614018 .unreferenced => false,
40624019 };
40634020
4064 var decl_prog_node = mod.sema_prog_node.start(mem.sliceTo(decl.name, 0), 0);
4021 var decl_prog_node = mod.sema_prog_node.start(mod.intern_pool.stringToSlice(decl.name), 0);
40654022 decl_prog_node.activate();
40664023 defer decl_prog_node.end();
40674024
......@@ -4190,14 +4147,11 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: Fn.Index) SemaError!void
41904147
41914148 if (no_bin_file and !dump_air and !dump_llvm_ir) return;
41924149
4193 log.debug("analyze liveness of {s}", .{decl.name});
41944150 var liveness = try Liveness.analyze(gpa, air, &mod.intern_pool);
41954151 defer liveness.deinit(gpa);
41964152
41974153 if (dump_air) {
4198 const fqn = try decl.getFullyQualifiedName(mod);
4199 defer mod.gpa.free(fqn);
4200
4154 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
42014155 std.debug.print("# Begin Function AIR: {s}:\n", .{fqn});
42024156 @import("print_air.zig").dump(mod, air, liveness);
42034157 std.debug.print("# End Function AIR: {s}\n\n", .{fqn});
......@@ -4354,9 +4308,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
43544308 if (file.root_decl != .none) return;
43554309
43564310 const gpa = mod.gpa;
4357 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
4358 errdefer new_decl_arena.deinit();
4359 const new_decl_arena_allocator = new_decl_arena.allocator();
43604311
43614312 // Because these three things each reference each other, `undefined`
43624313 // placeholders are used before being set after the struct type gains an
......@@ -4394,7 +4345,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
43944345 new_namespace.ty = struct_ty.toType();
43954346 file.root_decl = new_decl_index.toOptional();
43964347
4397 new_decl.name = try file.fullyQualifiedNameZ(gpa);
4348 new_decl.name = try file.fullyQualifiedName(mod);
43984349 new_decl.src_line = 0;
43994350 new_decl.is_pub = true;
44004351 new_decl.is_exported = false;
......@@ -4403,7 +4354,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
44034354 new_decl.ty = Type.type;
44044355 new_decl.val = struct_ty.toValue();
44054356 new_decl.@"align" = 0;
4406 new_decl.@"linksection" = null;
4357 new_decl.@"linksection" = .none;
44074358 new_decl.has_tv = true;
44084359 new_decl.owns_tv = true;
44094360 new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive.
......@@ -4431,7 +4382,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
44314382 .mod = mod,
44324383 .gpa = gpa,
44334384 .arena = sema_arena_allocator,
4434 .perm_arena = new_decl_arena_allocator,
44354385 .code = file.zir,
44364386 .owner_decl = new_decl,
44374387 .owner_decl_index = new_decl_index,
......@@ -4484,8 +4434,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
44844434 } else {
44854435 new_decl.analysis = .file_failure;
44864436 }
4487
4488 try new_decl.finalizeNewArena(&new_decl_arena);
44894437}
44904438
44914439/// Returns `true` if the Decl type changed.
......@@ -4507,28 +4455,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45074455
45084456 decl.analysis = .in_progress;
45094457
4510 // We need the memory for the Type to go into the arena for the Decl
4511 var decl_arena = std.heap.ArenaAllocator.init(gpa);
4512 const decl_arena_allocator = decl_arena.allocator();
4513 const decl_value_arena = blk: {
4514 errdefer decl_arena.deinit();
4515 const s = try decl_arena_allocator.create(ValueArena);
4516 s.* = .{ .state = undefined };
4517 break :blk s;
4518 };
4519 defer {
4520 if (decl.value_arena) |value_arena| {
4521 assert(value_arena.state_acquired == null);
4522 decl_value_arena.prev = value_arena;
4523 }
4524
4525 decl_value_arena.state = decl_arena.state;
4526 decl.value_arena = decl_value_arena;
4527 }
4528
45294458 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
45304459 defer analysis_arena.deinit();
4531 const analysis_arena_allocator = analysis_arena.allocator();
45324460
45334461 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
45344462 defer comptime_mutable_decls.deinit();
......@@ -4536,8 +4464,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45364464 var sema: Sema = .{
45374465 .mod = mod,
45384466 .gpa = gpa,
4539 .arena = analysis_arena_allocator,
4540 .perm_arena = decl_arena_allocator,
4467 .arena = analysis_arena.allocator(),
45414468 .code = zir,
45424469 .owner_decl = decl,
45434470 .owner_decl_index = decl_index,
......@@ -4551,7 +4478,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45514478 defer sema.deinit();
45524479
45534480 if (mod.declIsRoot(decl_index)) {
4554 log.debug("semaDecl root {*} ({s})", .{ decl, decl.name });
45554481 const main_struct_inst = Zir.main_struct_inst;
45564482 const struct_index = decl.getOwnedStructIndex(mod).unwrap().?;
45574483 const struct_obj = mod.structPtr(struct_index);
......@@ -4563,7 +4489,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45634489 decl.generation = mod.generation;
45644490 return false;
45654491 }
4566 log.debug("semaDecl {*} ({s})", .{ decl, decl.name });
45674492
45684493 var wip_captures = try WipCaptureScope.init(gpa, decl.src_scope);
45694494 defer wip_captures.deinit();
......@@ -4619,7 +4544,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
46194544 decl.ty = InternPool.Index.type_type.toType();
46204545 decl.val = ty.toValue();
46214546 decl.@"align" = 0;
4622 decl.@"linksection" = null;
4547 decl.@"linksection" = .none;
46234548 decl.has_tv = true;
46244549 decl.owns_tv = false;
46254550 decl.analysis = .complete;
......@@ -4646,7 +4571,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
46464571 decl.clearValues(mod);
46474572
46484573 decl.ty = decl_tv.ty;
4649 decl.val = try decl_tv.val.copy(decl_arena_allocator);
4574 decl.val = (try decl_tv.val.intern(decl_tv.ty, mod)).toValue();
46504575 // linksection, align, and addrspace were already set by Sema
46514576 decl.has_tv = true;
46524577 decl.owns_tv = owns_tv;
......@@ -4660,7 +4585,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
46604585 return sema.fail(&block_scope, export_src, "export of inline function", .{});
46614586 }
46624587 // The scope needs to have the decl in it.
4663 const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
4588 const options: std.builtin.ExportOptions = .{
4589 .name = mod.intern_pool.stringToSlice(decl.name),
4590 };
46644591 try sema.analyzeExport(&block_scope, export_src, options, decl_index);
46654592 }
46664593 return type_changed or is_inline != prev_is_inline;
......@@ -4693,14 +4620,13 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
46934620 .func => {},
46944621
46954622 else => {
4696 log.debug("send global const to linker: {*} ({s})", .{ decl, decl.name });
46974623 queue_linker_work = true;
46984624 },
46994625 },
47004626 }
47014627
47024628 decl.ty = decl_tv.ty;
4703 decl.val = try decl_tv.val.copy(decl_arena_allocator);
4629 decl.val = (try decl_tv.val.intern(decl_tv.ty, mod)).toValue();
47044630 decl.@"align" = blk: {
47054631 const align_ref = decl.zirAlignRef(mod);
47064632 if (align_ref == .none) break :blk 0;
......@@ -4708,14 +4634,15 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
47084634 };
47094635 decl.@"linksection" = blk: {
47104636 const linksection_ref = decl.zirLinksectionRef(mod);
4711 if (linksection_ref == .none) break :blk null;
4637 if (linksection_ref == .none) break :blk .none;
47124638 const bytes = try sema.resolveConstString(&block_scope, section_src, linksection_ref, "linksection must be comptime-known");
47134639 if (mem.indexOfScalar(u8, bytes, 0) != null) {
47144640 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
47154641 } else if (bytes.len == 0) {
47164642 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
47174643 }
4718 break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr;
4644 const section = try mod.intern_pool.getOrPutString(gpa, bytes);
4645 break :blk section.toOptional();
47194646 };
47204647 decl.@"addrspace" = blk: {
47214648 const addrspace_ctx: Sema.AddressSpaceContext = switch (mod.intern_pool.indexToKey(decl_tv.val.toIntern())) {
......@@ -4743,7 +4670,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
47434670 (queue_linker_work and try sema.typeHasRuntimeBits(decl.ty));
47444671
47454672 if (has_runtime_bits) {
4746 log.debug("queue linker work for {*} ({s})", .{ decl, decl.name });
47474673
47484674 // Needed for codegen_decl which will call updateDecl and then the
47494675 // codegen backend wants full access to the Decl Type.
......@@ -4759,7 +4685,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
47594685 if (decl.is_exported) {
47604686 const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) };
47614687 // The scope needs to have the decl in it.
4762 const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) };
4688 const options: std.builtin.ExportOptions = .{
4689 .name = mod.intern_pool.stringToSlice(decl.name),
4690 };
47634691 try sema.analyzeExport(&block_scope, export_src, options, decl_index);
47644692 }
47654693
......@@ -4785,10 +4713,6 @@ pub fn declareDeclDependencyType(mod: *Module, depender_index: Decl.Index, depen
47854713 }
47864714 }
47874715
4788 log.debug("{*} ({s}) depends on {*} ({s})", .{
4789 depender, depender.name, dependee, dependee.name,
4790 });
4791
47924716 if (dependee.deletion_flag) {
47934717 dependee.deletion_flag = false;
47944718 assert(mod.deletion_set.swapRemove(dependee_index));
......@@ -5138,6 +5062,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
51385062 const namespace = mod.namespacePtr(namespace_index);
51395063 const gpa = mod.gpa;
51405064 const zir = namespace.file_scope.zir;
5065 const ip = &mod.intern_pool;
51415066
51425067 // zig fmt: off
51435068 const is_pub = (flags & 0b0001) != 0;
......@@ -5157,31 +5082,31 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
51575082 // Every Decl needs a name.
51585083 var is_named_test = false;
51595084 var kind: Decl.Kind = .named;
5160 const decl_name: [:0]const u8 = switch (decl_name_index) {
5085 const decl_name: InternPool.NullTerminatedString = switch (decl_name_index) {
51615086 0 => name: {
51625087 if (export_bit) {
51635088 const i = iter.usingnamespace_index;
51645089 iter.usingnamespace_index += 1;
51655090 kind = .@"usingnamespace";
5166 break :name try std.fmt.allocPrintZ(gpa, "usingnamespace_{d}", .{i});
5091 break :name try ip.getOrPutStringFmt(gpa, "usingnamespace_{d}", .{i});
51675092 } else {
51685093 const i = iter.comptime_index;
51695094 iter.comptime_index += 1;
51705095 kind = .@"comptime";
5171 break :name try std.fmt.allocPrintZ(gpa, "comptime_{d}", .{i});
5096 break :name try ip.getOrPutStringFmt(gpa, "comptime_{d}", .{i});
51725097 }
51735098 },
51745099 1 => name: {
51755100 const i = iter.unnamed_test_index;
51765101 iter.unnamed_test_index += 1;
51775102 kind = .@"test";
5178 break :name try std.fmt.allocPrintZ(gpa, "test_{d}", .{i});
5103 break :name try ip.getOrPutStringFmt(gpa, "test_{d}", .{i});
51795104 },
51805105 2 => name: {
51815106 is_named_test = true;
51825107 const test_name = zir.nullTerminatedString(decl_doccomment_index);
51835108 kind = .@"test";
5184 break :name try std.fmt.allocPrintZ(gpa, "decltest.{s}", .{test_name});
5109 break :name try ip.getOrPutStringFmt(gpa, "decltest.{s}", .{test_name});
51855110 },
51865111 else => name: {
51875112 const raw_name = zir.nullTerminatedString(decl_name_index);
......@@ -5189,14 +5114,12 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
51895114 is_named_test = true;
51905115 const test_name = zir.nullTerminatedString(decl_name_index + 1);
51915116 kind = .@"test";
5192 break :name try std.fmt.allocPrintZ(gpa, "test.{s}", .{test_name});
5117 break :name try ip.getOrPutStringFmt(gpa, "test.{s}", .{test_name});
51935118 } else {
5194 break :name try gpa.dupeZ(u8, raw_name);
5119 break :name try ip.getOrPutString(gpa, raw_name);
51955120 }
51965121 },
51975122 };
5198 var must_free_decl_name = true;
5199 defer if (must_free_decl_name) gpa.free(decl_name);
52005123
52015124 const is_exported = export_bit and decl_name_index != 0;
52025125 if (kind == .@"usingnamespace") try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);
......@@ -5204,7 +5127,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
52045127 // We create a Decl for it regardless of analysis status.
52055128 const gop = try namespace.decls.getOrPutContextAdapted(
52065129 gpa,
5207 @as([]const u8, mem.sliceTo(decl_name, 0)),
5130 decl_name,
52085131 DeclAdapter{ .mod = mod },
52095132 Namespace.DeclContext{ .module = mod },
52105133 );
......@@ -5214,11 +5137,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
52145137 const new_decl = mod.declPtr(new_decl_index);
52155138 new_decl.kind = kind;
52165139 new_decl.name = decl_name;
5217 must_free_decl_name = false;
52185140 if (kind == .@"usingnamespace") {
52195141 namespace.usingnamespace_set.putAssumeCapacity(new_decl_index, is_pub);
52205142 }
5221 log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace });
52225143 new_decl.src_line = line;
52235144 gop.key_ptr.* = new_decl_index;
52245145 // Exported decls, comptime decls, usingnamespace decls, and
......@@ -5239,7 +5160,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
52395160 if (!comp.bin_file.options.is_test) break :blk false;
52405161 if (decl_pkg != mod.main_pkg) break :blk false;
52415162 if (comp.test_filter) |test_filter| {
5242 if (mem.indexOf(u8, decl_name, test_filter) == null) {
5163 if (mem.indexOf(u8, ip.stringToSlice(decl_name), test_filter) == null) {
52435164 break :blk false;
52445165 }
52455166 }
......@@ -5270,7 +5191,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
52705191 gpa,
52715192 src_loc,
52725193 "duplicate test name: {s}",
5273 .{decl_name},
5194 .{ip.stringToSlice(decl_name)},
52745195 );
52755196 errdefer msg.destroy(gpa);
52765197 try mod.failed_decls.putNoClobber(gpa, decl_index, msg);
......@@ -5281,7 +5202,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
52815202 };
52825203 try mod.errNoteNonLazy(other_src_loc, msg, "other test here", .{});
52835204 }
5284 log.debug("scan existing {*} ({s}) of {*}", .{ decl, decl.name, namespace });
52855205 // Update the AST node of the decl; even if its contents are unchanged, it may
52865206 // have been re-ordered.
52875207 decl.src_node = decl_node;
......@@ -5315,7 +5235,6 @@ pub fn clearDecl(
53155235 defer tracy.end();
53165236
53175237 const decl = mod.declPtr(decl_index);
5318 log.debug("clearing {*} ({s})", .{ decl, decl.name });
53195238
53205239 const gpa = mod.gpa;
53215240 try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count());
......@@ -5330,9 +5249,6 @@ pub fn clearDecl(
53305249 const dep = mod.declPtr(dep_index);
53315250 dep.removeDependant(decl_index);
53325251 if (dep.dependants.count() == 0 and !dep.deletion_flag) {
5333 log.debug("insert {*} ({s}) dependant {*} ({s}) into deletion set", .{
5334 decl, decl.name, dep, dep.name,
5335 });
53365252 // We don't recursively perform a deletion here, because during the update,
53375253 // another reference to it may turn up.
53385254 dep.deletion_flag = true;
......@@ -5387,7 +5303,6 @@ pub fn clearDecl(
53875303/// This function is exclusively called for anonymous decls.
53885304pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void {
53895305 const decl = mod.declPtr(decl_index);
5390 log.debug("deleteUnusedDecl {d} ({s})", .{ decl_index, decl.name });
53915306
53925307 assert(!mod.declIsRoot(decl_index));
53935308 assert(mod.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index));
......@@ -5415,7 +5330,6 @@ fn markDeclForDeletion(mod: *Module, decl_index: Decl.Index) !void {
54155330/// If other decls depend on this decl, they must be aborted first.
54165331pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
54175332 const decl = mod.declPtr(decl_index);
5418 log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name });
54195333
54205334 assert(!mod.declIsRoot(decl_index));
54215335 assert(mod.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index));
......@@ -5468,21 +5382,20 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void
54685382 }
54695383 }
54705384 if (mod.comp.bin_file.cast(link.File.Elf)) |elf| {
5471 elf.deleteDeclExport(decl_index, exp.options.name);
5385 elf.deleteDeclExport(decl_index, exp.name);
54725386 }
54735387 if (mod.comp.bin_file.cast(link.File.MachO)) |macho| {
5474 try macho.deleteDeclExport(decl_index, exp.options.name);
5388 try macho.deleteDeclExport(decl_index, exp.name);
54755389 }
54765390 if (mod.comp.bin_file.cast(link.File.Wasm)) |wasm| {
54775391 wasm.deleteDeclExport(decl_index);
54785392 }
54795393 if (mod.comp.bin_file.cast(link.File.Coff)) |coff| {
5480 coff.deleteDeclExport(decl_index, exp.options.name);
5394 coff.deleteDeclExport(decl_index, exp.name);
54815395 }
54825396 if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| {
54835397 failed_kv.value.destroy(mod.gpa);
54845398 }
5485 mod.gpa.free(exp.options.name);
54865399 mod.gpa.destroy(exp);
54875400 }
54885401 export_owners.deinit(mod.gpa);
......@@ -5497,11 +5410,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
54975410 const decl_index = func.owner_decl;
54985411 const decl = mod.declPtr(decl_index);
54995412
5500 // Use the Decl's arena for captured values.
5501 var decl_arena: std.heap.ArenaAllocator = undefined;
5502 const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
5503 defer decl.value_arena.?.release(&decl_arena);
5504
55055413 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
55065414 defer comptime_mutable_decls.deinit();
55075415
......@@ -5512,7 +5420,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
55125420 .mod = mod,
55135421 .gpa = gpa,
55145422 .arena = arena,
5515 .perm_arena = decl_arena_allocator,
55165423 .code = decl.getFileScope(mod).zir,
55175424 .owner_decl = decl,
55185425 .owner_decl_index = decl_index,
......@@ -5616,7 +5523,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
56165523 }
56175524
56185525 func.state = .in_progress;
5619 log.debug("set {s} to in_progress", .{decl.name});
56205526
56215527 const last_arg_index = inner_block.instructions.items.len;
56225528
......@@ -5677,7 +5583,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
56775583 sema.air_extra.items[@enumToInt(Air.ExtraIndex.main_block)] = main_block_index;
56785584
56795585 func.state = .success;
5680 log.debug("set {s} to success", .{decl.name});
56815586
56825587 // Finally we must resolve the return type and parameter types so that backends
56835588 // have full access to type information.
......@@ -5724,7 +5629,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
57245629
57255630fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {
57265631 const decl = mod.declPtr(decl_index);
5727 log.debug("mark outdated {*} ({s})", .{ decl, decl.name });
57285632 try mod.comp.work_queue.writeItem(.{ .analyze_decl = decl_index });
57295633 if (mod.failed_decls.fetchSwapRemove(decl_index)) |kv| {
57305634 kv.value.destroy(mod.gpa);
......@@ -5821,7 +5725,7 @@ pub fn allocateNewDecl(
58215725 .ty = undefined,
58225726 .val = undefined,
58235727 .@"align" = undefined,
5824 .@"linksection" = undefined,
5728 .@"linksection" = .none,
58255729 .@"addrspace" = .generic,
58265730 .analysis = .unreferenced,
58275731 .deletion_flag = false,
......@@ -5839,25 +5743,20 @@ pub fn allocateNewDecl(
58395743 return decl_and_index.decl_index;
58405744}
58415745
5842/// Get error value for error tag `name`.
5843pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged(ErrorInt).KV {
5746pub fn getErrorValue(
5747 mod: *Module,
5748 name: InternPool.NullTerminatedString,
5749) Allocator.Error!ErrorInt {
58445750 const gop = try mod.global_error_set.getOrPut(mod.gpa, name);
5845 if (gop.found_existing) {
5846 return std.StringHashMapUnmanaged(ErrorInt).KV{
5847 .key = gop.key_ptr.*,
5848 .value = gop.value_ptr.*,
5849 };
5850 }
5751 return @intCast(ErrorInt, gop.index);
5752}
58515753
5852 errdefer assert(mod.global_error_set.remove(name));
5853 try mod.error_name_list.ensureUnusedCapacity(mod.gpa, 1);
5854 gop.key_ptr.* = try mod.gpa.dupe(u8, name);
5855 gop.value_ptr.* = @intCast(ErrorInt, mod.error_name_list.items.len);
5856 mod.error_name_list.appendAssumeCapacity(gop.key_ptr.*);
5857 return std.StringHashMapUnmanaged(ErrorInt).KV{
5858 .key = gop.key_ptr.*,
5859 .value = gop.value_ptr.*,
5860 };
5754pub fn getErrorValueFromSlice(
5755 mod: *Module,
5756 name: []const u8,
5757) Allocator.Error!ErrorInt {
5758 const interned_name = try mod.intern_pool.getOrPutString(mod.gpa, name);
5759 return getErrorValue(mod, interned_name);
58615760}
58625761
58635762pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !Decl.Index {
......@@ -5874,24 +5773,23 @@ pub fn createAnonymousDeclFromDecl(
58745773) !Decl.Index {
58755774 const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope);
58765775 errdefer mod.destroyDecl(new_decl_index);
5877 const name = try std.fmt.allocPrintZ(mod.gpa, "{s}__anon_{d}", .{
5878 src_decl.name, @enumToInt(new_decl_index),
5776 const ip = &mod.intern_pool;
5777 const name = try ip.getOrPutStringFmt(mod.gpa, "{s}__anon_{d}", .{
5778 ip.stringToSlice(src_decl.name), @enumToInt(new_decl_index),
58795779 });
58805780 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, tv, name);
58815781 return new_decl_index;
58825782}
58835783
5884/// Takes ownership of `name` even if it returns an error.
58855784pub fn initNewAnonDecl(
58865785 mod: *Module,
58875786 new_decl_index: Decl.Index,
58885787 src_line: u32,
58895788 namespace: Namespace.Index,
58905789 typed_value: TypedValue,
5891 name: [:0]u8,
5790 name: InternPool.NullTerminatedString,
58925791) Allocator.Error!void {
58935792 assert(typed_value.ty.toIntern() == mod.intern_pool.typeOf(typed_value.val.toIntern()));
5894 errdefer mod.gpa.free(name);
58955793
58965794 const new_decl = mod.declPtr(new_decl_index);
58975795
......@@ -5900,7 +5798,7 @@ pub fn initNewAnonDecl(
59005798 new_decl.ty = typed_value.ty;
59015799 new_decl.val = typed_value.val;
59025800 new_decl.@"align" = 0;
5903 new_decl.@"linksection" = null;
5801 new_decl.@"linksection" = .none;
59045802 new_decl.has_tv = true;
59055803 new_decl.analysis = .complete;
59065804 new_decl.generation = mod.generation;
......@@ -6330,12 +6228,11 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
63306228 // deletion set at this time.
63316229 for (file.deleted_decls.items) |decl_index| {
63326230 const decl = mod.declPtr(decl_index);
6333 log.debug("deleted from source: {*} ({s})", .{ decl, decl.name });
63346231
63356232 // Remove from the namespace it resides in, preserving declaration order.
63366233 assert(decl.zir_decl_index != 0);
63376234 _ = mod.namespacePtr(decl.src_namespace).decls.orderedRemoveAdapted(
6338 @as([]const u8, mem.sliceTo(decl.name, 0)),
6235 decl.name,
63396236 DeclAdapter{ .mod = mod },
63406237 );
63416238
......@@ -6357,7 +6254,7 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
63576254pub fn processExports(mod: *Module) !void {
63586255 const gpa = mod.gpa;
63596256 // Map symbol names to `Export` for name collision detection.
6360 var symbol_exports: std.StringArrayHashMapUnmanaged(*Export) = .{};
6257 var symbol_exports: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, *Export) = .{};
63616258 defer symbol_exports.deinit(gpa);
63626259
63636260 var it = mod.decl_exports.iterator();
......@@ -6365,13 +6262,13 @@ pub fn processExports(mod: *Module) !void {
63656262 const exported_decl = entry.key_ptr.*;
63666263 const exports = entry.value_ptr.items;
63676264 for (exports) |new_export| {
6368 const gop = try symbol_exports.getOrPut(gpa, new_export.options.name);
6265 const gop = try symbol_exports.getOrPut(gpa, new_export.name);
63696266 if (gop.found_existing) {
63706267 new_export.status = .failed_retryable;
63716268 try mod.failed_exports.ensureUnusedCapacity(gpa, 1);
63726269 const src_loc = new_export.getSrcLoc(mod);
63736270 const msg = try ErrorMsg.create(gpa, src_loc, "exported symbol collision: {s}", .{
6374 new_export.options.name,
6271 mod.intern_pool.stringToSlice(new_export.name),
63756272 });
63766273 errdefer msg.destroy(gpa);
63776274 const other_export = gop.value_ptr.*;
......@@ -6408,8 +6305,9 @@ pub fn populateTestFunctions(
64086305 const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file;
64096306 const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?);
64106307 const builtin_namespace = mod.namespacePtr(root_decl.src_namespace);
6308 const test_functions_str = try mod.intern_pool.getOrPutString(gpa, "test_functions");
64116309 const decl_index = builtin_namespace.decls.getKeyAdapted(
6412 @as([]const u8, "test_functions"),
6310 test_functions_str,
64136311 DeclAdapter{ .mod = mod },
64146312 ).?;
64156313 {
......@@ -6443,7 +6341,7 @@ pub fn populateTestFunctions(
64436341
64446342 for (test_fn_vals, mod.test_functions.keys()) |*test_fn_val, test_decl_index| {
64456343 const test_decl = mod.declPtr(test_decl_index);
6446 const test_decl_name = mem.span(test_decl.name);
6344 const test_decl_name = mod.intern_pool.stringToSlice(test_decl.name);
64476345 const test_name_decl_index = n: {
64486346 const test_name_decl_ty = try mod.arrayType(.{
64496347 .len = test_decl_name.len,
......@@ -7156,7 +7054,7 @@ pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc
71567054 return mod.declPtr(opaque_type.decl).srcLoc(mod);
71577055}
71587056
7159pub fn opaqueFullyQualifiedName(mod: *Module, opaque_type: InternPool.Key.OpaqueType) ![:0]u8 {
7057pub fn opaqueFullyQualifiedName(mod: *Module, opaque_type: InternPool.Key.OpaqueType) !InternPool.NullTerminatedString {
71607058 return mod.declPtr(opaque_type.decl).getFullyQualifiedName(mod);
71617059}
71627060
src/Sema.zig+655-549
......@@ -11,9 +11,6 @@ gpa: Allocator,
1111/// Points to the temporary arena allocator of the Sema.
1212/// This arena will be cleared when the sema is destroyed.
1313arena: Allocator,
14/// Points to the arena allocator for the owner_decl.
15/// This arena will persist until the decl is invalidated.
16perm_arena: Allocator,
1714code: Zir,
1815air_instructions: std.MultiArrayList(Air.Inst) = .{},
1916air_extra: std.ArrayListUnmanaged(u32) = .{},
......@@ -740,7 +737,6 @@ pub const Block = struct {
740737 // TODO: migrate Decl alignment to use `InternPool.Alignment`
741738 new_decl.@"align" = @intCast(u32, alignment);
742739 errdefer sema.mod.abortAnonDecl(new_decl_index);
743 try new_decl.finalizeNewArena(&wad.new_decl_arena);
744740 wad.finished = true;
745741 try sema.mod.finalizeAnonDecl(new_decl_index);
746742 return new_decl_index;
......@@ -1825,6 +1821,20 @@ pub fn resolveConstString(
18251821 return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod);
18261822}
18271823
1824pub fn resolveConstStringIntern(
1825 sema: *Sema,
1826 block: *Block,
1827 src: LazySrcLoc,
1828 zir_ref: Zir.Inst.Ref,
1829 reason: []const u8,
1830) !InternPool.NullTerminatedString {
1831 const air_inst = try sema.resolveInst(zir_ref);
1832 const wanted_type = Type.slice_const_u8;
1833 const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
1834 const val = try sema.resolveConstValue(block, src, coerced_inst, reason);
1835 return val.toIpString(wanted_type, sema.mod);
1836}
1837
18281838pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {
18291839 const air_inst = try sema.resolveInst(zir_ref);
18301840 assert(air_inst != .var_args_param_type);
......@@ -1847,11 +1857,13 @@ fn analyzeAsType(
18471857
18481858pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {
18491859 const mod = sema.mod;
1860 const gpa = sema.gpa;
1861 const ip = &mod.intern_pool;
18501862 if (!mod.backendSupportsFeature(.error_return_trace)) return;
18511863
18521864 assert(!block.is_comptime);
18531865 var err_trace_block = block.makeSubBlock();
1854 defer err_trace_block.instructions.deinit(sema.gpa);
1866 defer err_trace_block.instructions.deinit(gpa);
18551867
18561868 const src: LazySrcLoc = .unneeded;
18571869
......@@ -1866,17 +1878,19 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
18661878 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));
18671879
18681880 // st.instruction_addresses = &addrs;
1869 const addr_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, "instruction_addresses", src, true);
1881 const instruction_addresses_field_name = try ip.getOrPutString(gpa, "instruction_addresses");
1882 const addr_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, instruction_addresses_field_name, src, true);
18701883 try sema.storePtr2(&err_trace_block, src, addr_field_ptr, src, addrs_ptr, src, .store);
18711884
18721885 // st.index = 0;
1873 const index_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, "index", src, true);
1886 const index_field_name = try ip.getOrPutString(gpa, "index");
1887 const index_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, index_field_name, src, true);
18741888 try sema.storePtr2(&err_trace_block, src, index_field_ptr, src, .zero_usize, src, .store);
18751889
18761890 // @errorReturnTrace() = &st;
18771891 _ = try err_trace_block.addUnOp(.set_err_return_trace, st_ptr);
18781892
1879 try block.instructions.insertSlice(sema.gpa, last_arg_index, err_trace_block.instructions.items);
1893 try block.instructions.insertSlice(gpa, last_arg_index, err_trace_block.instructions.items);
18801894}
18811895
18821896/// May return Value Tags: `variable`, `undef`.
......@@ -2179,7 +2193,13 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
21792193 return sema.failWithOwnedErrorMsg(msg);
21802194}
21812195
2182fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError {
2196fn failWithInvalidFieldAccess(
2197 sema: *Sema,
2198 block: *Block,
2199 src: LazySrcLoc,
2200 object_ty: Type,
2201 field_name: InternPool.NullTerminatedString,
2202) CompileError {
21832203 const mod = sema.mod;
21842204 const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType(mod) else object_ty;
21852205
......@@ -2207,15 +2227,16 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec
22072227 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
22082228}
22092229
2210fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: []const u8) bool {
2230fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: InternPool.NullTerminatedString) bool {
2231 const ip = &mod.intern_pool;
22112232 switch (ty.zigTypeTag(mod)) {
2212 .Array => return mem.eql(u8, field_name, "len"),
2233 .Array => return ip.stringEqlSlice(field_name, "len"),
22132234 .Pointer => {
22142235 const ptr_info = ty.ptrInfo(mod);
22152236 if (ptr_info.size == .Slice) {
2216 return mem.eql(u8, field_name, "ptr") or mem.eql(u8, field_name, "len");
2237 return ip.stringEqlSlice(field_name, "ptr") or ip.stringEqlSlice(field_name, "len");
22172238 } else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
2218 return mem.eql(u8, field_name, "len");
2239 return ip.stringEqlSlice(field_name, "len");
22192240 } else return false;
22202241 },
22212242 .Type, .Struct, .Union => return true,
......@@ -2308,19 +2329,19 @@ pub fn fail(
23082329fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {
23092330 @setCold(true);
23102331 const gpa = sema.gpa;
2332 const mod = sema.mod;
23112333
2312 if (crash_report.is_enabled and sema.mod.comp.debug_compile_errors) {
2334 if (crash_report.is_enabled and mod.comp.debug_compile_errors) {
23132335 if (err_msg.src_loc.lazy == .unneeded) return error.NeededSourceLocation;
23142336 var wip_errors: std.zig.ErrorBundle.Wip = undefined;
23152337 wip_errors.init(gpa) catch unreachable;
2316 Compilation.addModuleErrorMsg(&wip_errors, err_msg.*) catch unreachable;
2338 Compilation.addModuleErrorMsg(mod, &wip_errors, err_msg.*) catch unreachable;
23172339 std.debug.print("compile error during Sema:\n", .{});
23182340 var error_bundle = wip_errors.toOwnedBundle("") catch unreachable;
23192341 error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
23202342 crash_report.compilerPanic("unexpected compile error occurred", null, null);
23212343 }
23222344
2323 const mod = sema.mod;
23242345 ref: {
23252346 errdefer err_msg.destroy(gpa);
23262347 if (err_msg.src_loc.lazy == .unneeded) {
......@@ -2330,9 +2351,9 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {
23302351 try mod.failed_files.ensureUnusedCapacity(gpa, 1);
23312352
23322353 const max_references = blk: {
2333 if (sema.mod.comp.reference_trace) |num| break :blk num;
2354 if (mod.comp.reference_trace) |num| break :blk num;
23342355 // Do not add multiple traces without explicit request.
2335 if (sema.mod.failed_decls.count() != 0) break :ref;
2356 if (mod.failed_decls.count() != 0) break :ref;
23362357 break :blk default_reference_trace_len;
23372358 };
23382359
......@@ -2350,13 +2371,16 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {
23502371 if (gop.found_existing) break;
23512372 if (cur_reference_trace < max_references) {
23522373 const decl = sema.mod.declPtr(ref.referencer);
2353 try reference_stack.append(.{ .decl = decl.name, .src_loc = ref.src.toSrcLoc(decl, mod) });
2374 try reference_stack.append(.{
2375 .decl = decl.name.toOptional(),
2376 .src_loc = ref.src.toSrcLoc(decl, mod),
2377 });
23542378 }
23552379 referenced_by = ref.referencer;
23562380 }
23572381 if (sema.mod.comp.reference_trace == null and cur_reference_trace > 0) {
23582382 try reference_stack.append(.{
2359 .decl = null,
2383 .decl = .none,
23602384 .src_loc = undefined,
23612385 .hidden = 0,
23622386 });
......@@ -2795,7 +2819,6 @@ fn zirStructDecl(
27952819 new_namespace.ty = struct_ty.toType();
27962820
27972821 try sema.analyzeStructDecl(new_decl, inst, struct_index);
2798 try new_decl.finalizeNewArena(&new_decl_arena);
27992822 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
28002823 try mod.finalizeAnonDecl(new_decl_index);
28012824 return decl_val;
......@@ -2812,6 +2835,7 @@ fn createAnonymousDeclTypeNamed(
28122835) !Decl.Index {
28132836 const mod = sema.mod;
28142837 const gpa = sema.gpa;
2838 const ip = &mod.intern_pool;
28152839 const namespace = block.namespace;
28162840 const src_scope = block.wip_capture_scope;
28172841 const src_decl = mod.declPtr(block.src_decl);
......@@ -2827,16 +2851,19 @@ fn createAnonymousDeclTypeNamed(
28272851 // semantically analyzed.
28282852 // This name is also used as the key in the parent namespace so it cannot be
28292853 // renamed.
2830 const name = try std.fmt.allocPrintZ(gpa, "{s}__{s}_{d}", .{
2831 src_decl.name, anon_prefix, @enumToInt(new_decl_index),
2832 });
2833 errdefer gpa.free(name);
2854
2855 // This ensureUnusedCapacity protects against the src_decl slice from being
2856 // reallocated during the call to `getOrPutStringFmt`.
2857 try ip.string_bytes.ensureUnusedCapacity(gpa, ip.stringToSlice(src_decl.name).len +
2858 anon_prefix.len + 20);
2859 const name = ip.getOrPutStringFmt(gpa, "{s}__{s}_{d}", .{
2860 ip.stringToSlice(src_decl.name), anon_prefix, @enumToInt(new_decl_index),
2861 }) catch unreachable;
28342862 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
28352863 return new_decl_index;
28362864 },
28372865 .parent => {
2838 const name = try gpa.dupeZ(u8, mem.sliceTo(sema.mod.declPtr(block.src_decl).name, 0));
2839 errdefer gpa.free(name);
2866 const name = mod.declPtr(block.src_decl).name;
28402867 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
28412868 return new_decl_index;
28422869 },
......@@ -2846,7 +2873,7 @@ fn createAnonymousDeclTypeNamed(
28462873
28472874 var buf = std.ArrayList(u8).init(gpa);
28482875 defer buf.deinit();
2849 try buf.appendSlice(mem.sliceTo(sema.mod.declPtr(block.src_decl).name, 0));
2876 try buf.appendSlice(ip.stringToSlice(mod.declPtr(block.src_decl).name));
28502877 try buf.appendSlice("(");
28512878
28522879 var arg_i: usize = 0;
......@@ -2871,8 +2898,7 @@ fn createAnonymousDeclTypeNamed(
28712898 };
28722899
28732900 try buf.appendSlice(")");
2874 const name = try buf.toOwnedSliceSentinel(0);
2875 errdefer gpa.free(name);
2901 const name = try ip.getOrPutString(gpa, buf.items);
28762902 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
28772903 return new_decl_index;
28782904 },
......@@ -2885,10 +2911,17 @@ fn createAnonymousDeclTypeNamed(
28852911 .dbg_var_ptr, .dbg_var_val => {
28862912 if (zir_data[i].str_op.operand != ref) continue;
28872913
2888 const name = try std.fmt.allocPrintZ(gpa, "{s}.{s}", .{
2889 src_decl.name, zir_data[i].str_op.getStr(sema.code),
2890 });
2891 errdefer gpa.free(name);
2914 // This ensureUnusedCapacity protects against the src_decl
2915 // slice from being reallocated during the call to
2916 // `getOrPutStringFmt`.
2917 const zir_str = zir_data[i].str_op.getStr(sema.code);
2918 try ip.string_bytes.ensureUnusedCapacity(
2919 gpa,
2920 ip.stringToSlice(src_decl.name).len + zir_str.len + 10,
2921 );
2922 const name = ip.getOrPutStringFmt(gpa, "{s}.{s}", .{
2923 ip.stringToSlice(src_decl.name), zir_str,
2924 }) catch unreachable;
28922925
28932926 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
28942927 return new_decl_index;
......@@ -3249,7 +3282,6 @@ fn zirUnionDecl(
32493282
32503283 _ = try mod.scanNamespace(new_namespace_index, extra_index, decls_len, new_decl);
32513284
3252 try new_decl.finalizeNewArena(&new_decl_arena);
32533285 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
32543286 try mod.finalizeAnonDecl(new_decl_index);
32553287 return decl_val;
......@@ -3315,7 +3347,6 @@ fn zirOpaqueDecl(
33153347
33163348 extra_index = try mod.scanNamespace(new_namespace_index, extra_index, decls_len, new_decl);
33173349
3318 try new_decl.finalizeNewArena(&new_decl_arena);
33193350 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
33203351 try mod.finalizeAnonDecl(new_decl_index);
33213352 return decl_val;
......@@ -3344,8 +3375,8 @@ fn zirErrorSetDecl(
33443375 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
33453376 const str_index = sema.code.extra[extra_index];
33463377 const name = sema.code.nullTerminatedString(str_index);
3347 const kv = try mod.getErrorValue(name);
3348 const name_ip = try mod.intern_pool.getOrPutString(gpa, kv.key);
3378 const name_ip = try mod.intern_pool.getOrPutString(gpa, name);
3379 _ = try mod.getErrorValue(name_ip);
33493380 const result = names.getOrPutAssumeCapacity(name_ip);
33503381 assert(!result.found_existing); // verified in AstGen
33513382 }
......@@ -3512,7 +3543,8 @@ fn indexablePtrLen(
35123543 const is_pointer_to = object_ty.isSinglePointer(mod);
35133544 const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty;
35143545 try checkIndexable(sema, block, src, indexable_ty);
3515 return sema.fieldVal(block, src, object, "len", src);
3546 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "len");
3547 return sema.fieldVal(block, src, object, field_name, src);
35163548}
35173549
35183550fn indexablePtrLenOrNone(
......@@ -3525,7 +3557,8 @@ fn indexablePtrLenOrNone(
35253557 const operand_ty = sema.typeOf(operand);
35263558 try checkMemOperand(sema, block, src, operand_ty);
35273559 if (operand_ty.ptrSize(mod) == .Many) return .none;
3528 return sema.fieldVal(block, src, operand, "len", src);
3560 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "len");
3561 return sema.fieldVal(block, src, operand, field_name, src);
35293562}
35303563
35313564fn zirAllocExtended(
......@@ -4079,6 +4112,7 @@ fn zirFieldBasePtr(
40794112fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
40804113 const mod = sema.mod;
40814114 const gpa = sema.gpa;
4115 const ip = &mod.intern_pool;
40824116 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
40834117 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
40844118 const args = sema.code.refSlice(extra.end, extra.data.operands_len);
......@@ -4122,7 +4156,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
41224156 }
41234157 if (!object_ty.indexableHasLen(mod)) continue;
41244158
4125 break :l try sema.fieldVal(block, arg_src, object, "len", arg_src);
4159 break :l try sema.fieldVal(block, arg_src, object, try ip.getOrPutString(gpa, "len"), arg_src);
41264160 };
41274161 const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src);
41284162 if (len == .none) {
......@@ -4308,6 +4342,7 @@ fn validateUnionInit(
43084342 union_ptr: Air.Inst.Ref,
43094343) CompileError!void {
43104344 const mod = sema.mod;
4345 const gpa = sema.gpa;
43114346
43124347 if (instrs.len != 1) {
43134348 const msg = msg: {
......@@ -4317,7 +4352,7 @@ fn validateUnionInit(
43174352 "cannot initialize multiple union fields at once; unions can only have one active field",
43184353 .{},
43194354 );
4320 errdefer msg.destroy(sema.gpa);
4355 errdefer msg.destroy(gpa);
43214356
43224357 for (instrs[1..]) |inst| {
43234358 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
......@@ -4341,7 +4376,7 @@ fn validateUnionInit(
43414376 const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node;
43424377 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };
43434378 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
4344 const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start);
4379 const field_name = try mod.intern_pool.getOrPutString(gpa, sema.code.nullTerminatedString(field_ptr_extra.field_name_start));
43454380 // Validate the field access but ignore the index since we want the tag enum field index.
43464381 _ = try sema.unionFieldIndex(block, union_ty, field_name, field_src);
43474382 const air_tags = sema.air_instructions.items(.tag);
......@@ -4444,6 +4479,7 @@ fn validateStructInit(
44444479) CompileError!void {
44454480 const mod = sema.mod;
44464481 const gpa = sema.gpa;
4482 const ip = &mod.intern_pool;
44474483
44484484 // Maps field index to field_ptr index of where it was already initialized.
44494485 const found_fields = try gpa.alloc(Zir.Inst.Index, struct_ty.structFieldCount(mod));
......@@ -4457,7 +4493,10 @@ fn validateStructInit(
44574493 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };
44584494 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
44594495 struct_ptr_zir_ref = field_ptr_extra.lhs;
4460 const field_name = sema.code.nullTerminatedString(field_ptr_extra.field_name_start);
4496 const field_name = try ip.getOrPutString(
4497 gpa,
4498 sema.code.nullTerminatedString(field_ptr_extra.field_name_start),
4499 );
44614500 const field_index = if (struct_ty.isTuple(mod))
44624501 try sema.tupleFieldIndex(block, struct_ty, field_name, field_src)
44634502 else
......@@ -4504,7 +4543,7 @@ fn validateStructInit(
45044543 }
45054544 const field_name = struct_ty.structFieldName(i, mod);
45064545 const template = "missing struct field: {s}";
4507 const args = .{field_name};
4546 const args = .{ip.stringToSlice(field_name)};
45084547 if (root_msg) |msg| {
45094548 try sema.errNote(block, init_src, msg, template, args);
45104549 } else {
......@@ -4525,8 +4564,7 @@ fn validateStructInit(
45254564
45264565 if (root_msg) |msg| {
45274566 if (mod.typeToStruct(struct_ty)) |struct_obj| {
4528 const fqn = try struct_obj.getFullyQualifiedName(mod);
4529 defer gpa.free(fqn);
4567 const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
45304568 try mod.errNoteNonLazy(
45314569 struct_obj.srcLoc(mod),
45324570 msg,
......@@ -4649,7 +4687,7 @@ fn validateStructInit(
46494687 }
46504688 const field_name = struct_ty.structFieldName(i, mod);
46514689 const template = "missing struct field: {s}";
4652 const args = .{field_name};
4690 const args = .{ip.stringToSlice(field_name)};
46534691 if (root_msg) |msg| {
46544692 try sema.errNote(block, init_src, msg, template, args);
46554693 } else {
......@@ -4662,10 +4700,9 @@ fn validateStructInit(
46624700
46634701 if (root_msg) |msg| {
46644702 if (mod.typeToStruct(struct_ty)) |struct_obj| {
4665 const fqn = try struct_obj.getFullyQualifiedName(sema.mod);
4666 defer gpa.free(fqn);
4703 const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
46674704 try sema.mod.errNoteNonLazy(
4668 struct_obj.srcLoc(sema.mod),
4705 struct_obj.srcLoc(mod),
46694706 msg,
46704707 "struct '{s}' declared here",
46714708 .{fqn},
......@@ -4949,7 +4986,7 @@ fn failWithBadMemberAccess(
49494986 block: *Block,
49504987 agg_ty: Type,
49514988 field_src: LazySrcLoc,
4952 field_name: []const u8,
4989 field_name_nts: InternPool.NullTerminatedString,
49534990) CompileError {
49544991 const mod = sema.mod;
49554992 const kw_name = switch (agg_ty.zigTypeTag(mod)) {
......@@ -4959,6 +4996,7 @@ fn failWithBadMemberAccess(
49594996 .Enum => "enum",
49604997 else => unreachable,
49614998 };
4999 const field_name = mod.intern_pool.stringToSlice(field_name_nts);
49625000 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (sema.mod.declIsRoot(some)) {
49635001 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{s}'", .{
49645002 agg_ty.fmt(sema.mod), field_name,
......@@ -4980,22 +5018,23 @@ fn failWithBadStructFieldAccess(
49805018 block: *Block,
49815019 struct_obj: *Module.Struct,
49825020 field_src: LazySrcLoc,
4983 field_name: []const u8,
5021 field_name: InternPool.NullTerminatedString,
49845022) CompileError {
5023 const mod = sema.mod;
49855024 const gpa = sema.gpa;
5025 const ip = &mod.intern_pool;
49865026
4987 const fqn = try struct_obj.getFullyQualifiedName(sema.mod);
4988 defer gpa.free(fqn);
5027 const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
49895028
49905029 const msg = msg: {
49915030 const msg = try sema.errMsg(
49925031 block,
49935032 field_src,
49945033 "no field named '{s}' in struct '{s}'",
4995 .{ field_name, fqn },
5034 .{ ip.stringToSlice(field_name), fqn },
49965035 );
49975036 errdefer msg.destroy(gpa);
4998 try sema.mod.errNoteNonLazy(struct_obj.srcLoc(sema.mod), msg, "struct declared here", .{});
5037 try mod.errNoteNonLazy(struct_obj.srcLoc(mod), msg, "struct declared here", .{});
49995038 break :msg msg;
50005039 };
50015040 return sema.failWithOwnedErrorMsg(msg);
......@@ -5006,22 +5045,23 @@ fn failWithBadUnionFieldAccess(
50065045 block: *Block,
50075046 union_obj: *Module.Union,
50085047 field_src: LazySrcLoc,
5009 field_name: []const u8,
5048 field_name: InternPool.NullTerminatedString,
50105049) CompileError {
5050 const mod = sema.mod;
50115051 const gpa = sema.gpa;
5052 const ip = &mod.intern_pool;
50125053
5013 const fqn = try union_obj.getFullyQualifiedName(sema.mod);
5014 defer gpa.free(fqn);
5054 const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod));
50155055
50165056 const msg = msg: {
50175057 const msg = try sema.errMsg(
50185058 block,
50195059 field_src,
50205060 "no field named '{s}' in union '{s}'",
5021 .{ field_name, fqn },
5061 .{ ip.stringToSlice(field_name), fqn },
50225062 );
50235063 errdefer msg.destroy(gpa);
5024 try sema.mod.errNoteNonLazy(union_obj.srcLoc(sema.mod), msg, "union declared here", .{});
5064 try mod.errNoteNonLazy(union_obj.srcLoc(mod), msg, "union declared here", .{});
50255065 break :msg msg;
50265066 };
50275067 return sema.failWithOwnedErrorMsg(msg);
......@@ -5772,7 +5812,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
57725812 const src = inst_data.src();
57735813 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
57745814 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
5775 const decl_name = sema.code.nullTerminatedString(extra.decl_name);
5815 const decl_name = try mod.intern_pool.getOrPutString(mod.gpa, sema.code.nullTerminatedString(extra.decl_name));
57765816 const decl_index = if (extra.namespace != .none) index_blk: {
57775817 const container_ty = try sema.resolveType(block, operand_src, extra.namespace);
57785818 const container_namespace = container_ty.getNamespaceIndex(mod).unwrap().?;
......@@ -5875,19 +5915,14 @@ pub fn analyzeExport(
58755915 const new_export = try gpa.create(Export);
58765916 errdefer gpa.destroy(new_export);
58775917
5878 const symbol_name = try gpa.dupe(u8, borrowed_options.name);
5879 errdefer gpa.free(symbol_name);
5880
5881 const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null;
5882 errdefer if (section) |s| gpa.free(s);
5918 const symbol_name = try mod.intern_pool.getOrPutString(gpa, borrowed_options.name);
5919 const section = try mod.intern_pool.getOrPutStringOpt(gpa, borrowed_options.section);
58835920
58845921 new_export.* = .{
5885 .options = .{
5886 .name = symbol_name,
5887 .linkage = borrowed_options.linkage,
5888 .section = section,
5889 .visibility = borrowed_options.visibility,
5890 },
5922 .name = symbol_name,
5923 .linkage = borrowed_options.linkage,
5924 .section = section,
5925 .visibility = borrowed_options.visibility,
58915926 .src = src,
58925927 .owner_decl = sema.owner_decl_index,
58935928 .src_decl = block.src_decl,
......@@ -6121,23 +6156,25 @@ fn addDbgVar(
61216156}
61226157
61236158fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6159 const mod = sema.mod;
61246160 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
61256161 const src = inst_data.src();
6126 const decl_name = inst_data.get(sema.code);
6162 const decl_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
61276163 const decl_index = try sema.lookupIdentifier(block, src, decl_name);
61286164 try sema.addReferencedBy(block, src, decl_index);
61296165 return sema.analyzeDeclRef(decl_index);
61306166}
61316167
61326168fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6169 const mod = sema.mod;
61336170 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
61346171 const src = inst_data.src();
6135 const decl_name = inst_data.get(sema.code);
6172 const decl_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
61366173 const decl = try sema.lookupIdentifier(block, src, decl_name);
61376174 return sema.analyzeDeclVal(block, src, decl);
61386175}
61396176
6140fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: []const u8) !Decl.Index {
6177fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !Decl.Index {
61416178 const mod = sema.mod;
61426179 var namespace = block.namespace;
61436180 while (true) {
......@@ -6156,7 +6193,7 @@ fn lookupInNamespace(
61566193 block: *Block,
61576194 src: LazySrcLoc,
61586195 namespace_index: Namespace.Index,
6159 ident_name: []const u8,
6196 ident_name: InternPool.NullTerminatedString,
61606197 observe_usingnamespace: bool,
61616198) CompileError!?Decl.Index {
61626199 const mod = sema.mod;
......@@ -6249,9 +6286,6 @@ fn lookupInNamespace(
62496286 return decl_index;
62506287 }
62516288
6252 log.debug("{*} ({s}) depends on non-existence of '{s}' in {*} ({s})", .{
6253 sema.owner_decl, sema.owner_decl.name, ident_name, namespace_decl, namespace_decl.name,
6254 });
62556289 // TODO This dependency is too strong. Really, it should only be a dependency
62566290 // on the non-existence of `ident_name` in the namespace. We can lessen the number of
62576291 // outdated declarations by making this dependency more sophisticated.
......@@ -6276,10 +6310,12 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
62766310}
62776311
62786312pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
6313 const mod = sema.mod;
6314 const gpa = sema.gpa;
62796315 const src = sema.src;
62806316
6281 if (!sema.mod.backendSupportsFeature(.error_return_trace)) return .none;
6282 if (!sema.mod.comp.bin_file.options.error_return_tracing) return .none;
6317 if (!mod.backendSupportsFeature(.error_return_trace)) return .none;
6318 if (!mod.comp.bin_file.options.error_return_tracing) return .none;
62836319
62846320 if (block.is_comptime)
62856321 return .none;
......@@ -6292,7 +6328,8 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
62926328 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
62936329 else => |e| return e,
62946330 };
6295 const field_index = sema.structFieldIndex(block, stack_trace_ty, "index", src) catch |err| switch (err) {
6331 const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
6332 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, src) catch |err| switch (err) {
62966333 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
62976334 else => |e| return e,
62986335 };
......@@ -6316,6 +6353,7 @@ fn popErrorReturnTrace(
63166353 saved_error_trace_index: Air.Inst.Ref,
63176354) CompileError!void {
63186355 const mod = sema.mod;
6356 const gpa = sema.gpa;
63196357 var is_non_error: ?bool = null;
63206358 var is_non_error_inst: Air.Inst.Ref = undefined;
63216359 if (operand != .none) {
......@@ -6332,13 +6370,14 @@ fn popErrorReturnTrace(
63326370 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
63336371 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
63346372 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
6335 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, "index", src, stack_trace_ty, true);
6373 const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
6374 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, field_name, src, stack_trace_ty, true);
63366375 try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);
63376376 } else if (is_non_error == null) {
63386377 // The result might be an error. If it is, we leave the error trace alone. If it isn't, we need
63396378 // to pop any error trace that may have been propagated from our arguments.
63406379
6341 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Block).Struct.fields.len);
6380 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len);
63426381 const cond_block_inst = try block.addInstAsIndex(.{
63436382 .tag = .block,
63446383 .data = .{
......@@ -6350,28 +6389,29 @@ fn popErrorReturnTrace(
63506389 });
63516390
63526391 var then_block = block.makeSubBlock();
6353 defer then_block.instructions.deinit(sema.gpa);
6392 defer then_block.instructions.deinit(gpa);
63546393
63556394 // If non-error, then pop the error return trace by restoring the index.
63566395 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
63576396 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
63586397 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
63596398 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
6360 const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, "index", src, stack_trace_ty, true);
6399 const field_name = try mod.intern_pool.getOrPutString(gpa, "index");
6400 const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, field_name, src, stack_trace_ty, true);
63616401 try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);
63626402 _ = try then_block.addBr(cond_block_inst, Air.Inst.Ref.void_value);
63636403
63646404 // Otherwise, do nothing
63656405 var else_block = block.makeSubBlock();
6366 defer else_block.instructions.deinit(sema.gpa);
6406 defer else_block.instructions.deinit(gpa);
63676407 _ = try else_block.addBr(cond_block_inst, Air.Inst.Ref.void_value);
63686408
6369 try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.CondBr).Struct.fields.len +
6409 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +
63706410 then_block.instructions.items.len + else_block.instructions.items.len +
63716411 @typeInfo(Air.Block).Struct.fields.len + 1); // +1 for the sole .cond_br instruction in the .block
63726412
63736413 const cond_br_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);
6374 try sema.air_instructions.append(sema.gpa, .{ .tag = .cond_br, .data = .{ .pl_op = .{
6414 try sema.air_instructions.append(gpa, .{ .tag = .cond_br, .data = .{ .pl_op = .{
63756415 .operand = is_non_error_inst,
63766416 .payload = sema.addExtraAssumeCapacity(Air.CondBr{
63776417 .then_body_len = @intCast(u32, then_block.instructions.items.len),
......@@ -6414,7 +6454,7 @@ fn zirCall(
64146454 .direct => .{ .direct = try sema.resolveInst(extra.data.callee) },
64156455 .field => blk: {
64166456 const object_ptr = try sema.resolveInst(extra.data.obj_ptr);
6417 const field_name = sema.code.nullTerminatedString(extra.data.field_name_start);
6457 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, sema.code.nullTerminatedString(extra.data.field_name_start));
64186458 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
64196459 break :blk try sema.fieldCallBind(block, callee_src, object_ptr, field_name, field_name_src);
64206460 },
......@@ -6509,7 +6549,8 @@ fn zirCall(
65096549 if (input_is_error or (pop_error_return_trace and modifier != .always_tail and return_ty.isError(mod))) {
65106550 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
65116551 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
6512 const field_index = try sema.structFieldIndex(block, stack_trace_ty, "index", call_src);
6552 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index");
6553 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
65136554
65146555 // Insert a save instruction before the arg resolution + call instructions we just generated
65156556 const save_inst = try block.insertInst(block_index, .{
......@@ -7436,9 +7477,10 @@ fn instantiateGenericCall(
74367477) CompileError!Air.Inst.Ref {
74377478 const mod = sema.mod;
74387479 const gpa = sema.gpa;
7480 const ip = &mod.intern_pool;
74397481
74407482 const func_val = try sema.resolveConstValue(block, func_src, func, "generic function being called must be comptime-known");
7441 const module_fn = mod.funcPtr(switch (mod.intern_pool.indexToKey(func_val.toIntern())) {
7483 const module_fn = mod.funcPtr(switch (ip.indexToKey(func_val.toIntern())) {
74427484 .func => |function| function.index,
74437485 .ptr => |ptr| mod.declPtr(ptr.addr.decl).val.getFunctionIndex(mod).unwrap().?,
74447486 else => unreachable,
......@@ -7567,9 +7609,12 @@ fn instantiateGenericCall(
75677609 const new_decl_index = try mod.allocateNewDecl(namespace_index, fn_owner_decl.src_node, src_decl.src_scope);
75687610 const new_decl = mod.declPtr(new_decl_index);
75697611 // TODO better names for generic function instantiations
7570 const decl_name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{
7571 fn_owner_decl.name, @enumToInt(new_decl_index),
7572 });
7612 // The ensureUnusedCapacity here protects against fn_owner_decl.name slice being
7613 // reallocated during getOrPutStringFmt.
7614 try ip.string_bytes.ensureUnusedCapacity(gpa, ip.stringToSlice(fn_owner_decl.name).len + 20);
7615 const decl_name = ip.getOrPutStringFmt(gpa, "{s}__anon_{d}", .{
7616 ip.stringToSlice(fn_owner_decl.name), @enumToInt(new_decl_index),
7617 }) catch unreachable;
75737618 new_decl.name = decl_name;
75747619 new_decl.src_line = fn_owner_decl.src_line;
75757620 new_decl.is_pub = fn_owner_decl.is_pub;
......@@ -7590,12 +7635,8 @@ fn instantiateGenericCall(
75907635 assert(new_decl.dependencies.keys().len == 0);
75917636 try mod.declareDeclDependencyType(new_decl_index, module_fn.owner_decl, .function_body);
75927637
7593 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
7594 const new_decl_arena_allocator = new_decl_arena.allocator();
7595
75967638 const new_func = sema.resolveGenericInstantiationType(
75977639 block,
7598 new_decl_arena_allocator,
75997640 fn_zir,
76007641 new_decl,
76017642 new_decl_index,
......@@ -7608,7 +7649,6 @@ fn instantiateGenericCall(
76087649 bound_arg_src,
76097650 ) catch |err| switch (err) {
76107651 error.GenericPoison, error.ComptimeReturn => {
7611 new_decl_arena.deinit();
76127652 // Resolving the new function type below will possibly declare more decl dependencies
76137653 // and so we remove them all here in case of error.
76147654 for (new_decl.dependencies.keys()) |dep_index| {
......@@ -7623,10 +7663,6 @@ fn instantiateGenericCall(
76237663 },
76247664 else => {
76257665 assert(mod.monomorphed_funcs.removeContext(new_module_func_index, .{ .mod = mod }));
7626 {
7627 errdefer new_decl_arena.deinit();
7628 try new_decl.finalizeNewArena(&new_decl_arena);
7629 }
76307666 // TODO look up the compile error that happened here and attach a note to it
76317667 // pointing here, at the generic instantiation callsite.
76327668 if (sema.owner_func) |owner_func| {
......@@ -7637,9 +7673,7 @@ fn instantiateGenericCall(
76377673 return err;
76387674 },
76397675 };
7640 errdefer new_decl_arena.deinit();
76417676
7642 try new_decl.finalizeNewArena(&new_decl_arena);
76437677 break :callee new_func;
76447678 } else gop.key_ptr.*;
76457679 const callee = mod.funcPtr(callee_index);
......@@ -7729,7 +7763,6 @@ fn instantiateGenericCall(
77297763fn resolveGenericInstantiationType(
77307764 sema: *Sema,
77317765 block: *Block,
7732 new_decl_arena_allocator: Allocator,
77337766 fn_zir: Zir,
77347767 new_decl: *Decl,
77357768 new_decl_index: Decl.Index,
......@@ -7755,7 +7788,6 @@ fn resolveGenericInstantiationType(
77557788 .mod = mod,
77567789 .gpa = gpa,
77577790 .arena = sema.arena,
7758 .perm_arena = new_decl_arena_allocator,
77597791 .code = fn_zir,
77607792 .owner_decl = new_decl,
77617793 .owner_decl_index = new_decl_index,
......@@ -7764,7 +7796,8 @@ fn resolveGenericInstantiationType(
77647796 .fn_ret_ty = Type.void,
77657797 .owner_func = null,
77667798 .owner_func_index = .none,
7767 .comptime_args = try new_decl_arena_allocator.alloc(TypedValue, uncasted_args.len),
7799 // TODO: fully migrate functions into InternPool
7800 .comptime_args = try mod.tmp_hack_arena.allocator().alloc(TypedValue, uncasted_args.len),
77687801 .comptime_args_fn_inst = module_fn.zir_body_inst,
77697802 .preallocated_new_func = new_module_func.toOptional(),
77707803 .is_generic_instantiation = true,
......@@ -7931,10 +7964,6 @@ fn resolveGenericInstantiationType(
79317964 new_decl.owns_tv = true;
79327965 new_decl.analysis = .complete;
79337966
7934 log.debug("generic function '{s}' instantiated with type {}", .{
7935 new_decl.name, new_decl.ty.fmtDebug(),
7936 });
7937
79387967 // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field
79397968 // will be populated, ensuring it will have `analyzeBody` called with the ZIR
79407969 // parameters mapped appropriately.
......@@ -8134,13 +8163,13 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
81348163 _ = block;
81358164 const mod = sema.mod;
81368165 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
8137 const name = inst_data.get(sema.code);
8166 const name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
8167 _ = try mod.getErrorValue(name);
81388168 // Create an error set type with only this error value, and return the value.
8139 const kv = try sema.mod.getErrorValue(name);
8140 const error_set_type = try mod.singleErrorSetType(kv.key);
8169 const error_set_type = try mod.singleErrorSetTypeNts(name);
81418170 return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
81428171 .ty = error_set_type.toIntern(),
8143 .name = try mod.intern_pool.getOrPutString(sema.gpa, kv.key),
8172 .name = name,
81448173 } })).toValue());
81458174}
81468175
......@@ -8162,7 +8191,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
81628191 const err_name = mod.intern_pool.indexToKey(val.toIntern()).err.name;
81638192 return sema.addConstant(Type.err_int, try mod.intValue(
81648193 Type.err_int,
8165 (try mod.getErrorValue(mod.intern_pool.stringToSlice(err_name))).value,
8194 try mod.getErrorValue(err_name),
81668195 ));
81678196 }
81688197
......@@ -8173,8 +8202,8 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
81738202 switch (names.len) {
81748203 0 => return sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)),
81758204 1 => {
8176 const name = mod.intern_pool.stringToSlice(names[0]);
8177 return sema.addIntUnsigned(Type.err_int, mod.global_error_set.get(name).?);
8205 const int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(names[0]).?);
8206 return sema.addIntUnsigned(Type.err_int, int);
81788207 },
81798208 else => {},
81808209 }
......@@ -8197,11 +8226,11 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
81978226
81988227 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
81998228 const int = try sema.usizeCast(block, operand_src, value.toUnsignedInt(mod));
8200 if (int > sema.mod.global_error_set.count() or int == 0)
8229 if (int > mod.global_error_set.count() or int == 0)
82018230 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
82028231 return sema.addConstant(Type.anyerror, (try mod.intern(.{ .err = .{
82038232 .ty = .anyerror_type,
8204 .name = mod.intern_pool.getString(sema.mod.error_name_list.items[int]).unwrap().?,
8233 .name = mod.global_error_set.keys()[int],
82058234 } })).toValue());
82068235 }
82078236 try sema.requireRuntimeBlock(block, src, operand_src);
......@@ -8917,7 +8946,7 @@ fn handleExternLibName(
89178946const FuncLinkSection = union(enum) {
89188947 generic,
89198948 default,
8920 explicit: []const u8,
8949 explicit: InternPool.NullTerminatedString,
89218950};
89228951
89238952fn funcCommon(
......@@ -9186,9 +9215,9 @@ fn funcCommon(
91869215 };
91879216
91889217 sema.owner_decl.@"linksection" = switch (section) {
9189 .generic => undefined,
9190 .default => null,
9191 .explicit => |section_name| try sema.perm_arena.dupeZ(u8, section_name),
9218 .generic => .none,
9219 .default => .none,
9220 .explicit => |section_name| section_name.toOptional(),
91929221 };
91939222 sema.owner_decl.@"align" = alignment orelse 0;
91949223 sema.owner_decl.@"addrspace" = address_space orelse .generic;
......@@ -9572,11 +9601,12 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
95729601 const tracy = trace(@src());
95739602 defer tracy.end();
95749603
9604 const mod = sema.mod;
95759605 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
95769606 const src = inst_data.src();
95779607 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
95789608 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
9579 const field_name = sema.code.nullTerminatedString(extra.field_name_start);
9609 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, sema.code.nullTerminatedString(extra.field_name_start));
95809610 const object = try sema.resolveInst(extra.lhs);
95819611 return sema.fieldVal(block, src, object, field_name, field_name_src);
95829612}
......@@ -9585,11 +9615,12 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index, initializing: b
95859615 const tracy = trace(@src());
95869616 defer tracy.end();
95879617
9618 const mod = sema.mod;
95889619 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
95899620 const src = inst_data.src();
95909621 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
95919622 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;
9592 const field_name = sema.code.nullTerminatedString(extra.field_name_start);
9623 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, sema.code.nullTerminatedString(extra.field_name_start));
95939624 const object_ptr = try sema.resolveInst(extra.lhs);
95949625 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, initializing);
95959626}
......@@ -9603,7 +9634,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
96039634 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
96049635 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
96059636 const object = try sema.resolveInst(extra.lhs);
9606 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime-known");
9637 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, "field name must be comptime-known");
96079638 return sema.fieldVal(block, src, object, field_name, field_name_src);
96089639}
96099640
......@@ -9616,7 +9647,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
96169647 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
96179648 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
96189649 const object_ptr = try sema.resolveInst(extra.lhs);
9619 const field_name = try sema.resolveConstString(block, field_name_src, extra.field_name, "field name must be comptime-known");
9650 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, "field name must be comptime-known");
96209651 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);
96219652}
96229653
......@@ -10434,6 +10465,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1043410465
1043510466 const mod = sema.mod;
1043610467 const gpa = sema.gpa;
10468 const ip = &mod.intern_pool;
1043710469 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1043810470 const src = inst_data.src();
1043910471 const src_node_offset = inst_data.src_node;
......@@ -10605,7 +10637,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1060510637 i,
1060610638 msg,
1060710639 "unhandled enumeration value: '{s}'",
10608 .{field_name},
10640 .{ip.stringToSlice(field_name)},
1060910641 );
1061010642 }
1061110643 try mod.errNoteNonLazy(
......@@ -10689,7 +10721,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1068910721 errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);
1069010722
1069110723 for (operand_ty.errorSetNames(mod)) |error_name_ip| {
10692 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
10724 const error_name = ip.stringToSlice(error_name_ip);
1069310725 if (!seen_errors.contains(error_name) and special_prong != .@"else") {
1069410726 const msg = maybe_msg orelse blk: {
1069510727 maybe_msg = try sema.errMsg(
......@@ -10758,7 +10790,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1075810790 var names: Module.Fn.InferredErrorSet.NameMap = .{};
1075910791 try names.ensureUnusedCapacity(sema.arena, error_names.len);
1076010792 for (error_names) |error_name_ip| {
10761 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
10793 const error_name = ip.stringToSlice(error_name_ip);
1076210794 if (seen_errors.contains(error_name)) continue;
1076310795
1076410796 names.putAssumeCapacityNoClobber(error_name_ip, {});
......@@ -12062,7 +12094,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1206212094 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1206312095 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
1206412096 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);
12065 const field_name = try sema.resolveConstString(block, name_src, extra.rhs, "field name must be comptime-known");
12097 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, "field name must be comptime-known");
1206612098 const ty = try sema.resolveTypeFields(unresolved_ty);
1206712099 const ip = &mod.intern_pool;
1206812100
......@@ -12070,19 +12102,17 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1207012102 switch (ip.indexToKey(ty.toIntern())) {
1207112103 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
1207212104 .Slice => {
12073 if (mem.eql(u8, field_name, "ptr")) break :hf true;
12074 if (mem.eql(u8, field_name, "len")) break :hf true;
12105 if (ip.stringEqlSlice(field_name, "ptr")) break :hf true;
12106 if (ip.stringEqlSlice(field_name, "len")) break :hf true;
1207512107 break :hf false;
1207612108 },
1207712109 else => {},
1207812110 },
1207912111 .anon_struct_type => |anon_struct| {
1208012112 if (anon_struct.names.len != 0) {
12081 // If the string is not interned, then the field certainly is not present.
12082 const name_interned = ip.getString(field_name).unwrap() orelse break :hf false;
12083 break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names, name_interned) != null;
12113 break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names, field_name) != null;
1208412114 } else {
12085 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch break :hf false;
12115 const field_index = std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10) catch break :hf false;
1208612116 break :hf field_index < ty.structFieldCount(mod);
1208712117 }
1208812118 },
......@@ -12097,11 +12127,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1209712127 break :hf union_obj.fields.contains(field_name);
1209812128 },
1209912129 .enum_type => |enum_type| {
12100 // If the string is not interned, then the field certainly is not present.
12101 const name_interned = ip.getString(field_name).unwrap() orelse break :hf false;
12102 break :hf enum_type.nameIndex(ip, name_interned) != null;
12130 break :hf enum_type.nameIndex(ip, field_name) != null;
1210312131 },
12104 .array_type => break :hf mem.eql(u8, field_name, "len"),
12132 .array_type => break :hf ip.stringEqlSlice(field_name, "len"),
1210512133 else => {},
1210612134 }
1210712135 return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{
......@@ -12123,7 +12151,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1212312151 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1212412152 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
1212512153 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
12126 const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "decl name must be comptime-known");
12154 const decl_name = try sema.resolveConstStringIntern(block, rhs_src, extra.rhs, "decl name must be comptime-known");
1212712155
1212812156 try sema.checkNamespaceType(block, lhs_src, container_type);
1212912157
......@@ -12218,14 +12246,12 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1221812246fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1221912247 const mod = sema.mod;
1222012248 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
12221 const err_name = inst_data.get(sema.code);
12222
12223 // Return the error code from the function.
12224 const kv = try mod.getErrorValue(err_name);
12225 const error_set_type = try mod.singleErrorSetType(kv.key);
12249 const name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
12250 _ = try mod.getErrorValue(name);
12251 const error_set_type = try mod.singleErrorSetTypeNts(name);
1222612252 return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
1222712253 .ty = error_set_type.toIntern(),
12228 .name = mod.intern_pool.getString(kv.key).unwrap().?,
12254 .name = name,
1222912255 } })).toValue());
1223012256}
1223112257
......@@ -15730,12 +15756,7 @@ fn zirThis(
1573015756 return sema.analyzeDeclVal(block, src, this_decl_index);
1573115757}
1573215758
15733fn zirClosureCapture(
15734 sema: *Sema,
15735 block: *Block,
15736 inst: Zir.Inst.Index,
15737) CompileError!void {
15738 // TODO: Compile error when closed over values are modified
15759fn zirClosureCapture(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
1573915760 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1574015761 // Closures are not necessarily constant values. For example, the
1574115762 // code might do something like this:
......@@ -15754,13 +15775,8 @@ fn zirClosureCapture(
1575415775 try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, capture);
1575515776}
1575615777
15757fn zirClosureGet(
15758 sema: *Sema,
15759 block: *Block,
15760 inst: Zir.Inst.Index,
15761) CompileError!Air.Inst.Ref {
15778fn zirClosureGet(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1576215779 const mod = sema.mod;
15763 // TODO CLOSURE: Test this with inline functions
1576415780 const inst_data = sema.code.instructions.items(.data)[inst].inst_node;
1576515781 var scope: *CaptureScope = mod.declPtr(block.src_decl).src_scope.?;
1576615782 // Note: The target closure must be in this scope list.
......@@ -15896,7 +15912,7 @@ fn zirBuiltinSrc(
1589615912 const func_name_val = blk: {
1589715913 var anon_decl = try block.startAnonDecl();
1589815914 defer anon_decl.deinit();
15899 const name = mem.span(fn_owner_decl.name);
15915 const name = mod.intern_pool.stringToSlice(fn_owner_decl.name);
1590015916 const new_decl_ty = try mod.arrayType(.{
1590115917 .len = name.len,
1590215918 .child = .u8_type,
......@@ -15965,6 +15981,7 @@ fn zirBuiltinSrc(
1596515981fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1596615982 const mod = sema.mod;
1596715983 const gpa = sema.gpa;
15984 const ip = &mod.intern_pool;
1596815985 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1596915986 const src = inst_data.src();
1597015987 const ty = try sema.resolveType(block, src, inst_data.operand);
......@@ -15995,7 +16012,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1599516012 block,
1599616013 src,
1599716014 type_info_ty.getNamespaceIndex(mod).unwrap().?,
15998 "Fn",
16015 try ip.getOrPutString(gpa, "Fn"),
1599916016 )).?;
1600016017 try mod.declareDeclDependency(sema.owner_decl_index, fn_info_decl_index);
1600116018 try sema.ensureDeclAnalyzed(fn_info_decl_index);
......@@ -16006,7 +16023,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1600616023 block,
1600716024 src,
1600816025 fn_info_ty.getNamespaceIndex(mod).unwrap().?,
16009 "Param",
16026 try ip.getOrPutString(gpa, "Param"),
1601016027 )).?;
1601116028 try mod.declareDeclDependency(sema.owner_decl_index, param_info_decl_index);
1601216029 try sema.ensureDeclAnalyzed(param_info_decl_index);
......@@ -16018,8 +16035,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1601816035 const info = mod.typeToFunc(ty).?;
1601916036 const param_ty = info.param_types[i];
1602016037 const is_generic = param_ty == .generic_poison_type;
16021 const param_ty_val = try mod.intern_pool.get(gpa, .{ .opt = .{
16022 .ty = try mod.intern_pool.get(gpa, .{ .opt_type = .type_type }),
16038 const param_ty_val = try ip.get(gpa, .{ .opt = .{
16039 .ty = try ip.get(gpa, .{ .opt_type = .type_type }),
1602316040 .val = if (is_generic) .none else param_ty,
1602416041 } });
1602516042
......@@ -16070,7 +16087,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1607016087
1607116088 const info = mod.typeToFunc(ty).?;
1607216089 const ret_ty_opt = try mod.intern(.{ .opt = .{
16073 .ty = try mod.intern_pool.get(gpa, .{ .opt_type = .type_type }),
16090 .ty = try ip.get(gpa, .{ .opt_type = .type_type }),
1607416091 .val = if (info.return_type == .generic_poison_type) .none else info.return_type,
1607516092 } });
1607616093
......@@ -16104,7 +16121,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1610416121 block,
1610516122 src,
1610616123 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16107 "Int",
16124 try ip.getOrPutString(gpa, "Int"),
1610816125 )).?;
1610916126 try mod.declareDeclDependency(sema.owner_decl_index, int_info_decl_index);
1611016127 try sema.ensureDeclAnalyzed(int_info_decl_index);
......@@ -16133,7 +16150,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1613316150 block,
1613416151 src,
1613516152 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16136 "Float",
16153 try ip.getOrPutString(gpa, "Float"),
1613716154 )).?;
1613816155 try mod.declareDeclDependency(sema.owner_decl_index, float_info_decl_index);
1613916156 try sema.ensureDeclAnalyzed(float_info_decl_index);
......@@ -16166,7 +16183,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1616616183 block,
1616716184 src,
1616816185 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,
16169 "Pointer",
16186 try ip.getOrPutString(gpa, "Pointer"),
1617016187 )).?;
1617116188 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
1617216189 try sema.ensureDeclAnalyzed(decl_index);
......@@ -16178,7 +16195,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1617816195 block,
1617916196 src,
1618016197 pointer_ty.getNamespaceIndex(mod).unwrap().?,
16181 "Size",
16198 try ip.getOrPutString(gpa, "Size"),
1618216199 )).?;
1618316200 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
1618416201 try sema.ensureDeclAnalyzed(decl_index);
......@@ -16219,7 +16236,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1621916236 block,
1622016237 src,
1622116238 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16222 "Array",
16239 try ip.getOrPutString(gpa, "Array"),
1622316240 )).?;
1622416241 try mod.declareDeclDependency(sema.owner_decl_index, array_field_ty_decl_index);
1622516242 try sema.ensureDeclAnalyzed(array_field_ty_decl_index);
......@@ -16251,7 +16268,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1625116268 block,
1625216269 src,
1625316270 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16254 "Vector",
16271 try ip.getOrPutString(gpa, "Vector"),
1625516272 )).?;
1625616273 try mod.declareDeclDependency(sema.owner_decl_index, vector_field_ty_decl_index);
1625716274 try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);
......@@ -16281,7 +16298,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1628116298 block,
1628216299 src,
1628316300 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16284 "Optional",
16301 try ip.getOrPutString(gpa, "Optional"),
1628516302 )).?;
1628616303 try mod.declareDeclDependency(sema.owner_decl_index, optional_field_ty_decl_index);
1628716304 try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);
......@@ -16312,7 +16329,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1631216329 block,
1631316330 src,
1631416331 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16315 "Error",
16332 try ip.getOrPutString(gpa, "Error"),
1631616333 )).?;
1631716334 try mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);
1631816335 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
......@@ -16332,7 +16349,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1633216349 const names = ty.errorSetNames(mod);
1633316350 const vals = try sema.arena.alloc(InternPool.Index, names.len);
1633416351 for (vals, names) |*field_val, name_ip| {
16335 const name = mod.intern_pool.stringToSlice(name_ip);
16352 const name = ip.stringToSlice(name_ip);
1633616353 const name_val = v: {
1633716354 var anon_decl = try block.startAnonDecl();
1633816355 defer anon_decl.deinit();
......@@ -16415,7 +16432,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1641516432 block,
1641616433 src,
1641716434 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16418 "ErrorUnion",
16435 try ip.getOrPutString(gpa, "ErrorUnion"),
1641916436 )).?;
1642016437 try mod.declareDeclDependency(sema.owner_decl_index, error_union_field_ty_decl_index);
1642116438 try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index);
......@@ -16440,7 +16457,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1644016457 },
1644116458 .Enum => {
1644216459 // TODO: look into memoizing this result.
16443 const enum_type = mod.intern_pool.indexToKey(ty.toIntern()).enum_type;
16460 const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
1644416461
1644516462 const is_exhaustive = Value.makeBool(enum_type.tag_mode != .nonexhaustive);
1644616463
......@@ -16452,7 +16469,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1645216469 block,
1645316470 src,
1645416471 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16455 "EnumField",
16472 try ip.getOrPutString(gpa, "EnumField"),
1645616473 )).?;
1645716474 try mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);
1645816475 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
......@@ -16462,8 +16479,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1646216479
1646316480 const enum_field_vals = try sema.arena.alloc(InternPool.Index, enum_type.names.len);
1646416481 for (enum_field_vals, 0..) |*field_val, i| {
16465 const name_ip = mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names[i];
16466 const name = mod.intern_pool.stringToSlice(name_ip);
16482 const name_ip = ip.indexToKey(ty.toIntern()).enum_type.names[i];
16483 const name = ip.stringToSlice(name_ip);
1646716484 const name_val = v: {
1646816485 var anon_decl = try block.startAnonDecl();
1646916486 defer anon_decl.deinit();
......@@ -16532,7 +16549,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1653216549 block,
1653316550 src,
1653416551 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16535 "Enum",
16552 try ip.getOrPutString(gpa, "Enum"),
1653616553 )).?;
1653716554 try mod.declareDeclDependency(sema.owner_decl_index, type_enum_ty_decl_index);
1653816555 try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);
......@@ -16570,7 +16587,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1657016587 block,
1657116588 src,
1657216589 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16573 "Union",
16590 try ip.getOrPutString(gpa, "Union"),
1657416591 )).?;
1657516592 try mod.declareDeclDependency(sema.owner_decl_index, type_union_ty_decl_index);
1657616593 try sema.ensureDeclAnalyzed(type_union_ty_decl_index);
......@@ -16583,7 +16600,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1658316600 block,
1658416601 src,
1658516602 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16586 "UnionField",
16603 try ip.getOrPutString(gpa, "UnionField"),
1658716604 )).?;
1658816605 try mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);
1658916606 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
......@@ -16601,7 +16618,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1660116618
1660216619 for (union_field_vals, 0..) |*field_val, i| {
1660316620 const field = union_fields.values()[i];
16604 const name = union_fields.keys()[i];
16621 const name = ip.stringToSlice(union_fields.keys()[i]);
1660516622 const name_val = v: {
1660616623 var anon_decl = try block.startAnonDecl();
1660716624 defer anon_decl.deinit();
......@@ -16682,7 +16699,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1668216699 block,
1668316700 src,
1668416701 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,
16685 "ContainerLayout",
16702 try ip.getOrPutString(gpa, "ContainerLayout"),
1668616703 )).?;
1668716704 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
1668816705 try sema.ensureDeclAnalyzed(decl_index);
......@@ -16721,7 +16738,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1672116738 block,
1672216739 src,
1672316740 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16724 "Struct",
16741 try ip.getOrPutString(gpa, "Struct"),
1672516742 )).?;
1672616743 try mod.declareDeclDependency(sema.owner_decl_index, type_struct_ty_decl_index);
1672716744 try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);
......@@ -16734,7 +16751,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1673416751 block,
1673516752 src,
1673616753 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16737 "StructField",
16754 try ip.getOrPutString(gpa, "StructField"),
1673816755 )).?;
1673916756 try mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);
1674016757 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
......@@ -16749,11 +16766,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1674916766 var struct_field_vals: []InternPool.Index = &.{};
1675016767 defer gpa.free(struct_field_vals);
1675116768 fv: {
16752 const struct_type = switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
16769 const struct_type = switch (ip.indexToKey(struct_ty.toIntern())) {
1675316770 .anon_struct_type => |tuple| {
1675416771 struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);
1675516772 for (struct_field_vals, 0..) |*struct_field_val, i| {
16756 const anon_struct_type = mod.intern_pool.indexToKey(struct_ty.toIntern()).anon_struct_type;
16773 const anon_struct_type = ip.indexToKey(struct_ty.toIntern()).anon_struct_type;
1675716774 const field_ty = anon_struct_type.types[i];
1675816775 const field_val = anon_struct_type.values[i];
1675916776 const name_val = v: {
......@@ -16761,7 +16778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1676116778 defer anon_decl.deinit();
1676216779 const bytes = if (tuple.names.len != 0)
1676316780 // https://github.com/ziglang/zig/issues/15709
16764 @as([]const u8, mod.intern_pool.stringToSlice(tuple.names[i]))
16781 @as([]const u8, ip.stringToSlice(tuple.names[i]))
1676516782 else
1676616783 try std.fmt.allocPrint(sema.arena, "{d}", .{i});
1676716784 const new_decl_ty = try mod.arrayType(.{
......@@ -16815,7 +16832,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1681516832 struct_field_vals,
1681616833 struct_obj.fields.keys(),
1681716834 struct_obj.fields.values(),
16818 ) |*field_val, name, field| {
16835 ) |*field_val, name_nts, field| {
16836 const name = ip.stringToSlice(name_nts);
1681916837 const name_val = v: {
1682016838 var anon_decl = try block.startAnonDecl();
1682116839 defer anon_decl.deinit();
......@@ -16838,10 +16856,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1683816856 } });
1683916857 };
1684016858
16841 const opt_default_val = if (field.default_val.toIntern() == .unreachable_value)
16859 const opt_default_val = if (field.default_val == .none)
1684216860 null
1684316861 else
16844 field.default_val;
16862 field.default_val.toValue();
1684516863 const default_val_ptr = try sema.optRefValue(block, field.ty, opt_default_val);
1684616864 const alignment = field.alignment(mod, layout);
1684716865
......@@ -16908,7 +16926,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1690816926 block,
1690916927 src,
1691016928 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,
16911 "ContainerLayout",
16929 try ip.getOrPutString(gpa, "ContainerLayout"),
1691216930 )).?;
1691316931 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
1691416932 try sema.ensureDeclAnalyzed(decl_index);
......@@ -16945,7 +16963,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1694516963 block,
1694616964 src,
1694716965 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16948 "Opaque",
16966 try ip.getOrPutString(gpa, "Opaque"),
1694916967 )).?;
1695016968 try mod.declareDeclDependency(sema.owner_decl_index, type_opaque_ty_decl_index);
1695116969 try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);
......@@ -16982,6 +17000,8 @@ fn typeInfoDecls(
1698217000 opt_namespace: Module.Namespace.OptionalIndex,
1698317001) CompileError!InternPool.Index {
1698417002 const mod = sema.mod;
17003 const gpa = sema.gpa;
17004
1698517005 var decls_anon_decl = try block.startAnonDecl();
1698617006 defer decls_anon_decl.deinit();
1698717007
......@@ -16990,7 +17010,7 @@ fn typeInfoDecls(
1699017010 block,
1699117011 src,
1699217012 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16993 "Declaration",
17013 try mod.intern_pool.getOrPutString(gpa, "Declaration"),
1699417014 )).?;
1699517015 try mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);
1699617016 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
......@@ -16999,10 +17019,10 @@ fn typeInfoDecls(
1699917019 };
1700017020 try sema.queueFullTypeResolution(declaration_ty);
1700117021
17002 var decl_vals = std.ArrayList(InternPool.Index).init(sema.gpa);
17022 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
1700317023 defer decl_vals.deinit();
1700417024
17005 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(sema.gpa);
17025 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);
1700617026 defer seen_namespaces.deinit();
1700717027
1700817028 if (opt_namespace.unwrap()) |namespace_index| {
......@@ -17061,7 +17081,7 @@ fn typeInfoNamespaceDecls(
1706117081 const name_val = v: {
1706217082 var anon_decl = try block.startAnonDecl();
1706317083 defer anon_decl.deinit();
17064 const name = mem.span(decl.name);
17084 const name = mod.intern_pool.stringToSlice(decl.name);
1706517085 const new_decl_ty = try mod.arrayType(.{
1706617086 .len = name.len,
1706717087 .child = .u8_type,
......@@ -17696,15 +17716,14 @@ fn zirRetErrValue(
1769617716) CompileError!Zir.Inst.Index {
1769717717 const mod = sema.mod;
1769817718 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
17699 const err_name = inst_data.get(sema.code);
17719 const err_name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
17720 _ = try mod.getErrorValue(err_name);
1770017721 const src = inst_data.src();
17701
1770217722 // Return the error code from the function.
17703 const kv = try mod.getErrorValue(err_name);
17704 const error_set_type = try mod.singleErrorSetType(err_name);
17723 const error_set_type = try mod.singleErrorSetTypeNts(err_name);
1770517724 const result_inst = try sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
1770617725 .ty = error_set_type.toIntern(),
17707 .name = try mod.intern_pool.getOrPutString(sema.gpa, kv.key),
17726 .name = err_name,
1770817727 } })).toValue());
1770917728 return sema.analyzeRet(block, result_inst, src);
1771017729}
......@@ -18177,7 +18196,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1817718196 const init_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
1817818197 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
1817918198 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
18180 const field_name = try sema.resolveConstString(block, field_src, extra.field_name, "name of field being initialized must be comptime-known");
18199 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, "name of field being initialized must be comptime-known");
1818118200 const init = try sema.resolveInst(extra.init);
1818218201 return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src);
1818318202}
......@@ -18189,7 +18208,7 @@ fn unionInit(
1818918208 init_src: LazySrcLoc,
1819018209 union_ty: Type,
1819118210 union_ty_src: LazySrcLoc,
18192 field_name: []const u8,
18211 field_name: InternPool.NullTerminatedString,
1819318212 field_src: LazySrcLoc,
1819418213) CompileError!Air.Inst.Ref {
1819518214 const mod = sema.mod;
......@@ -18257,7 +18276,7 @@ fn zirStructInit(
1825718276 const field_type_data = zir_datas[item.data.field_type].pl_node;
1825818277 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };
1825918278 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
18260 const field_name = sema.code.nullTerminatedString(field_type_extra.name_start);
18279 const field_name = try mod.intern_pool.getOrPutString(gpa, sema.code.nullTerminatedString(field_type_extra.name_start));
1826118280 const field_index = if (resolved_ty.isTuple(mod))
1826218281 try sema.tupleFieldIndex(block, resolved_ty, field_name, field_src)
1826318282 else
......@@ -18298,7 +18317,7 @@ fn zirStructInit(
1829818317 const field_type_data = zir_datas[item.data.field_type].pl_node;
1829918318 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };
1830018319 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;
18301 const field_name = sema.code.nullTerminatedString(field_type_extra.name_start);
18320 const field_name = try mod.intern_pool.getOrPutString(gpa, sema.code.nullTerminatedString(field_type_extra.name_start));
1830218321 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
1830318322 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);
1830418323 const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);
......@@ -18347,12 +18366,12 @@ fn finishStructInit(
1834718366 is_ref: bool,
1834818367) CompileError!Air.Inst.Ref {
1834918368 const mod = sema.mod;
18350 const gpa = sema.gpa;
18369 const ip = &mod.intern_pool;
1835118370
1835218371 var root_msg: ?*Module.ErrorMsg = null;
1835318372 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
1835418373
18355 switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
18374 switch (ip.indexToKey(struct_ty.toIntern())) {
1835618375 .anon_struct_type => |anon_struct| {
1835718376 for (anon_struct.types, anon_struct.values, 0..) |field_ty, default_val, i| {
1835818377 if (field_inits[i] != .none) continue;
......@@ -18366,9 +18385,9 @@ fn finishStructInit(
1836618385 root_msg = try sema.errMsg(block, init_src, template, .{i});
1836718386 }
1836818387 } else {
18369 const field_name = mod.intern_pool.stringToSlice(anon_struct.names[i]);
18388 const field_name = anon_struct.names[i];
1837018389 const template = "missing struct field: {s}";
18371 const args = .{field_name};
18390 const args = .{ip.stringToSlice(field_name)};
1837218391 if (root_msg) |msg| {
1837318392 try sema.errNote(block, init_src, msg, template, args);
1837418393 } else {
......@@ -18385,17 +18404,17 @@ fn finishStructInit(
1838518404 for (struct_obj.fields.values(), 0..) |field, i| {
1838618405 if (field_inits[i] != .none) continue;
1838718406
18388 if (field.default_val.toIntern() == .unreachable_value) {
18407 if (field.default_val == .none) {
1838918408 const field_name = struct_obj.fields.keys()[i];
1839018409 const template = "missing struct field: {s}";
18391 const args = .{field_name};
18410 const args = .{ip.stringToSlice(field_name)};
1839218411 if (root_msg) |msg| {
1839318412 try sema.errNote(block, init_src, msg, template, args);
1839418413 } else {
1839518414 root_msg = try sema.errMsg(block, init_src, template, args);
1839618415 }
1839718416 } else {
18398 field_inits[i] = try sema.addConstant(field.ty, field.default_val);
18417 field_inits[i] = try sema.addConstant(field.ty, field.default_val.toValue());
1839918418 }
1840018419 }
1840118420 },
......@@ -18404,10 +18423,9 @@ fn finishStructInit(
1840418423
1840518424 if (root_msg) |msg| {
1840618425 if (mod.typeToStruct(struct_ty)) |struct_obj| {
18407 const fqn = try struct_obj.getFullyQualifiedName(sema.mod);
18408 defer gpa.free(fqn);
18409 try sema.mod.errNoteNonLazy(
18410 struct_obj.srcLoc(sema.mod),
18426 const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
18427 try mod.errNoteNonLazy(
18428 struct_obj.srcLoc(mod),
1841118429 msg,
1841218430 "struct '{s}' declared here",
1841318431 .{fqn},
......@@ -18826,11 +18844,13 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
1882618844 const ty_src = inst_data.src();
1882718845 const field_src = inst_data.src();
1882818846 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);
18829 const field_name = try sema.resolveConstString(block, field_src, extra.field_name, "field name must be comptime-known");
18847 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, "field name must be comptime-known");
1883018848 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);
1883118849}
1883218850
1883318851fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
18852 const mod = sema.mod;
18853 const ip = &mod.intern_pool;
1883418854 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1883518855 const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
1883618856 const ty_src = inst_data.src();
......@@ -18843,7 +18863,8 @@ fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1884318863 error.GenericPoison => return Air.Inst.Ref.generic_poison_type,
1884418864 else => |e| return e,
1884518865 };
18846 const field_name = sema.code.nullTerminatedString(extra.name_start);
18866 const zir_field_name = sema.code.nullTerminatedString(extra.name_start);
18867 const field_name = try ip.getOrPutString(sema.gpa, zir_field_name);
1884718868 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);
1884818869}
1884918870
......@@ -18851,7 +18872,7 @@ fn fieldType(
1885118872 sema: *Sema,
1885218873 block: *Block,
1885318874 aggregate_ty: Type,
18854 field_name: []const u8,
18875 field_name: InternPool.NullTerminatedString,
1885518876 field_src: LazySrcLoc,
1885618877 ty_src: LazySrcLoc,
1885718878) CompileError!Air.Inst.Ref {
......@@ -19050,13 +19071,14 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1905019071 const operand = try sema.resolveInst(inst_data.operand);
1905119072 const operand_ty = sema.typeOf(operand);
1905219073 const mod = sema.mod;
19074 const ip = &mod.intern_pool;
1905319075
1905419076 try sema.resolveTypeLayout(operand_ty);
1905519077 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
1905619078 .EnumLiteral => {
1905719079 const val = try sema.resolveConstValue(block, .unneeded, operand, "");
19058 const tag_name = mod.intern_pool.indexToKey(val.toIntern()).enum_literal;
19059 const bytes = mod.intern_pool.stringToSlice(tag_name);
19080 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
19081 const bytes = ip.stringToSlice(tag_name);
1906019082 return sema.addStrLit(block, bytes);
1906119083 },
1906219084 .Enum => operand_ty,
......@@ -19089,7 +19111,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1908919111 const enum_decl = mod.declPtr(enum_decl_index);
1909019112 const msg = msg: {
1909119113 const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{s}'", .{
19092 val.fmtValue(enum_ty, sema.mod), enum_decl.name,
19114 val.fmtValue(enum_ty, sema.mod), ip.stringToSlice(enum_decl.name),
1909319115 });
1909419116 errdefer msg.destroy(sema.gpa);
1909519117 try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{});
......@@ -19098,7 +19120,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1909819120 return sema.failWithOwnedErrorMsg(msg);
1909919121 };
1910019122 const field_name = enum_ty.enumFieldName(field_index, mod);
19101 return sema.addStrLit(block, field_name);
19123 return sema.addStrLit(block, ip.stringToSlice(field_name));
1910219124 }
1910319125 try sema.requireRuntimeBlock(block, src, operand_src);
1910419126 if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) {
......@@ -19119,6 +19141,7 @@ fn zirReify(
1911919141) CompileError!Air.Inst.Ref {
1912019142 const mod = sema.mod;
1912119143 const gpa = sema.gpa;
19144 const ip = &mod.intern_pool;
1912219145 const name_strategy = @intToEnum(Zir.Inst.NameStrategy, extended.small);
1912319146 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
1912419147 const src = LazySrcLoc.nodeOffset(extra.node);
......@@ -19127,11 +19150,10 @@ fn zirReify(
1912719150 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
1912819151 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
1912919152 const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime-known");
19130 const union_val = mod.intern_pool.indexToKey(val.toIntern()).un;
19153 const union_val = ip.indexToKey(val.toIntern()).un;
1913119154 const target = mod.getTarget();
1913219155 if (try union_val.val.toValue().anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
1913319156 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag.toValue(), mod).?;
19134 const ip = &mod.intern_pool;
1913519157 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
1913619158 .Type => return Air.Inst.Ref.type_type,
1913719159 .Void => return Air.Inst.Ref.void_type,
......@@ -19145,8 +19167,14 @@ fn zirReify(
1914519167 .EnumLiteral => return Air.Inst.Ref.enum_literal_type,
1914619168 .Int => {
1914719169 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19148 const signedness_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("signedness").?);
19149 const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("bits").?);
19170 const signedness_val = try union_val.val.toValue().fieldValue(
19171 mod,
19172 fields.getIndex(try ip.getOrPutString(gpa, "signedness")).?,
19173 );
19174 const bits_val = try union_val.val.toValue().fieldValue(
19175 mod,
19176 fields.getIndex(try ip.getOrPutString(gpa, "bits")).?,
19177 );
1915019178
1915119179 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
1915219180 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
......@@ -19155,8 +19183,12 @@ fn zirReify(
1915519183 },
1915619184 .Vector => {
1915719185 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19158 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);
19159 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
19186 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19187 try ip.getOrPutString(gpa, "len"),
19188 ).?);
19189 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19190 try ip.getOrPutString(gpa, "child"),
19191 ).?);
1916019192
1916119193 const len = @intCast(u32, len_val.toUnsignedInt(mod));
1916219194 const child_ty = child_val.toType();
......@@ -19171,7 +19203,9 @@ fn zirReify(
1917119203 },
1917219204 .Float => {
1917319205 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19174 const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("bits").?);
19206 const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19207 try ip.getOrPutString(gpa, "bits"),
19208 ).?);
1917519209
1917619210 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
1917719211 const ty = switch (bits) {
......@@ -19186,14 +19220,30 @@ fn zirReify(
1918619220 },
1918719221 .Pointer => {
1918819222 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19189 const size_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("size").?);
19190 const is_const_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_const").?);
19191 const is_volatile_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_volatile").?);
19192 const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);
19193 const address_space_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("address_space").?);
19194 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
19195 const is_allowzero_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_allowzero").?);
19196 const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);
19223 const size_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19224 try ip.getOrPutString(gpa, "size"),
19225 ).?);
19226 const is_const_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19227 try ip.getOrPutString(gpa, "is_const"),
19228 ).?);
19229 const is_volatile_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19230 try ip.getOrPutString(gpa, "is_volatile"),
19231 ).?);
19232 const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19233 try ip.getOrPutString(gpa, "alignment"),
19234 ).?);
19235 const address_space_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19236 try ip.getOrPutString(gpa, "address_space"),
19237 ).?);
19238 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19239 try ip.getOrPutString(gpa, "child"),
19240 ).?);
19241 const is_allowzero_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19242 try ip.getOrPutString(gpa, "is_allowzero"),
19243 ).?);
19244 const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19245 try ip.getOrPutString(gpa, "sentinel"),
19246 ).?);
1919719247
1919819248 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
1919919249 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
......@@ -19279,9 +19329,15 @@ fn zirReify(
1927919329 },
1928019330 .Array => {
1928119331 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19282 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);
19283 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
19284 const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);
19332 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19333 try ip.getOrPutString(gpa, "len"),
19334 ).?);
19335 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19336 try ip.getOrPutString(gpa, "child"),
19337 ).?);
19338 const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19339 try ip.getOrPutString(gpa, "sentinel"),
19340 ).?);
1928519341
1928619342 const len = len_val.toUnsignedInt(mod);
1928719343 const child_ty = child_val.toType();
......@@ -19298,7 +19354,9 @@ fn zirReify(
1929819354 },
1929919355 .Optional => {
1930019356 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19301 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);
19357 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19358 try ip.getOrPutString(gpa, "child"),
19359 ).?);
1930219360
1930319361 const child_ty = child_val.toType();
1930419362
......@@ -19307,8 +19365,12 @@ fn zirReify(
1930719365 },
1930819366 .ErrorUnion => {
1930919367 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19310 const error_set_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("error_set").?);
19311 const payload_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("payload").?);
19368 const error_set_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19369 try ip.getOrPutString(gpa, "error_set"),
19370 ).?);
19371 const payload_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19372 try ip.getOrPutString(gpa, "payload"),
19373 ).?);
1931219374
1931319375 const error_set_ty = error_set_val.toType();
1931419376 const payload_ty = payload_val.toType();
......@@ -19330,14 +19392,17 @@ fn zirReify(
1933019392 for (0..len) |i| {
1933119393 const elem_val = try payload_val.elemValue(mod, i);
1933219394 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19333 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19395 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19396 try ip.getOrPutString(gpa, "name"),
19397 ).?);
1933419398
19335 const name_str = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
19336 const kv = try mod.getErrorValue(name_str);
19337 const name_ip = try mod.intern_pool.getOrPutString(gpa, kv.key);
19338 const gop = names.getOrPutAssumeCapacity(name_ip);
19399 const name = try name_val.toIpString(Type.slice_const_u8, mod);
19400 _ = try mod.getErrorValue(name);
19401 const gop = names.getOrPutAssumeCapacity(name);
1933919402 if (gop.found_existing) {
19340 return sema.fail(block, src, "duplicate error '{s}'", .{name_str});
19403 return sema.fail(block, src, "duplicate error '{s}'", .{
19404 ip.stringToSlice(name),
19405 });
1934119406 }
1934219407 }
1934319408
......@@ -19346,11 +19411,21 @@ fn zirReify(
1934619411 },
1934719412 .Struct => {
1934819413 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19349 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);
19350 const backing_integer_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("backing_integer").?);
19351 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
19352 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
19353 const is_tuple_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_tuple").?);
19414 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19415 try ip.getOrPutString(gpa, "layout"),
19416 ).?);
19417 const backing_integer_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19418 try ip.getOrPutString(gpa, "backing_integer"),
19419 ).?);
19420 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19421 try ip.getOrPutString(gpa, "fields"),
19422 ).?);
19423 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19424 try ip.getOrPutString(gpa, "decls"),
19425 ).?);
19426 const is_tuple_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19427 try ip.getOrPutString(gpa, "is_tuple"),
19428 ).?);
1935419429
1935519430 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
1935619431
......@@ -19367,10 +19442,18 @@ fn zirReify(
1936719442 },
1936819443 .Enum => {
1936919444 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19370 const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("tag_type").?);
19371 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
19372 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
19373 const is_exhaustive_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_exhaustive").?);
19445 const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19446 try ip.getOrPutString(gpa, "tag_type"),
19447 ).?);
19448 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19449 try ip.getOrPutString(gpa, "fields"),
19450 ).?);
19451 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19452 try ip.getOrPutString(gpa, "decls"),
19453 ).?);
19454 const is_exhaustive_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19455 try ip.getOrPutString(gpa, "is_exhaustive"),
19456 ).?);
1937419457
1937519458 // Decls
1937619459 if (decls_val.sliceLen(mod) > 0) {
......@@ -19396,7 +19479,7 @@ fn zirReify(
1939619479
1939719480 // Define our empty enum decl
1939819481 const fields_len = @intCast(u32, try sema.usizeCast(block, src, fields_val.sliceLen(mod)));
19399 const incomplete_enum = try mod.intern_pool.getIncompleteEnum(gpa, .{
19482 const incomplete_enum = try ip.getIncompleteEnum(gpa, .{
1940019483 .decl = new_decl_index,
1940119484 .namespace = .none,
1940219485 .fields_len = fields_len,
......@@ -19407,35 +19490,36 @@ fn zirReify(
1940719490 .explicit,
1940819491 .tag_ty = int_tag_ty.toIntern(),
1940919492 });
19410 errdefer mod.intern_pool.remove(incomplete_enum.index);
19493 errdefer ip.remove(incomplete_enum.index);
1941119494
1941219495 new_decl.val = incomplete_enum.index.toValue();
1941319496
1941419497 for (0..fields_len) |field_i| {
1941519498 const elem_val = try fields_val.elemValue(mod, field_i);
1941619499 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19417 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19418 const value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("value").?);
19500 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19501 try ip.getOrPutString(gpa, "name"),
19502 ).?);
19503 const value_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19504 try ip.getOrPutString(gpa, "value"),
19505 ).?);
1941919506
19420 const field_name = try name_val.toAllocatedBytes(
19421 Type.slice_const_u8,
19422 sema.arena,
19423 mod,
19424 );
19425 const field_name_ip = try mod.intern_pool.getOrPutString(gpa, field_name);
19507 const field_name = try name_val.toIpString(Type.slice_const_u8, mod);
1942619508
1942719509 if (!try sema.intFitsInType(value_val, int_tag_ty, null)) {
1942819510 // TODO: better source location
1942919511 return sema.fail(block, src, "field '{s}' with enumeration value '{}' is too large for backing int type '{}'", .{
19430 field_name,
19512 ip.stringToSlice(field_name),
1943119513 value_val.fmtValue(Type.comptime_int, mod),
1943219514 int_tag_ty.fmt(mod),
1943319515 });
1943419516 }
1943519517
19436 if (try incomplete_enum.addFieldName(&mod.intern_pool, gpa, field_name_ip)) |other_index| {
19518 if (try incomplete_enum.addFieldName(ip, gpa, field_name)) |other_index| {
1943719519 const msg = msg: {
19438 const msg = try sema.errMsg(block, src, "duplicate enum field '{s}'", .{field_name});
19520 const msg = try sema.errMsg(block, src, "duplicate enum field '{s}'", .{
19521 ip.stringToSlice(field_name),
19522 });
1943919523 errdefer msg.destroy(gpa);
1944019524 _ = other_index; // TODO: this note is incorrect
1944119525 try sema.errNote(block, src, msg, "other field here", .{});
......@@ -19444,7 +19528,7 @@ fn zirReify(
1944419528 return sema.failWithOwnedErrorMsg(msg);
1944519529 }
1944619530
19447 if (try incomplete_enum.addFieldValue(&mod.intern_pool, gpa, (try mod.getCoerced(value_val, int_tag_ty)).toIntern())) |other| {
19531 if (try incomplete_enum.addFieldValue(ip, gpa, (try mod.getCoerced(value_val, int_tag_ty)).toIntern())) |other| {
1944819532 const msg = msg: {
1944919533 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});
1945019534 errdefer msg.destroy(gpa);
......@@ -19462,7 +19546,9 @@ fn zirReify(
1946219546 },
1946319547 .Opaque => {
1946419548 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19465 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
19549 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19550 try ip.getOrPutString(gpa, "decls"),
19551 ).?);
1946619552
1946719553 // Decls
1946819554 if (decls_val.sliceLen(mod) > 0) {
......@@ -19496,22 +19582,29 @@ fn zirReify(
1949619582 .decl = new_decl_index,
1949719583 .namespace = new_namespace_index,
1949819584 } });
19499 errdefer mod.intern_pool.remove(opaque_ty);
19585 errdefer ip.remove(opaque_ty);
1950019586
1950119587 new_decl.val = opaque_ty.toValue();
1950219588 new_namespace.ty = opaque_ty.toType();
1950319589
19504 try new_decl.finalizeNewArena(&new_decl_arena);
1950519590 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
1950619591 try mod.finalizeAnonDecl(new_decl_index);
1950719592 return decl_val;
1950819593 },
1950919594 .Union => {
1951019595 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19511 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);
19512 const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("tag_type").?);
19513 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);
19514 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);
19596 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19597 try ip.getOrPutString(gpa, "layout"),
19598 ).?);
19599 const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19600 try ip.getOrPutString(gpa, "tag_type"),
19601 ).?);
19602 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19603 try ip.getOrPutString(gpa, "fields"),
19604 ).?);
19605 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19606 try ip.getOrPutString(gpa, "decls"),
19607 ).?);
1951519608
1951619609 // Decls
1951719610 if (decls_val.sliceLen(mod) > 0) {
......@@ -19555,7 +19648,7 @@ fn zirReify(
1955519648 const union_obj = mod.unionPtr(union_index);
1955619649 errdefer mod.destroyUnion(union_index);
1955719650
19558 const union_ty = try mod.intern_pool.get(gpa, .{ .union_type = .{
19651 const union_ty = try ip.get(gpa, .{ .union_type = .{
1955919652 .index = union_index,
1956019653 .runtime_tag = if (!tag_type_val.isNull(mod))
1956119654 .tagged
......@@ -19566,7 +19659,7 @@ fn zirReify(
1956619659 .ReleaseFast, .ReleaseSmall => .none,
1956719660 },
1956819661 } });
19569 errdefer mod.intern_pool.remove(union_ty);
19662 errdefer ip.remove(union_ty);
1957019663
1957119664 new_decl.val = union_ty.toValue();
1957219665 new_namespace.ty = union_ty.toType();
......@@ -19579,7 +19672,7 @@ fn zirReify(
1957919672 if (tag_type_val.optionalValue(mod)) |payload_val| {
1958019673 union_obj.tag_ty = payload_val.toType();
1958119674
19582 const enum_type = switch (mod.intern_pool.indexToKey(union_obj.tag_ty.toIntern())) {
19675 const enum_type = switch (ip.indexToKey(union_obj.tag_ty.toIntern())) {
1958319676 .enum_type => |x| x,
1958419677 else => return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{}),
1958519678 };
......@@ -19597,26 +19690,26 @@ fn zirReify(
1959719690 for (0..fields_len) |i| {
1959819691 const elem_val = try fields_val.elemValue(mod, i);
1959919692 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19600 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19601 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
19602 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);
19603
19604 const field_name = try name_val.toAllocatedBytes(
19605 Type.slice_const_u8,
19606 new_decl_arena_allocator,
19607 mod,
19608 );
19609
19610 const field_name_ip = try mod.intern_pool.getOrPutString(gpa, field_name);
19693 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19694 try ip.getOrPutString(gpa, "name"),
19695 ).?);
19696 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19697 try ip.getOrPutString(gpa, "type"),
19698 ).?);
19699 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19700 try ip.getOrPutString(gpa, "alignment"),
19701 ).?);
19702
19703 const field_name = try name_val.toIpString(Type.slice_const_u8, mod);
1961119704
1961219705 if (enum_field_names.len != 0) {
19613 enum_field_names[i] = field_name_ip;
19706 enum_field_names[i] = field_name;
1961419707 }
1961519708
1961619709 if (explicit_enum_info) |tag_info| {
19617 const enum_index = tag_info.nameIndex(&mod.intern_pool, field_name_ip) orelse {
19710 const enum_index = tag_info.nameIndex(ip, field_name) orelse {
1961819711 const msg = msg: {
19619 const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(mod) });
19712 const msg = try sema.errMsg(block, src, "no field named '{s}' in enum '{}'", .{ ip.stringToSlice(field_name), union_obj.tag_ty.fmt(mod) });
1962019713 errdefer msg.destroy(gpa);
1962119714 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
1962219715 break :msg msg;
......@@ -19632,7 +19725,7 @@ fn zirReify(
1963219725 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
1963319726 if (gop.found_existing) {
1963419727 // TODO: better source location
19635 return sema.fail(block, src, "duplicate union field {s}", .{field_name});
19728 return sema.fail(block, src, "duplicate union field {s}", .{ip.stringToSlice(field_name)});
1963619729 }
1963719730
1963819731 const field_ty = type_val.toType();
......@@ -19688,7 +19781,7 @@ fn zirReify(
1968819781 for (tag_info.names, 0..) |field_name, field_index| {
1968919782 if (explicit_tags_seen[field_index]) continue;
1969019783 try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{
19691 mod.intern_pool.stringToSlice(field_name),
19784 ip.stringToSlice(field_name),
1969219785 });
1969319786 }
1969419787 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
......@@ -19700,19 +19793,30 @@ fn zirReify(
1970019793 union_obj.tag_ty = try sema.generateUnionTagTypeSimple(block, enum_field_names, null);
1970119794 }
1970219795
19703 try new_decl.finalizeNewArena(&new_decl_arena);
1970419796 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
1970519797 try mod.finalizeAnonDecl(new_decl_index);
1970619798 return decl_val;
1970719799 },
1970819800 .Fn => {
1970919801 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19710 const calling_convention_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("calling_convention").?);
19711 const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);
19712 const is_generic_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_generic").?);
19713 const is_var_args_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_var_args").?);
19714 const return_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("return_type").?);
19715 const params_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("params").?);
19802 const calling_convention_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19803 try ip.getOrPutString(gpa, "calling_convention"),
19804 ).?);
19805 const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19806 try ip.getOrPutString(gpa, "alignment"),
19807 ).?);
19808 const is_generic_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19809 try ip.getOrPutString(gpa, "is_generic"),
19810 ).?);
19811 const is_var_args_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19812 try ip.getOrPutString(gpa, "is_var_args"),
19813 ).?);
19814 const return_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19815 try ip.getOrPutString(gpa, "return_type"),
19816 ).?);
19817 const params_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19818 try ip.getOrPutString(gpa, "params"),
19819 ).?);
1971619820
1971719821 const is_generic = is_generic_val.toBool();
1971819822 if (is_generic) {
......@@ -19746,9 +19850,15 @@ fn zirReify(
1974619850 for (param_types, 0..) |*param_type, i| {
1974719851 const elem_val = try params_val.elemValue(mod, i);
1974819852 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19749 const param_is_generic_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_generic").?);
19750 const param_is_noalias_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_noalias").?);
19751 const opt_param_type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
19853 const param_is_generic_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19854 try ip.getOrPutString(gpa, "is_generic"),
19855 ).?);
19856 const param_is_noalias_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19857 try ip.getOrPutString(gpa, "is_noalias"),
19858 ).?);
19859 const opt_param_type_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19860 try ip.getOrPutString(gpa, "type"),
19861 ).?);
1975219862
1975319863 if (param_is_generic_val.toBool()) {
1975419864 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});
......@@ -19801,6 +19911,7 @@ fn reifyStruct(
1980119911) CompileError!Air.Inst.Ref {
1980219912 const mod = sema.mod;
1980319913 const gpa = sema.gpa;
19914 const ip = &mod.intern_pool;
1980419915
1980519916 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
1980619917 errdefer new_decl_arena.deinit();
......@@ -19839,11 +19950,11 @@ fn reifyStruct(
1983919950 const struct_obj = mod.structPtr(struct_index);
1984019951 errdefer mod.destroyStruct(struct_index);
1984119952
19842 const struct_ty = try mod.intern_pool.get(gpa, .{ .struct_type = .{
19953 const struct_ty = try ip.get(gpa, .{ .struct_type = .{
1984319954 .index = struct_index.toOptional(),
1984419955 .namespace = new_namespace_index.toOptional(),
1984519956 } });
19846 errdefer mod.intern_pool.remove(struct_ty);
19957 errdefer ip.remove(struct_ty);
1984719958
1984819959 new_decl.val = struct_ty.toValue();
1984919960 new_namespace.ty = struct_ty.toType();
......@@ -19854,12 +19965,22 @@ fn reifyStruct(
1985419965 var i: usize = 0;
1985519966 while (i < fields_len) : (i += 1) {
1985619967 const elem_val = try fields_val.elemValue(mod, i);
19857 const elem_fields = mod.intern_pool.typeOf(elem_val.toIntern()).toType().structFields(mod);
19858 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);
19859 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);
19860 const default_value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("default_value").?);
19861 const is_comptime_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_comptime").?);
19862 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);
19968 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19969 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19970 try ip.getOrPutString(gpa, "name"),
19971 ).?);
19972 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19973 try ip.getOrPutString(gpa, "type"),
19974 ).?);
19975 const default_value_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19976 try ip.getOrPutString(gpa, "default_value"),
19977 ).?);
19978 const is_comptime_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19979 try ip.getOrPutString(gpa, "is_comptime"),
19980 ).?);
19981 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19982 try ip.getOrPutString(gpa, "alignment"),
19983 ).?);
1986319984
1986419985 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
1986519986 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
......@@ -19874,19 +19995,15 @@ fn reifyStruct(
1987419995 return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{});
1987519996 }
1987619997
19877 const field_name = try name_val.toAllocatedBytes(
19878 Type.slice_const_u8,
19879 new_decl_arena_allocator,
19880 mod,
19881 );
19998 const field_name = try name_val.toIpString(Type.slice_const_u8, mod);
1988219999
1988320000 if (is_tuple) {
19884 const field_index = std.fmt.parseUnsigned(u32, field_name, 10) catch {
20001 const field_index = std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10) catch {
1988520002 return sema.fail(
1988620003 block,
1988720004 src,
1988820005 "tuple cannot have non-numeric field '{s}'",
19889 .{field_name},
20006 .{ip.stringToSlice(field_name)},
1989020007 );
1989120008 };
1989220009
......@@ -19902,16 +20019,16 @@ fn reifyStruct(
1990220019 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
1990320020 if (gop.found_existing) {
1990420021 // TODO: better source location
19905 return sema.fail(block, src, "duplicate struct field {s}", .{field_name});
20022 return sema.fail(block, src, "duplicate struct field {s}", .{ip.stringToSlice(field_name)});
1990620023 }
1990720024
1990820025 const field_ty = type_val.toType();
1990920026 const default_val = if (default_value_val.optionalValue(mod)) |opt_val|
19910 try sema.pointerDeref(block, src, opt_val, try mod.singleConstPtrType(field_ty)) orelse
19911 return sema.failWithNeededComptime(block, src, "struct field default value must be comptime-known")
20027 (try sema.pointerDeref(block, src, opt_val, try mod.singleConstPtrType(field_ty)) orelse
20028 return sema.failWithNeededComptime(block, src, "struct field default value must be comptime-known")).toIntern()
1991220029 else
19913 Value.@"unreachable";
19914 if (is_comptime_val.toBool() and default_val.toIntern() == .unreachable_value) {
20030 .none;
20031 if (is_comptime_val.toBool() and default_val == .none) {
1991520032 return sema.fail(block, src, "comptime field without default initialization value", .{});
1991620033 }
1991720034
......@@ -20000,7 +20117,6 @@ fn reifyStruct(
2000020117 struct_obj.status = .have_layout;
2000120118 }
2000220119
20003 try new_decl.finalizeNewArena(&new_decl_arena);
2000420120 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
2000520121 try mod.finalizeAnonDecl(new_decl_index);
2000620122 return decl_val;
......@@ -20871,7 +20987,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2087120987 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2087220988
2087320989 const ty = try sema.resolveType(block, lhs_src, extra.lhs);
20874 const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs, "name of field must be comptime-known");
20990 const field_name = try sema.resolveConstStringIntern(block, rhs_src, extra.rhs, "name of field must be comptime-known");
2087520991
2087620992 const mod = sema.mod;
2087720993 try sema.resolveTypeLayout(ty);
......@@ -20889,7 +21005,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2088921005 }
2089021006
2089121007 const field_index = if (ty.isTuple(mod)) blk: {
20892 if (mem.eql(u8, field_name, "len")) {
21008 if (mod.intern_pool.stringEqlSlice(field_name, "len")) {
2089321009 return sema.fail(block, src, "no offset available for 'len' field of tuple", .{});
2089421010 }
2089521011 break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src);
......@@ -21351,6 +21467,8 @@ fn resolveExportOptions(
2135121467 zir_ref: Zir.Inst.Ref,
2135221468) CompileError!std.builtin.ExportOptions {
2135321469 const mod = sema.mod;
21470 const gpa = sema.gpa;
21471 const ip = &mod.intern_pool;
2135421472 const export_options_ty = try sema.getBuiltinType("ExportOptions");
2135521473 const air_ref = try sema.resolveInst(zir_ref);
2135621474 const options = try sema.coerce(block, export_options_ty, air_ref, src);
......@@ -21360,16 +21478,16 @@ fn resolveExportOptions(
2136021478 const section_src = sema.maybeOptionsSrc(block, src, "section");
2136121479 const visibility_src = sema.maybeOptionsSrc(block, src, "visibility");
2136221480
21363 const name_operand = try sema.fieldVal(block, src, options, "name", name_src);
21481 const name_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src);
2136421482 const name_val = try sema.resolveConstValue(block, name_src, name_operand, "name of exported value must be comptime-known");
2136521483 const name_ty = Type.slice_const_u8;
2136621484 const name = try name_val.toAllocatedBytes(name_ty, sema.arena, mod);
2136721485
21368 const linkage_operand = try sema.fieldVal(block, src, options, "linkage", linkage_src);
21486 const linkage_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage"), linkage_src);
2136921487 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_operand, "linkage of exported value must be comptime-known");
2137021488 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
2137121489
21372 const section_operand = try sema.fieldVal(block, src, options, "section", section_src);
21490 const section_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "section"), section_src);
2137321491 const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known");
2137421492 const section_ty = Type.slice_const_u8;
2137521493 const section = if (section_opt_val.optionalValue(mod)) |section_val|
......@@ -21377,7 +21495,7 @@ fn resolveExportOptions(
2137721495 else
2137821496 null;
2137921497
21380 const visibility_operand = try sema.fieldVal(block, src, options, "visibility", visibility_src);
21498 const visibility_operand = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "visibility"), visibility_src);
2138121499 const visibility_val = try sema.resolveConstValue(block, visibility_src, visibility_operand, "visibility of exported value must be comptime-known");
2138221500 const visibility = mod.toEnum(std.builtin.SymbolVisibility, visibility_val);
2138321501
......@@ -22217,10 +22335,11 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2221722335 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
2221822336
2221922337 const parent_ty = try sema.resolveType(block, ty_src, extra.parent_type);
22220 const field_name = try sema.resolveConstString(block, name_src, extra.field_name, "field name must be comptime-known");
22338 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.field_name, "field name must be comptime-known");
2222122339 const field_ptr = try sema.resolveInst(extra.field_ptr);
2222222340 const field_ptr_ty = sema.typeOf(field_ptr);
2222322341 const mod = sema.mod;
22342 const ip = &mod.intern_pool;
2222422343
2222522344 if (parent_ty.zigTypeTag(mod) != .Struct and parent_ty.zigTypeTag(mod) != .Union) {
2222622345 return sema.fail(block, ty_src, "expected struct or union type, found '{}'", .{parent_ty.fmt(sema.mod)});
......@@ -22230,7 +22349,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2223022349 const field_index = switch (parent_ty.zigTypeTag(mod)) {
2223122350 .Struct => blk: {
2223222351 if (parent_ty.isTuple(mod)) {
22233 if (mem.eql(u8, field_name, "len")) {
22352 if (ip.stringEqlSlice(field_name, "len")) {
2223422353 return sema.fail(block, src, "cannot get @fieldParentPtr of 'len' field of tuple", .{});
2223522354 }
2223622355 break :blk try sema.tupleFieldIndex(block, parent_ty, field_name, name_src);
......@@ -22276,7 +22395,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2227622395 const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
2227722396
2227822397 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {
22279 const field = switch (mod.intern_pool.indexToKey(field_ptr_val.toIntern())) {
22398 const field = switch (ip.indexToKey(field_ptr_val.toIntern())) {
2228022399 .ptr => |ptr| switch (ptr.addr) {
2228122400 .field => |field| field,
2228222401 else => null,
......@@ -22291,7 +22410,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2229122410 src,
2229222411 "field '{s}' has index '{d}' but pointer value is index '{d}' of struct '{}'",
2229322412 .{
22294 field_name,
22413 ip.stringToSlice(field_name),
2229522414 field_index,
2229622415 field.index,
2229722416 parent_ty.fmt(sema.mod),
......@@ -22807,6 +22926,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2280722926
2280822927fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
2280922928 const mod = sema.mod;
22929 const gpa = sema.gpa;
22930 const ip = &mod.intern_pool;
2281022931 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2281122932 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2281222933 const src = inst_data.src();
......@@ -22824,7 +22945,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2282422945 const dest_elem_ty = dest_ptr_ty.elemType2(mod);
2282522946
2282622947 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {
22827 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, "len", dest_src);
22948 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len"), dest_src);
2282822949 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse
2282922950 break :rs dest_src;
2283022951 const len_u64 = (try len_val.getUnsignedIntAdvanced(mod, sema)).?;
......@@ -23068,11 +23189,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2306823189 if (val.isGenericPoison()) {
2306923190 break :blk FuncLinkSection{ .generic = {} };
2307023191 }
23071 break :blk FuncLinkSection{ .explicit = try val.toAllocatedBytes(ty, sema.arena, sema.mod) };
23192 break :blk FuncLinkSection{ .explicit = try val.toIpString(ty, mod) };
2307223193 } else if (extra.data.bits.has_section_ref) blk: {
2307323194 const section_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
2307423195 extra_index += 1;
23075 const section_name = sema.resolveConstString(block, section_src, section_ref, "linksection must be comptime-known") catch |err| switch (err) {
23196 const section_name = sema.resolveConstStringIntern(block, section_src, section_ref, "linksection must be comptime-known") catch |err| switch (err) {
2307623197 error.GenericPoison => {
2307723198 break :blk FuncLinkSection{ .generic = {} };
2307823199 },
......@@ -23272,6 +23393,8 @@ fn resolvePrefetchOptions(
2327223393 zir_ref: Zir.Inst.Ref,
2327323394) CompileError!std.builtin.PrefetchOptions {
2327423395 const mod = sema.mod;
23396 const gpa = sema.gpa;
23397 const ip = &mod.intern_pool;
2327523398 const options_ty = try sema.getBuiltinType("PrefetchOptions");
2327623399 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2327723400
......@@ -23279,13 +23402,13 @@ fn resolvePrefetchOptions(
2327923402 const locality_src = sema.maybeOptionsSrc(block, src, "locality");
2328023403 const cache_src = sema.maybeOptionsSrc(block, src, "cache");
2328123404
23282 const rw = try sema.fieldVal(block, src, options, "rw", rw_src);
23405 const rw = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "rw"), rw_src);
2328323406 const rw_val = try sema.resolveConstValue(block, rw_src, rw, "prefetch read/write must be comptime-known");
2328423407
23285 const locality = try sema.fieldVal(block, src, options, "locality", locality_src);
23408 const locality = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "locality"), locality_src);
2328623409 const locality_val = try sema.resolveConstValue(block, locality_src, locality, "prefetch locality must be comptime-known");
2328723410
23288 const cache = try sema.fieldVal(block, src, options, "cache", cache_src);
23411 const cache = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "cache"), cache_src);
2328923412 const cache_val = try sema.resolveConstValue(block, cache_src, cache, "prefetch cache must be comptime-known");
2329023413
2329123414 return std.builtin.PrefetchOptions{
......@@ -23336,6 +23459,8 @@ fn resolveExternOptions(
2333623459 zir_ref: Zir.Inst.Ref,
2333723460) CompileError!std.builtin.ExternOptions {
2333823461 const mod = sema.mod;
23462 const gpa = sema.gpa;
23463 const ip = &mod.intern_pool;
2333923464 const options_inst = try sema.resolveInst(zir_ref);
2334023465 const extern_options_ty = try sema.getBuiltinType("ExternOptions");
2334123466 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
......@@ -23345,18 +23470,18 @@ fn resolveExternOptions(
2334523470 const linkage_src = sema.maybeOptionsSrc(block, src, "linkage");
2334623471 const thread_local_src = sema.maybeOptionsSrc(block, src, "thread_local");
2334723472
23348 const name_ref = try sema.fieldVal(block, src, options, "name", name_src);
23473 const name_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "name"), name_src);
2334923474 const name_val = try sema.resolveConstValue(block, name_src, name_ref, "name of the extern symbol must be comptime-known");
2335023475 const name = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
2335123476
23352 const library_name_inst = try sema.fieldVal(block, src, options, "library_name", library_src);
23477 const library_name_inst = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "library_name"), library_src);
2335323478 const library_name_val = try sema.resolveConstValue(block, library_src, library_name_inst, "library in which extern symbol is must be comptime-known");
2335423479
23355 const linkage_ref = try sema.fieldVal(block, src, options, "linkage", linkage_src);
23480 const linkage_ref = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "linkage"), linkage_src);
2335623481 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_ref, "linkage of the extern symbol must be comptime-known");
2335723482 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);
2335823483
23359 const is_thread_local = try sema.fieldVal(block, src, options, "is_thread_local", thread_local_src);
23484 const is_thread_local = try sema.fieldVal(block, src, options, try ip.getOrPutString(gpa, "is_thread_local"), thread_local_src);
2336023485 const is_thread_local_val = try sema.resolveConstValue(block, thread_local_src, is_thread_local, "threadlocality of the extern symbol must be comptime-known");
2336123486
2336223487 const library_name = if (library_name_val.optionalValue(mod)) |payload| blk: {
......@@ -23425,7 +23550,7 @@ fn zirBuiltinExtern(
2342523550 const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node, null);
2342623551 errdefer mod.destroyDecl(new_decl_index);
2342723552 const new_decl = mod.declPtr(new_decl_index);
23428 new_decl.name = try sema.gpa.dupeZ(u8, options.name);
23553 new_decl.name = try mod.intern_pool.getOrPutString(sema.gpa, options.name);
2342923554
2343023555 {
2343123556 const new_var = try mod.intern(.{ .variable = .{
......@@ -23444,7 +23569,7 @@ fn zirBuiltinExtern(
2344423569 new_decl.ty = ty;
2344523570 new_decl.val = new_var.toValue();
2344623571 new_decl.@"align" = 0;
23447 new_decl.@"linksection" = null;
23572 new_decl.@"linksection" = .none;
2344823573 new_decl.has_tv = true;
2344923574 new_decl.analysis = .complete;
2345023575 new_decl.generation = mod.generation;
......@@ -24265,12 +24390,13 @@ fn safetyPanic(
2426524390 panic_id: PanicId,
2426624391) CompileError!void {
2426724392 const mod = sema.mod;
24393 const gpa = sema.gpa;
2426824394 const panic_messages_ty = try sema.getBuiltinType("panic_messages");
2426924395 const msg_decl_index = (try sema.namespaceLookup(
2427024396 block,
2427124397 sema.src,
2427224398 panic_messages_ty.getNamespaceIndex(mod).unwrap().?,
24273 @tagName(panic_id),
24399 try mod.intern_pool.getOrPutString(gpa, @tagName(panic_id)),
2427424400 )).?;
2427524401
2427624402 const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index);
......@@ -24302,14 +24428,13 @@ fn fieldVal(
2430224428 block: *Block,
2430324429 src: LazySrcLoc,
2430424430 object: Air.Inst.Ref,
24305 field_name: []const u8,
24431 field_name: InternPool.NullTerminatedString,
2430624432 field_name_src: LazySrcLoc,
2430724433) CompileError!Air.Inst.Ref {
2430824434 // When editing this function, note that there is corresponding logic to be edited
2430924435 // in `fieldPtr`. This function takes a value and returns a value.
2431024436
2431124437 const mod = sema.mod;
24312 const gpa = sema.gpa;
2431324438 const ip = &mod.intern_pool;
2431424439 const object_src = src; // TODO better source location
2431524440 const object_ty = sema.typeOf(object);
......@@ -24326,12 +24451,12 @@ fn fieldVal(
2432624451
2432724452 switch (inner_ty.zigTypeTag(mod)) {
2432824453 .Array => {
24329 if (mem.eql(u8, field_name, "len")) {
24454 if (ip.stringEqlSlice(field_name, "len")) {
2433024455 return sema.addConstant(
2433124456 Type.usize,
2433224457 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
2433324458 );
24334 } else if (mem.eql(u8, field_name, "ptr") and is_pointer_to) {
24459 } else if (ip.stringEqlSlice(field_name, "ptr") and is_pointer_to) {
2433524460 const ptr_info = object_ty.ptrInfo(mod);
2433624461 const result_ty = try Type.ptr(sema.arena, mod, .{
2433724462 .pointee_type = ptr_info.pointee_type.childType(mod),
......@@ -24352,20 +24477,20 @@ fn fieldVal(
2435224477 block,
2435324478 field_name_src,
2435424479 "no member named '{s}' in '{}'",
24355 .{ field_name, object_ty.fmt(mod) },
24480 .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
2435624481 );
2435724482 }
2435824483 },
2435924484 .Pointer => {
2436024485 const ptr_info = inner_ty.ptrInfo(mod);
2436124486 if (ptr_info.size == .Slice) {
24362 if (mem.eql(u8, field_name, "ptr")) {
24487 if (ip.stringEqlSlice(field_name, "ptr")) {
2436324488 const slice = if (is_pointer_to)
2436424489 try sema.analyzeLoad(block, src, object, object_src)
2436524490 else
2436624491 object;
2436724492 return sema.analyzeSlicePtr(block, object_src, slice, inner_ty);
24368 } else if (mem.eql(u8, field_name, "len")) {
24493 } else if (ip.stringEqlSlice(field_name, "len")) {
2436924494 const slice = if (is_pointer_to)
2437024495 try sema.analyzeLoad(block, src, object, object_src)
2437124496 else
......@@ -24376,7 +24501,7 @@ fn fieldVal(
2437624501 block,
2437724502 field_name_src,
2437824503 "no member named '{s}' in '{}'",
24379 .{ field_name, object_ty.fmt(mod) },
24504 .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
2438024505 );
2438124506 }
2438224507 }
......@@ -24392,13 +24517,12 @@ fn fieldVal(
2439224517
2439324518 switch (try child_type.zigTypeTagOrPoison(mod)) {
2439424519 .ErrorSet => {
24395 const name = try ip.getOrPutString(gpa, field_name);
2439624520 switch (ip.indexToKey(child_type.toIntern())) {
2439724521 .error_set_type => |error_set_type| blk: {
24398 if (error_set_type.nameIndex(ip, name) != null) break :blk;
24522 if (error_set_type.nameIndex(ip, field_name) != null) break :blk;
2439924523 const msg = msg: {
2440024524 const msg = try sema.errMsg(block, src, "no error named '{s}' in '{}'", .{
24401 field_name, child_type.fmt(mod),
24525 ip.stringToSlice(field_name), child_type.fmt(mod),
2440224526 });
2440324527 errdefer msg.destroy(sema.gpa);
2440424528 try sema.addDeclaredHereNote(msg, child_type);
......@@ -24419,10 +24543,10 @@ fn fieldVal(
2441924543 const error_set_type = if (!child_type.isAnyError(mod))
2442024544 child_type
2442124545 else
24422 try mod.singleErrorSetTypeNts(name);
24546 try mod.singleErrorSetTypeNts(field_name);
2442324547 return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
2442424548 .ty = error_set_type.toIntern(),
24425 .name = name,
24549 .name = field_name,
2442624550 } })).toValue());
2442724551 },
2442824552 .Union => {
......@@ -24499,7 +24623,7 @@ fn fieldPtr(
2449924623 block: *Block,
2450024624 src: LazySrcLoc,
2450124625 object_ptr: Air.Inst.Ref,
24502 field_name: []const u8,
24626 field_name: InternPool.NullTerminatedString,
2450324627 field_name_src: LazySrcLoc,
2450424628 initializing: bool,
2450524629) CompileError!Air.Inst.Ref {
......@@ -24507,7 +24631,6 @@ fn fieldPtr(
2450724631 // in `fieldVal`. This function takes a pointer and returns a pointer.
2450824632
2450924633 const mod = sema.mod;
24510 const gpa = sema.gpa;
2451124634 const ip = &mod.intern_pool;
2451224635 const object_ptr_src = src; // TODO better source location
2451324636 const object_ptr_ty = sema.typeOf(object_ptr);
......@@ -24528,7 +24651,7 @@ fn fieldPtr(
2452824651
2452924652 switch (inner_ty.zigTypeTag(mod)) {
2453024653 .Array => {
24531 if (mem.eql(u8, field_name, "len")) {
24654 if (ip.stringEqlSlice(field_name, "len")) {
2453224655 var anon_decl = try block.startAnonDecl();
2453324656 defer anon_decl.deinit();
2453424657 return sema.analyzeDeclRef(try anon_decl.finish(
......@@ -24541,7 +24664,7 @@ fn fieldPtr(
2454124664 block,
2454224665 field_name_src,
2454324666 "no member named '{s}' in '{}'",
24544 .{ field_name, object_ty.fmt(mod) },
24667 .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
2454524668 );
2454624669 }
2454724670 },
......@@ -24553,7 +24676,7 @@ fn fieldPtr(
2455324676
2455424677 const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty;
2455524678
24556 if (mem.eql(u8, field_name, "ptr")) {
24679 if (ip.stringEqlSlice(field_name, "ptr")) {
2455724680 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2455824681
2455924682 const result_ty = try Type.ptr(sema.arena, mod, .{
......@@ -24575,7 +24698,7 @@ fn fieldPtr(
2457524698 try sema.requireRuntimeBlock(block, src, null);
2457624699
2457724700 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);
24578 } else if (mem.eql(u8, field_name, "len")) {
24701 } else if (ip.stringEqlSlice(field_name, "len")) {
2457924702 const result_ty = try Type.ptr(sema.arena, mod, .{
2458024703 .pointee_type = Type.usize,
2458124704 .mutable = attr_ptr_ty.ptrIsMutable(mod),
......@@ -24600,7 +24723,7 @@ fn fieldPtr(
2460024723 block,
2460124724 field_name_src,
2460224725 "no member named '{s}' in '{}'",
24603 .{ field_name, object_ty.fmt(mod) },
24726 .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
2460424727 );
2460524728 }
2460624729 },
......@@ -24617,14 +24740,13 @@ fn fieldPtr(
2461724740
2461824741 switch (child_type.zigTypeTag(mod)) {
2461924742 .ErrorSet => {
24620 const name = try ip.getOrPutString(gpa, field_name);
2462124743 switch (ip.indexToKey(child_type.toIntern())) {
2462224744 .error_set_type => |error_set_type| blk: {
24623 if (error_set_type.nameIndex(ip, name) != null) {
24745 if (error_set_type.nameIndex(ip, field_name) != null) {
2462424746 break :blk;
2462524747 }
2462624748 return sema.fail(block, src, "no error named '{s}' in '{}'", .{
24627 field_name, child_type.fmt(mod),
24749 ip.stringToSlice(field_name), child_type.fmt(mod),
2462824750 });
2462924751 },
2463024752 .inferred_error_set_type => {
......@@ -24642,12 +24764,12 @@ fn fieldPtr(
2464224764 const error_set_type = if (!child_type.isAnyError(mod))
2464324765 child_type
2464424766 else
24645 try mod.singleErrorSetTypeNts(name);
24767 try mod.singleErrorSetTypeNts(field_name);
2464624768 return sema.analyzeDeclRef(try anon_decl.finish(
2464724769 error_set_type,
2464824770 (try mod.intern(.{ .err = .{
2464924771 .ty = error_set_type.toIntern(),
24650 .name = name,
24772 .name = field_name,
2465124773 } })).toValue(),
2465224774 0, // default alignment
2465324775 ));
......@@ -24736,13 +24858,14 @@ fn fieldCallBind(
2473624858 block: *Block,
2473724859 src: LazySrcLoc,
2473824860 raw_ptr: Air.Inst.Ref,
24739 field_name: []const u8,
24861 field_name: InternPool.NullTerminatedString,
2474024862 field_name_src: LazySrcLoc,
2474124863) CompileError!ResolvedFieldCallee {
2474224864 // When editing this function, note that there is corresponding logic to be edited
2474324865 // in `fieldVal`. This function takes a pointer and returns a pointer.
2474424866
2474524867 const mod = sema.mod;
24868 const ip = &mod.intern_pool;
2474624869 const raw_ptr_src = src; // TODO better source location
2474724870 const raw_ptr_ty = sema.typeOf(raw_ptr);
2474824871 const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C))
......@@ -24771,18 +24894,18 @@ fn fieldCallBind(
2477124894
2477224895 return sema.finishFieldCallBind(block, src, ptr_ty, field.ty, field_index, object_ptr);
2477324896 } else if (struct_ty.isTuple(mod)) {
24774 if (mem.eql(u8, field_name, "len")) {
24897 if (ip.stringEqlSlice(field_name, "len")) {
2477524898 return .{ .direct = try sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount(mod)) };
2477624899 }
24777 if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| {
24900 if (std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10)) |field_index| {
2477824901 if (field_index >= struct_ty.structFieldCount(mod)) break :find_field;
2477924902 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(field_index, mod), field_index, object_ptr);
2478024903 } else |_| {}
2478124904 } else {
2478224905 const max = struct_ty.structFieldCount(mod);
24783 var i: u32 = 0;
24784 while (i < max) : (i += 1) {
24785 if (mem.eql(u8, struct_ty.structFieldName(i, mod), field_name)) {
24906 for (0..max) |i_usize| {
24907 const i = @intCast(u32, i_usize);
24908 if (field_name == struct_ty.structFieldName(i, mod)) {
2478624909 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(i, mod), i, object_ptr);
2478724910 }
2478824911 }
......@@ -24876,12 +24999,12 @@ fn fieldCallBind(
2487624999 };
2487725000
2487825001 const msg = msg: {
24879 const msg = try sema.errMsg(block, src, "no field or member function named '{s}' in '{}'", .{ field_name, concrete_ty.fmt(mod) });
25002 const msg = try sema.errMsg(block, src, "no field or member function named '{s}' in '{}'", .{ ip.stringToSlice(field_name), concrete_ty.fmt(mod) });
2488025003 errdefer msg.destroy(sema.gpa);
2488125004 try sema.addDeclaredHereNote(msg, concrete_ty);
2488225005 if (found_decl) |decl_idx| {
2488325006 const decl = mod.declPtr(decl_idx);
24884 try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "'{s}' is not a member function", .{field_name});
25007 try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "'{s}' is not a member function", .{ip.stringToSlice(field_name)});
2488525008 }
2488625009 break :msg msg;
2488725010 };
......@@ -24933,7 +25056,7 @@ fn namespaceLookup(
2493325056 block: *Block,
2493425057 src: LazySrcLoc,
2493525058 namespace: Namespace.Index,
24936 decl_name: []const u8,
25059 decl_name: InternPool.NullTerminatedString,
2493725060) CompileError!?Decl.Index {
2493825061 const mod = sema.mod;
2493925062 const gpa = sema.gpa;
......@@ -24942,7 +25065,7 @@ fn namespaceLookup(
2494225065 if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) {
2494325066 const msg = msg: {
2494425067 const msg = try sema.errMsg(block, src, "'{s}' is not marked 'pub'", .{
24945 decl_name,
25068 mod.intern_pool.stringToSlice(decl_name),
2494625069 });
2494725070 errdefer msg.destroy(gpa);
2494825071 try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "declared here", .{});
......@@ -24960,7 +25083,7 @@ fn namespaceLookupRef(
2496025083 block: *Block,
2496125084 src: LazySrcLoc,
2496225085 namespace: Namespace.Index,
24963 decl_name: []const u8,
25086 decl_name: InternPool.NullTerminatedString,
2496425087) CompileError!?Air.Inst.Ref {
2496525088 const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null;
2496625089 try sema.addReferencedBy(block, src, decl);
......@@ -24972,7 +25095,7 @@ fn namespaceLookupVal(
2497225095 block: *Block,
2497325096 src: LazySrcLoc,
2497425097 namespace: Namespace.Index,
24975 decl_name: []const u8,
25098 decl_name: InternPool.NullTerminatedString,
2497625099) CompileError!?Air.Inst.Ref {
2497725100 const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null;
2497825101 return try sema.analyzeDeclVal(block, src, decl);
......@@ -24983,7 +25106,7 @@ fn structFieldPtr(
2498325106 block: *Block,
2498425107 src: LazySrcLoc,
2498525108 struct_ptr: Air.Inst.Ref,
24986 field_name: []const u8,
25109 field_name: InternPool.NullTerminatedString,
2498725110 field_name_src: LazySrcLoc,
2498825111 unresolved_struct_ty: Type,
2498925112 initializing: bool,
......@@ -24995,7 +25118,7 @@ fn structFieldPtr(
2499525118 try sema.resolveStructLayout(struct_ty);
2499625119
2499725120 if (struct_ty.isTuple(mod)) {
24998 if (mem.eql(u8, field_name, "len")) {
25121 if (mod.intern_pool.stringEqlSlice(field_name, "len")) {
2499925122 const len_inst = try sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount(mod));
2500025123 return sema.analyzeRef(block, src, len_inst);
2500125124 }
......@@ -25101,7 +25224,7 @@ fn structFieldPtrByIndex(
2510125224 if (field.is_comptime) {
2510225225 const val = try mod.intern(.{ .ptr = .{
2510325226 .ty = ptr_field_ty.toIntern(),
25104 .addr = .{ .comptime_field = try field.default_val.intern(field.ty, mod) },
25227 .addr = .{ .comptime_field = field.default_val },
2510525228 } });
2510625229 return sema.addConstant(ptr_field_ty, val.toValue());
2510725230 }
......@@ -25126,7 +25249,7 @@ fn structFieldVal(
2512625249 block: *Block,
2512725250 src: LazySrcLoc,
2512825251 struct_byval: Air.Inst.Ref,
25129 field_name: []const u8,
25252 field_name: InternPool.NullTerminatedString,
2513025253 field_name_src: LazySrcLoc,
2513125254 unresolved_struct_ty: Type,
2513225255) CompileError!Air.Inst.Ref {
......@@ -25145,7 +25268,7 @@ fn structFieldVal(
2514525268 const field = struct_obj.fields.values()[field_index];
2514625269
2514725270 if (field.is_comptime) {
25148 return sema.addConstant(field.ty, field.default_val);
25271 return sema.addConstant(field.ty, field.default_val.toValue());
2514925272 }
2515025273
2515125274 if (try sema.resolveMaybeUndefVal(struct_byval)) |struct_val| {
......@@ -25176,12 +25299,12 @@ fn tupleFieldVal(
2517625299 block: *Block,
2517725300 src: LazySrcLoc,
2517825301 tuple_byval: Air.Inst.Ref,
25179 field_name: []const u8,
25302 field_name: InternPool.NullTerminatedString,
2518025303 field_name_src: LazySrcLoc,
2518125304 tuple_ty: Type,
2518225305) CompileError!Air.Inst.Ref {
2518325306 const mod = sema.mod;
25184 if (mem.eql(u8, field_name, "len")) {
25307 if (mod.intern_pool.stringEqlSlice(field_name, "len")) {
2518525308 return sema.addIntUnsigned(Type.usize, tuple_ty.structFieldCount(mod));
2518625309 }
2518725310 const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src);
......@@ -25193,11 +25316,12 @@ fn tupleFieldIndex(
2519325316 sema: *Sema,
2519425317 block: *Block,
2519525318 tuple_ty: Type,
25196 field_name: []const u8,
25319 field_name_ip: InternPool.NullTerminatedString,
2519725320 field_name_src: LazySrcLoc,
2519825321) CompileError!u32 {
2519925322 const mod = sema.mod;
25200 assert(!mem.eql(u8, field_name, "len"));
25323 const field_name = mod.intern_pool.stringToSlice(field_name_ip);
25324 assert(!std.mem.eql(u8, field_name, "len"));
2520125325 if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| {
2520225326 if (field_index < tuple_ty.structFieldCount(mod)) return field_index;
2520325327 return sema.fail(block, field_name_src, "index '{s}' out of bounds of tuple '{}'", .{
......@@ -25253,13 +25377,14 @@ fn unionFieldPtr(
2525325377 block: *Block,
2525425378 src: LazySrcLoc,
2525525379 union_ptr: Air.Inst.Ref,
25256 field_name: []const u8,
25380 field_name: InternPool.NullTerminatedString,
2525725381 field_name_src: LazySrcLoc,
2525825382 unresolved_union_ty: Type,
2525925383 initializing: bool,
2526025384) CompileError!Air.Inst.Ref {
2526125385 const arena = sema.arena;
2526225386 const mod = sema.mod;
25387 const ip = &mod.intern_pool;
2526325388
2526425389 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
2526525390
......@@ -25281,7 +25406,9 @@ fn unionFieldPtr(
2528125406 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
2528225407 errdefer msg.destroy(sema.gpa);
2528325408
25284 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
25409 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{
25410 ip.stringToSlice(field_name),
25411 });
2528525412 try sema.addDeclaredHereNote(msg, union_ty);
2528625413 break :msg msg;
2528725414 };
......@@ -25296,14 +25423,17 @@ fn unionFieldPtr(
2529625423 if (union_val.isUndef(mod)) {
2529725424 return sema.failWithUseOfUndef(block, src);
2529825425 }
25299 const un = mod.intern_pool.indexToKey(union_val.toIntern()).un;
25426 const un = ip.indexToKey(union_val.toIntern()).un;
2530025427 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
2530125428 const tag_matches = un.tag == field_tag.toIntern();
2530225429 if (!tag_matches) {
2530325430 const msg = msg: {
2530425431 const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
2530525432 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
25306 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
25433 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{
25434 ip.stringToSlice(field_name),
25435 ip.stringToSlice(active_field_name),
25436 });
2530725437 errdefer msg.destroy(sema.gpa);
2530825438 try sema.addDeclaredHereNote(msg, union_ty);
2530925439 break :msg msg;
......@@ -25345,11 +25475,12 @@ fn unionFieldVal(
2534525475 block: *Block,
2534625476 src: LazySrcLoc,
2534725477 union_byval: Air.Inst.Ref,
25348 field_name: []const u8,
25478 field_name: InternPool.NullTerminatedString,
2534925479 field_name_src: LazySrcLoc,
2535025480 unresolved_union_ty: Type,
2535125481) CompileError!Air.Inst.Ref {
2535225482 const mod = sema.mod;
25483 const ip = &mod.intern_pool;
2535325484 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
2535425485
2535525486 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
......@@ -25361,7 +25492,7 @@ fn unionFieldVal(
2536125492 if (try sema.resolveMaybeUndefVal(union_byval)) |union_val| {
2536225493 if (union_val.isUndef(mod)) return sema.addConstUndef(field.ty);
2536325494
25364 const un = mod.intern_pool.indexToKey(union_val.toIntern()).un;
25495 const un = ip.indexToKey(union_val.toIntern()).un;
2536525496 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
2536625497 const tag_matches = un.tag == field_tag.toIntern();
2536725498 switch (union_obj.layout) {
......@@ -25372,7 +25503,9 @@ fn unionFieldVal(
2537225503 const msg = msg: {
2537325504 const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
2537425505 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);
25375 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
25506 const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{
25507 ip.stringToSlice(field_name), ip.stringToSlice(active_field_name),
25508 });
2537625509 errdefer msg.destroy(sema.gpa);
2537725510 try sema.addDeclaredHereNote(msg, union_ty);
2537825511 break :msg msg;
......@@ -26470,14 +26603,13 @@ fn coerceExtra(
2647026603 // enum literal to enum
2647126604 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
2647226605 const string = mod.intern_pool.indexToKey(val.toIntern()).enum_literal;
26473 const bytes = mod.intern_pool.stringToSlice(string);
26474 const field_index = dest_ty.enumFieldIndex(bytes, mod) orelse {
26606 const field_index = dest_ty.enumFieldIndex(string, mod) orelse {
2647526607 const msg = msg: {
2647626608 const msg = try sema.errMsg(
2647726609 block,
2647826610 inst_src,
2647926611 "no field named '{s}' in enum '{}'",
26480 .{ bytes, dest_ty.fmt(mod) },
26612 .{ mod.intern_pool.stringToSlice(string), dest_ty.fmt(mod) },
2648126613 );
2648226614 errdefer msg.destroy(sema.gpa);
2648326615 try sema.addDeclaredHereNote(msg, dest_ty);
......@@ -27876,10 +28008,7 @@ fn storePtrVal(
2787628008 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{mut_kit.ty.fmt(mod)}),
2787728009 };
2787828010
27879 const arena = mut_kit.beginArena(mod);
27880 defer mut_kit.finishArena(mod);
27881
27882 reinterpret.val_ptr.* = (try (try Value.readFromMemory(mut_kit.ty, mod, buffer, arena)).intern(mut_kit.ty, mod)).toValue();
28011 reinterpret.val_ptr.* = (try (try Value.readFromMemory(mut_kit.ty, mod, buffer, sema.arena)).intern(mut_kit.ty, mod)).toValue();
2788328012 },
2788428013 .bad_decl_ty, .bad_ptr_ty => {
2788528014 // TODO show the decl declaration site in a note and explain whether the decl
......@@ -27913,18 +28042,6 @@ const ComptimePtrMutationKit = struct {
2791328042 bad_ptr_ty,
2791428043 },
2791528044 ty: Type,
27916 decl_arena: std.heap.ArenaAllocator = undefined,
27917
27918 fn beginArena(self: *ComptimePtrMutationKit, mod: *Module) Allocator {
27919 const decl = mod.declPtr(self.mut_decl.decl);
27920 return decl.value_arena.?.acquire(mod.gpa, &self.decl_arena);
27921 }
27922
27923 fn finishArena(self: *ComptimePtrMutationKit, mod: *Module) void {
27924 const decl = mod.declPtr(self.mut_decl.decl);
27925 decl.value_arena.?.release(&self.decl_arena);
27926 self.decl_arena = undefined;
27927 }
2792828045};
2792928046
2793028047fn beginComptimePtrMutation(
......@@ -27966,10 +28083,8 @@ fn beginComptimePtrMutation(
2796628083 // An error union has been initialized to undefined at comptime and now we
2796728084 // are for the first time setting the payload. We must change the
2796828085 // representation of the error union from `undef` to `opt_payload`.
27969 const arena = parent.beginArena(sema.mod);
27970 defer parent.finishArena(sema.mod);
2797128086
27972 const payload = try arena.create(Value.Payload.SubValue);
28087 const payload = try sema.arena.create(Value.Payload.SubValue);
2797328088 payload.* = .{
2797428089 .base = .{ .tag = .eu_payload },
2797528090 .data = (try mod.intern(.{ .undef = payload_ty.toIntern() })).toValue(),
......@@ -28019,10 +28134,8 @@ fn beginComptimePtrMutation(
2801928134 // An optional has been initialized to undefined at comptime and now we
2802028135 // are for the first time setting the payload. We must change the
2802128136 // representation of the optional from `undef` to `opt_payload`.
28022 const arena = parent.beginArena(sema.mod);
28023 defer parent.finishArena(sema.mod);
2802428137
28025 const payload = try arena.create(Value.Payload.SubValue);
28138 const payload = try sema.arena.create(Value.Payload.SubValue);
2802628139 payload.* = .{
2802728140 .base = .{ .tag = .opt_payload },
2802828141 .data = payload_val.toValue(),
......@@ -28088,8 +28201,7 @@ fn beginComptimePtrMutation(
2808828201 // If we wanted to avoid this, there would need to be special detection
2808928202 // elsewhere to identify when writing a value to an array element that is stored
2809028203 // using the `bytes` tag, and handle it without making a call to this function.
28091 const arena = parent.beginArena(sema.mod);
28092 defer parent.finishArena(sema.mod);
28204 const arena = sema.arena;
2809328205
2809428206 const bytes = val_ptr.castTag(.bytes).?.data;
2809528207 const dest_len = parent.ty.arrayLenIncludingSentinel(mod);
......@@ -28121,8 +28233,7 @@ fn beginComptimePtrMutation(
2812128233 // need to be special detection elsewhere to identify when writing a value to an
2812228234 // array element that is stored using the `repeated` tag, and handle it
2812328235 // without making a call to this function.
28124 const arena = parent.beginArena(sema.mod);
28125 defer parent.finishArena(sema.mod);
28236 const arena = sema.arena;
2812628237
2812728238 const repeated_val = try val_ptr.castTag(.repeated).?.data.copy(arena);
2812828239 const array_len_including_sentinel =
......@@ -28163,8 +28274,7 @@ fn beginComptimePtrMutation(
2816328274 // An array has been initialized to undefined at comptime and now we
2816428275 // are for the first time setting an element. We must change the representation
2816528276 // of the array from `undef` to `array`.
28166 const arena = parent.beginArena(sema.mod);
28167 defer parent.finishArena(sema.mod);
28277 const arena = sema.arena;
2816828278
2816928279 const array_len_including_sentinel =
2817028280 try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod));
......@@ -28261,8 +28371,7 @@ fn beginComptimePtrMutation(
2826128371 parent.mut_decl,
2826228372 ),
2826328373 .repeated => {
28264 const arena = parent.beginArena(sema.mod);
28265 defer parent.finishArena(sema.mod);
28374 const arena = sema.arena;
2826628375
2826728376 const elems = try arena.alloc(Value, parent.ty.structFieldCount(mod));
2826828377 @memset(elems, val_ptr.castTag(.repeated).?.data);
......@@ -28325,8 +28434,7 @@ fn beginComptimePtrMutation(
2832528434 // A struct or union has been initialized to undefined at comptime and now we
2832628435 // are for the first time setting a field. We must change the representation
2832728436 // of the struct/union from `undef` to `struct`/`union`.
28328 const arena = parent.beginArena(sema.mod);
28329 defer parent.finishArena(sema.mod);
28437 const arena = sema.arena;
2833028438
2833128439 switch (parent.ty.zigTypeTag(mod)) {
2833228440 .Struct => {
......@@ -28436,11 +28544,7 @@ fn beginComptimePtrMutationInner(
2843628544 const target = mod.getTarget();
2843728545 const coerce_ok = (try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_ty, true, target, src, src)) == .ok;
2843828546
28439 const decl = mod.declPtr(mut_decl.decl);
28440 var decl_arena: std.heap.ArenaAllocator = undefined;
28441 const allocator = decl.value_arena.?.acquire(sema.gpa, &decl_arena);
28442 defer decl.value_arena.?.release(&decl_arena);
28443 decl_val.* = try decl_val.unintern(allocator, mod);
28547 decl_val.* = try decl_val.unintern(sema.arena, mod);
2844428548
2844528549 if (coerce_ok) {
2844628550 return ComptimePtrMutationKit{
......@@ -28928,6 +29032,7 @@ fn coerceEnumToUnion(
2892829032 inst_src: LazySrcLoc,
2892929033) !Air.Inst.Ref {
2893029034 const mod = sema.mod;
29035 const ip = &mod.intern_pool;
2893129036 const inst_ty = sema.typeOf(inst);
2893229037
2893329038 const tag_ty = union_ty.unionTagType(mod) orelse {
......@@ -28966,7 +29071,9 @@ fn coerceEnumToUnion(
2896629071 errdefer msg.destroy(sema.gpa);
2896729072
2896829073 const field_name = union_obj.fields.keys()[field_index];
28969 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
29074 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{
29075 ip.stringToSlice(field_name),
29076 });
2897029077 try sema.addDeclaredHereNote(msg, union_ty);
2897129078 break :msg msg;
2897229079 };
......@@ -28976,11 +29083,14 @@ fn coerceEnumToUnion(
2897629083 const msg = msg: {
2897729084 const field_name = union_obj.fields.keys()[field_index];
2897829085 const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{s}'", .{
28979 inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod), field_ty.fmt(sema.mod), field_name,
29086 inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod),
29087 field_ty.fmt(sema.mod), ip.stringToSlice(field_name),
2898029088 });
2898129089 errdefer msg.destroy(sema.gpa);
2898229090
28983 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
29091 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{
29092 ip.stringToSlice(field_name),
29093 });
2898429094 try sema.addDeclaredHereNote(msg, union_ty);
2898529095 break :msg msg;
2898629096 };
......@@ -29049,7 +29159,10 @@ fn coerceEnumToUnion(
2904929159 const field_name = field.key_ptr.*;
2905029160 const field_ty = field.value_ptr.ty;
2905129161 if (!(try sema.typeHasRuntimeBits(field_ty))) continue;
29052 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) });
29162 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{
29163 ip.stringToSlice(field_name),
29164 field_ty.fmt(sema.mod),
29165 });
2905329166 }
2905429167 try sema.addDeclaredHereNote(msg, union_ty);
2905529168 break :msg msg;
......@@ -29068,11 +29181,11 @@ fn coerceAnonStructToUnion(
2906829181 const mod = sema.mod;
2906929182 const inst_ty = sema.typeOf(inst);
2907029183 const field_info: union(enum) {
29071 name: []const u8,
29184 name: InternPool.NullTerminatedString,
2907229185 count: usize,
2907329186 } = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
2907429187 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 1)
29075 .{ .name = mod.intern_pool.stringToSlice(anon_struct_type.names[0]) }
29188 .{ .name = anon_struct_type.names[0] }
2907629189 else
2907729190 .{ .count = anon_struct_type.names.len },
2907829191 .struct_type => |struct_type| name: {
......@@ -29335,6 +29448,7 @@ fn coerceTupleToStruct(
2933529448 inst_src: LazySrcLoc,
2933629449) !Air.Inst.Ref {
2933729450 const mod = sema.mod;
29451 const ip = &mod.intern_pool;
2933829452 const struct_ty = try sema.resolveTypeFields(dest_ty);
2933929453
2934029454 if (struct_ty.isTupleOrAnonStruct(mod)) {
......@@ -29348,7 +29462,7 @@ fn coerceTupleToStruct(
2934829462
2934929463 const inst_ty = sema.typeOf(inst);
2935029464 var runtime_src: ?LazySrcLoc = null;
29351 const field_count = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
29465 const field_count = switch (ip.indexToKey(inst_ty.toIntern())) {
2935229466 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
2935329467 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|
2935429468 struct_obj.fields.count()
......@@ -29360,11 +29474,11 @@ fn coerceTupleToStruct(
2936029474 const field_i = @intCast(u32, field_index_usize);
2936129475 const field_src = inst_src; // TODO better source location
2936229476 // https://github.com/ziglang/zig/issues/15709
29363 const field_name: []const u8 = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
29477 const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
2936429478 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
29365 mod.intern_pool.stringToSlice(anon_struct_type.names[field_i])
29479 anon_struct_type.names[field_i]
2936629480 else
29367 try std.fmt.allocPrint(sema.arena, "{d}", .{field_i}),
29481 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
2936829482 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
2936929483 else => unreachable,
2937029484 };
......@@ -29378,7 +29492,7 @@ fn coerceTupleToStruct(
2937829492 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known");
2937929493 };
2938029494
29381 if (!init_val.eql(field.default_val, field.ty, sema.mod)) {
29495 if (!init_val.eql(field.default_val.toValue(), field.ty, sema.mod)) {
2938229496 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i);
2938329497 }
2938429498 }
......@@ -29401,9 +29515,9 @@ fn coerceTupleToStruct(
2940129515 const field_name = fields.keys()[i];
2940229516 const field = fields.values()[i];
2940329517 const field_src = inst_src; // TODO better source location
29404 if (field.default_val.toIntern() == .unreachable_value) {
29518 if (field.default_val == .none) {
2940529519 const template = "missing struct field: {s}";
29406 const args = .{field_name};
29520 const args = .{ip.stringToSlice(field_name)};
2940729521 if (root_msg) |msg| {
2940829522 try sema.errNote(block, field_src, msg, template, args);
2940929523 } else {
......@@ -29412,9 +29526,9 @@ fn coerceTupleToStruct(
2941229526 continue;
2941329527 }
2941429528 if (runtime_src == null) {
29415 field_vals[i] = field.default_val.toIntern();
29529 field_vals[i] = field.default_val;
2941629530 } else {
29417 field_ref.* = try sema.addConstant(field.ty, field.default_val);
29531 field_ref.* = try sema.addConstant(field.ty, field.default_val.toValue());
2941829532 }
2941929533 }
2942029534
......@@ -29433,7 +29547,7 @@ fn coerceTupleToStruct(
2943329547 .ty = struct_ty.toIntern(),
2943429548 .storage = .{ .elems = field_vals },
2943529549 } });
29436 errdefer mod.intern_pool.remove(struct_val);
29550 errdefer ip.remove(struct_val);
2943729551
2943829552 return sema.addConstant(struct_ty, struct_val.toValue());
2943929553}
......@@ -29446,7 +29560,8 @@ fn coerceTupleToTuple(
2944629560 inst_src: LazySrcLoc,
2944729561) !Air.Inst.Ref {
2944829562 const mod = sema.mod;
29449 const dest_field_count = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
29563 const ip = &mod.intern_pool;
29564 const dest_field_count = switch (ip.indexToKey(tuple_ty.toIntern())) {
2945029565 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
2945129566 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|
2945229567 struct_obj.fields.count()
......@@ -29459,7 +29574,7 @@ fn coerceTupleToTuple(
2945929574 @memset(field_refs, .none);
2946029575
2946129576 const inst_ty = sema.typeOf(inst);
29462 const src_field_count = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
29577 const src_field_count = switch (ip.indexToKey(inst_ty.toIntern())) {
2946329578 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
2946429579 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|
2946529580 struct_obj.fields.count()
......@@ -29474,30 +29589,26 @@ fn coerceTupleToTuple(
2947429589 const field_i = @intCast(u32, field_index_usize);
2947529590 const field_src = inst_src; // TODO better source location
2947629591 // https://github.com/ziglang/zig/issues/15709
29477 const field_name: []const u8 = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
29592 const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
2947829593 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
29479 mod.intern_pool.stringToSlice(anon_struct_type.names[field_i])
29594 anon_struct_type.names[field_i]
2948029595 else
29481 try std.fmt.allocPrint(sema.arena, "{d}", .{field_i}),
29596 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
2948229597 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
2948329598 else => unreachable,
2948429599 };
2948529600
29486 if (mem.eql(u8, field_name, "len")) {
29601 if (ip.stringEqlSlice(field_name, "len"))
2948729602 return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{});
29488 }
2948929603
29490 const field_ty = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
29604 const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {
2949129605 .anon_struct_type => |anon_struct_type| anon_struct_type.types[field_index_usize].toType(),
2949229606 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].ty,
2949329607 else => unreachable,
2949429608 };
29495 const default_val = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
29609 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
2949629610 .anon_struct_type => |anon_struct_type| anon_struct_type.values[field_index_usize],
29497 .struct_type => |struct_type| switch (mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].default_val.toIntern()) {
29498 .unreachable_value => .none,
29499 else => |default_val| default_val,
29500 },
29611 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].default_val,
2950129612 else => unreachable,
2950229613 };
2950329614
......@@ -29531,12 +29642,9 @@ fn coerceTupleToTuple(
2953129642 for (field_refs, 0..) |*field_ref, i| {
2953229643 if (field_ref.* != .none) continue;
2953329644
29534 const default_val = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
29645 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
2953529646 .anon_struct_type => |anon_struct_type| anon_struct_type.values[i],
29536 .struct_type => |struct_type| switch (mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].default_val.toIntern()) {
29537 .unreachable_value => .none,
29538 else => |default_val| default_val,
29539 },
29647 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].default_val,
2954029648 else => unreachable,
2954129649 };
2954229650
......@@ -29552,7 +29660,7 @@ fn coerceTupleToTuple(
2955229660 continue;
2955329661 }
2955429662 const template = "missing struct field: {s}";
29555 const args = .{tuple_ty.structFieldName(i, mod)};
29663 const args = .{ip.stringToSlice(tuple_ty.structFieldName(i, mod))};
2955629664 if (root_msg) |msg| {
2955729665 try sema.errNote(block, field_src, msg, template, args);
2955829666 } else {
......@@ -29563,7 +29671,7 @@ fn coerceTupleToTuple(
2956329671 if (runtime_src == null) {
2956429672 field_vals[i] = default_val;
2956529673 } else {
29566 const field_ty = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {
29674 const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {
2956729675 .anon_struct_type => |anon_struct_type| anon_struct_type.types[i].toType(),
2956829676 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].ty,
2956929677 else => unreachable,
......@@ -31803,15 +31911,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3180331911 }
3180431912
3180531913 if (struct_obj.layout == .Auto and mod.backendSupportsFeature(.field_reordering)) {
31806 const optimized_order = if (struct_obj.owner_decl == sema.owner_decl_index)
31807 try sema.perm_arena.alloc(u32, struct_obj.fields.count())
31808 else blk: {
31809 const decl = mod.declPtr(struct_obj.owner_decl);
31810 var decl_arena: std.heap.ArenaAllocator = undefined;
31811 const decl_arena_allocator = decl.value_arena.?.acquire(sema.gpa, &decl_arena);
31812 defer decl.value_arena.?.release(&decl_arena);
31813 break :blk try decl_arena_allocator.alloc(u32, struct_obj.fields.count());
31814 };
31914 const optimized_order = try mod.tmp_hack_arena.allocator().alloc(u32, struct_obj.fields.count());
3181531915
3181631916 for (struct_obj.fields.values(), 0..) |field, i| {
3181731917 optimized_order[i] = if (try sema.typeHasRuntimeBits(field.ty))
......@@ -31852,9 +31952,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
3185231952
3185331953 const decl_index = struct_obj.owner_decl;
3185431954 const decl = mod.declPtr(decl_index);
31855 var decl_arena: std.heap.ArenaAllocator = undefined;
31856 const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
31857 defer decl.value_arena.?.release(&decl_arena);
3185831955
3185931956 const zir = mod.namespacePtr(struct_obj.namespace).file_scope.zir;
3186031957 const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;
......@@ -31880,7 +31977,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
3188031977 .mod = mod,
3188131978 .gpa = gpa,
3188231979 .arena = analysis_arena.allocator(),
31883 .perm_arena = decl_arena_allocator,
3188431980 .code = zir,
3188531981 .owner_decl = decl,
3188631982 .owner_decl_index = decl_index,
......@@ -31936,7 +32032,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
3193632032 .mod = mod,
3193732033 .gpa = gpa,
3193832034 .arena = undefined,
31939 .perm_arena = decl_arena_allocator,
3194032035 .code = zir,
3194132036 .owner_decl = decl,
3194232037 .owner_decl_index = decl_index,
......@@ -32581,6 +32676,7 @@ fn resolveInferredErrorSetTy(
3258132676
3258232677fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void {
3258332678 const gpa = mod.gpa;
32679 const ip = &mod.intern_pool;
3258432680 const decl_index = struct_obj.owner_decl;
3258532681 const zir = mod.namespacePtr(struct_obj.namespace).file_scope.zir;
3258632682 const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;
......@@ -32628,9 +32724,6 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3262832724 }
3262932725
3263032726 const decl = mod.declPtr(decl_index);
32631 var decl_arena: std.heap.ArenaAllocator = undefined;
32632 const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
32633 defer decl.value_arena.?.release(&decl_arena);
3263432727
3263532728 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3263632729 defer analysis_arena.deinit();
......@@ -32642,7 +32735,6 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3264232735 .mod = mod,
3264332736 .gpa = gpa,
3264432737 .arena = analysis_arena.allocator(),
32645 .perm_arena = decl_arena_allocator,
3264632738 .code = zir,
3264732739 .owner_decl = decl,
3264832740 .owner_decl_index = decl_index,
......@@ -32674,7 +32766,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3267432766 }
3267532767
3267632768 struct_obj.fields = .{};
32677 try struct_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
32769 try struct_obj.fields.ensureTotalCapacity(mod.tmp_hack_arena.allocator(), fields_len);
3267832770
3267932771 const Field = struct {
3268032772 type_body_len: u32 = 0,
......@@ -32725,16 +32817,15 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3272532817 extra_index += 1;
3272632818
3272732819 // This string needs to outlive the ZIR code.
32728 const field_name = if (field_name_zir) |some|
32729 try decl_arena_allocator.dupe(u8, some)
32730 else
32731 try std.fmt.allocPrint(decl_arena_allocator, "{d}", .{field_i});
32820 const field_name = try ip.getOrPutString(gpa, if (field_name_zir) |s| s else try std.fmt.allocPrint(sema.arena, "{d}", .{
32821 field_i,
32822 }));
3273232823
3273332824 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
3273432825 if (gop.found_existing) {
3273532826 const msg = msg: {
3273632827 const field_src = mod.fieldSrcLoc(struct_obj.owner_decl, .{ .index = field_i }).lazy;
32737 const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{field_name});
32828 const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{ip.stringToSlice(field_name)});
3273832829 errdefer msg.destroy(gpa);
3273932830
3274032831 const prev_field_index = struct_obj.fields.getIndex(field_name).?;
......@@ -32748,7 +32839,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3274832839 gop.value_ptr.* = .{
3274932840 .ty = Type.noreturn,
3275032841 .abi_align = 0,
32751 .default_val = Value.@"unreachable",
32842 .default_val = .none,
3275232843 .is_comptime = is_comptime,
3275332844 .offset = undefined,
3275432845 };
......@@ -32917,7 +33008,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
3291733008 }).lazy;
3291833009 return sema.failWithNeededComptime(&block_scope, init_src, "struct field default value must be comptime-known");
3291933010 };
32920 field.default_val = try default_val.copy(decl_arena_allocator);
33011 field.default_val = try default_val.intern(field.ty, mod);
3292133012 }
3292233013 }
3292333014 }
......@@ -32935,6 +33026,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3293533026 defer tracy.end();
3293633027
3293733028 const gpa = mod.gpa;
33029 const ip = &mod.intern_pool;
3293833030 const decl_index = union_obj.owner_decl;
3293933031 const zir = mod.namespacePtr(union_obj.namespace).file_scope.zir;
3294033032 const extended = zir.instructions.items(.data)[union_obj.zir_index].extended;
......@@ -32978,9 +33070,6 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3297833070 extra_index += body.len;
3297933071
3298033072 const decl = mod.declPtr(decl_index);
32981 var decl_arena: std.heap.ArenaAllocator = undefined;
32982 const decl_arena_allocator = decl.value_arena.?.acquire(gpa, &decl_arena);
32983 defer decl.value_arena.?.release(&decl_arena);
3298433073
3298533074 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3298633075 defer analysis_arena.deinit();
......@@ -32992,7 +33081,6 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3299233081 .mod = mod,
3299333082 .gpa = gpa,
3299433083 .arena = analysis_arena.allocator(),
32995 .perm_arena = decl_arena_allocator,
3299633084 .code = zir,
3299733085 .owner_decl = decl,
3299833086 .owner_decl_index = decl_index,
......@@ -33033,7 +33121,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3303333121 try ct_decl.intern(mod);
3303433122 }
3303533123
33036 try union_obj.fields.ensureTotalCapacity(decl_arena_allocator, fields_len);
33124 try union_obj.fields.ensureTotalCapacity(mod.tmp_hack_arena.allocator(), fields_len);
3303733125
3303833126 var int_tag_ty: Type = undefined;
3303933127 var enum_field_names: []InternPool.NullTerminatedString = &.{};
......@@ -33070,7 +33158,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3307033158 } else {
3307133159 // The provided type is the enum tag type.
3307233160 union_obj.tag_ty = provided_ty;
33073 const enum_type = switch (mod.intern_pool.indexToKey(union_obj.tag_ty.toIntern())) {
33161 const enum_type = switch (ip.indexToKey(union_obj.tag_ty.toIntern())) {
3307433162 .enum_type => |x| x,
3307533163 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(mod)}),
3307633164 };
......@@ -33174,10 +33262,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3317433262 }
3317533263
3317633264 // This string needs to outlive the ZIR code.
33177 const field_name = try decl_arena_allocator.dupe(u8, field_name_zir);
33178 const field_name_ip = try mod.intern_pool.getOrPutString(gpa, field_name);
33265 const field_name = try ip.getOrPutString(gpa, field_name_zir);
3317933266 if (enum_field_names.len != 0) {
33180 enum_field_names[field_i] = field_name_ip;
33267 enum_field_names[field_i] = field_name;
3318133268 }
3318233269
3318333270 const field_ty: Type = if (!has_type)
......@@ -33205,7 +33292,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3320533292 if (gop.found_existing) {
3320633293 const msg = msg: {
3320733294 const field_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ .index = field_i }).lazy;
33208 const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{field_name});
33295 const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{
33296 ip.stringToSlice(field_name),
33297 });
3320933298 errdefer msg.destroy(gpa);
3321033299
3321133300 const prev_field_index = union_obj.fields.getIndex(field_name).?;
......@@ -33218,14 +33307,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3321833307 }
3321933308
3322033309 if (explicit_enum_info) |tag_info| {
33221 const enum_index = tag_info.nameIndex(&mod.intern_pool, field_name_ip) orelse {
33310 const enum_index = tag_info.nameIndex(ip, field_name) orelse {
3322233311 const msg = msg: {
3322333312 const ty_src = mod.fieldSrcLoc(union_obj.owner_decl, .{
3322433313 .index = field_i,
3322533314 .range = .type,
3322633315 }).lazy;
3322733316 const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{s}' in enum '{}'", .{
33228 field_name, union_obj.tag_ty.fmt(mod),
33317 ip.stringToSlice(field_name), union_obj.tag_ty.fmt(mod),
3322933318 });
3323033319 errdefer msg.destroy(sema.gpa);
3323133320 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
......@@ -33317,7 +33406,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
3331733406 for (tag_info.names, 0..) |field_name, field_index| {
3331833407 if (explicit_tags_seen[field_index]) continue;
3331933408 try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{
33320 mod.intern_pool.stringToSlice(field_name),
33409 ip.stringToSlice(field_name),
3332133410 });
3332233411 }
3332333412 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
......@@ -33345,14 +33434,22 @@ fn generateUnionTagTypeNumbered(
3334533434 union_obj: *Module.Union,
3334633435) !Type {
3334733436 const mod = sema.mod;
33437 const gpa = sema.gpa;
33438 const ip = &mod.intern_pool;
3334833439
3334933440 const src_decl = mod.declPtr(block.src_decl);
3335033441 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
3335133442 errdefer mod.destroyDecl(new_decl_index);
3335233443 const name = name: {
33353 const fqn = try union_obj.getFullyQualifiedName(mod);
33354 defer sema.gpa.free(fqn);
33355 break :name try std.fmt.allocPrintZ(sema.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn});
33444 const prefix = "@typeInfo(";
33445 const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod));
33446 const suffix = ").Union.tag_type.?";
33447 const start = ip.string_bytes.items.len;
33448 try ip.string_bytes.ensureUnusedCapacity(gpa, prefix.len + suffix.len + fqn.len);
33449 ip.string_bytes.appendSliceAssumeCapacity(prefix);
33450 ip.string_bytes.appendSliceAssumeCapacity(fqn);
33451 ip.string_bytes.appendSliceAssumeCapacity(suffix);
33452 break :name try ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
3335633453 };
3335733454 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{
3335833455 .ty = Type.type,
......@@ -33390,6 +33487,8 @@ fn generateUnionTagTypeSimple(
3339033487 maybe_union_obj: ?*Module.Union,
3339133488) !Type {
3339233489 const mod = sema.mod;
33490 const gpa = sema.gpa;
33491 const ip = &mod.intern_pool;
3339333492
3339433493 const new_decl_index = new_decl_index: {
3339533494 const union_obj = maybe_union_obj orelse {
......@@ -33402,9 +33501,15 @@ fn generateUnionTagTypeSimple(
3340233501 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
3340333502 errdefer mod.destroyDecl(new_decl_index);
3340433503 const name = name: {
33405 const fqn = try union_obj.getFullyQualifiedName(mod);
33406 defer sema.gpa.free(fqn);
33407 break :name try std.fmt.allocPrintZ(sema.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn});
33504 const prefix = "@typeInfo(";
33505 const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod));
33506 const suffix = ").Union.tag_type.?";
33507 const start = ip.string_bytes.items.len;
33508 try ip.string_bytes.ensureUnusedCapacity(gpa, prefix.len + suffix.len + fqn.len);
33509 ip.string_bytes.appendSliceAssumeCapacity(prefix);
33510 ip.string_bytes.appendSliceAssumeCapacity(fqn);
33511 ip.string_bytes.appendSliceAssumeCapacity(suffix);
33512 break :name try ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
3340833513 };
3340933514 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{
3341033515 .ty = Type.type,
......@@ -33436,7 +33541,9 @@ fn generateUnionTagTypeSimple(
3343633541}
3343733542
3343833543fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
33439 var wip_captures = try WipCaptureScope.init(sema.gpa, sema.owner_decl.src_scope);
33544 const gpa = sema.gpa;
33545
33546 var wip_captures = try WipCaptureScope.init(gpa, sema.owner_decl.src_scope);
3344033547 defer wip_captures.deinit();
3344133548
3344233549 var block: Block = .{
......@@ -33450,19 +33557,20 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
3345033557 .is_comptime = true,
3345133558 };
3345233559 defer {
33453 block.instructions.deinit(sema.gpa);
33454 block.params.deinit(sema.gpa);
33560 block.instructions.deinit(gpa);
33561 block.params.deinit(gpa);
3345533562 }
3345633563 const src = LazySrcLoc.nodeOffset(0);
3345733564
3345833565 const mod = sema.mod;
33566 const ip = &mod.intern_pool;
3345933567 const std_pkg = mod.main_pkg.table.get("std").?;
3346033568 const std_file = (mod.importPkg(std_pkg) catch unreachable).file;
3346133569 const opt_builtin_inst = (try sema.namespaceLookupRef(
3346233570 &block,
3346333571 src,
3346433572 mod.declPtr(std_file.root_decl.unwrap().?).src_namespace,
33465 "builtin",
33573 try ip.getOrPutString(gpa, "builtin"),
3346633574 )) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
3346733575 const builtin_inst = try sema.analyzeLoad(&block, src, opt_builtin_inst, src);
3346833576 const builtin_ty = sema.analyzeAsType(&block, src, builtin_inst) catch |err| switch (err) {
......@@ -33473,7 +33581,7 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
3347333581 &block,
3347433582 src,
3347533583 builtin_ty.getNamespaceIndex(mod).unwrap().?,
33476 name,
33584 try ip.getOrPutString(gpa, name),
3347733585 )) orelse std.debug.panic("lib/std/builtin.zig is corrupt and missing '{s}'", .{name});
3347833586 return sema.analyzeDeclVal(&block, src, opt_ty_decl);
3347933587}
......@@ -33608,7 +33716,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3360833716 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
3360933717 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
3361033718 if (field.is_comptime) {
33611 field_val.* = try field.default_val.intern(field.ty, mod);
33719 field_val.* = field.default_val;
3361233720 continue;
3361333721 }
3361433722 if (field.ty.eql(resolved_ty, sema.mod)) {
......@@ -34287,7 +34395,7 @@ fn unionFieldIndex(
3428734395 sema: *Sema,
3428834396 block: *Block,
3428934397 unresolved_union_ty: Type,
34290 field_name: []const u8,
34398 field_name: InternPool.NullTerminatedString,
3429134399 field_src: LazySrcLoc,
3429234400) !u32 {
3429334401 const mod = sema.mod;
......@@ -34302,7 +34410,7 @@ fn structFieldIndex(
3430234410 sema: *Sema,
3430334411 block: *Block,
3430434412 unresolved_struct_ty: Type,
34305 field_name: []const u8,
34413 field_name: InternPool.NullTerminatedString,
3430634414 field_src: LazySrcLoc,
3430734415) !u32 {
3430834416 const mod = sema.mod;
......@@ -34321,19 +34429,17 @@ fn anonStructFieldIndex(
3432134429 sema: *Sema,
3432234430 block: *Block,
3432334431 struct_ty: Type,
34324 field_name: []const u8,
34432 field_name: InternPool.NullTerminatedString,
3432534433 field_src: LazySrcLoc,
3432634434) !u32 {
3432734435 const mod = sema.mod;
3432834436 switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
3432934437 .anon_struct_type => |anon_struct_type| for (anon_struct_type.names, 0..) |name, i| {
34330 if (mem.eql(u8, mod.intern_pool.stringToSlice(name), field_name)) {
34331 return @intCast(u32, i);
34332 }
34438 if (name == field_name) return @intCast(u32, i);
3433334439 },
3433434440 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {
3433534441 for (struct_obj.fields.keys(), 0..) |name, i| {
34336 if (mem.eql(u8, name, field_name)) {
34442 if (name == field_name) {
3433734443 return @intCast(u32, i);
3433834444 }
3433934445 }
......@@ -34341,7 +34447,7 @@ fn anonStructFieldIndex(
3434134447 else => unreachable,
3434234448 }
3434334449 return sema.fail(block, field_src, "no field named '{s}' in anonymous struct '{}'", .{
34344 field_name, struct_ty.fmt(sema.mod),
34450 mod.intern_pool.stringToSlice(field_name), struct_ty.fmt(sema.mod),
3434534451 });
3434634452}
3434734453
src/TypedValue.zig+14-13
......@@ -201,10 +201,10 @@ pub fn print(
201201 },
202202 .variable => return writer.writeAll("(variable)"),
203203 .extern_func => |extern_func| return writer.print("(extern function '{s}')", .{
204 mod.declPtr(extern_func.decl).name,
204 mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name),
205205 }),
206 .func => |func| return writer.print("(function '{s}')", .{
207 mod.declPtr(mod.funcPtr(func.index).owner_decl).name,
206 .func => |func| return writer.print("(function '{d}')", .{
207 mod.intern_pool.stringToSlice(mod.declPtr(mod.funcPtr(func.index).owner_decl).name),
208208 }),
209209 .int => |int| switch (int.storage) {
210210 inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
......@@ -296,19 +296,20 @@ fn printAggregate(
296296 }
297297 if (ty.zigTypeTag(mod) == .Struct) {
298298 try writer.writeAll(".{");
299 const max_len = std.math.min(ty.structFieldCount(mod), max_aggregate_items);
299 const max_len = @min(ty.structFieldCount(mod), max_aggregate_items);
300300
301 var i: u32 = 0;
302 while (i < max_len) : (i += 1) {
301 for (0..max_len) |i| {
303302 if (i != 0) try writer.writeAll(", ");
304 if (switch (mod.intern_pool.indexToKey(ty.toIntern())) {
305 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[i],
306 .anon_struct_type => |anon_struct_type| if (anon_struct_type.isTuple())
307 null
308 else
309 mod.intern_pool.stringToSlice(anon_struct_type.names[i]),
303
304 const field_name = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
305 .struct_type => |x| mod.structPtrUnwrap(x.index).?.fields.keys()[i].toOptional(),
306 .anon_struct_type => |x| if (x.isTuple()) .none else x.names[i].toOptional(),
310307 else => unreachable,
311 }) |field_name| try writer.print(".{s} = ", .{field_name});
308 };
309
310 if (field_name.unwrap()) |name_ip| try writer.print(".{s} = ", .{
311 mod.intern_pool.stringToSlice(name_ip),
312 });
312313 try print(.{
313314 .ty = ty.structFieldType(i, mod),
314315 .val = try val.fieldValue(mod, i),
src/arch/aarch64/CodeGen.zig+1-1
......@@ -4350,7 +4350,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43504350 .data = .{ .reg = .x30 },
43514351 });
43524352 } else if (func_value.getExternFunc(mod)) |extern_func| {
4353 const decl_name = mem.sliceTo(mod.declPtr(extern_func.decl).name, 0);
4353 const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name);
43544354 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
43554355 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
43564356 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
src/arch/sparc64/CodeGen.zig-2
......@@ -276,8 +276,6 @@ pub fn generate(
276276 assert(fn_owner_decl.has_tv);
277277 const fn_type = fn_owner_decl.ty;
278278
279 log.debug("fn {s}", .{fn_owner_decl.name});
280
281279 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
282280 defer {
283281 assert(branch_stack.items.len == 1);
src/arch/wasm/CodeGen.zig+10-16
......@@ -2208,7 +2208,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
22082208 const atom = func.bin_file.getAtomPtr(atom_index);
22092209 const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);
22102210 try func.bin_file.addOrUpdateImport(
2211 mem.sliceTo(ext_decl.name, 0),
2211 mod.intern_pool.stringToSlice(ext_decl.name),
22122212 atom.getSymbolIndex().?,
22132213 mod.intern_pool.stringToSliceUnwrap(ext_decl.getOwnedExternFunc(mod).?.lib_name),
22142214 type_index,
......@@ -3180,9 +3180,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
31803180 }
31813181 },
31823182 .err => |err| {
3183 const name = mod.intern_pool.stringToSlice(err.name);
3184 const kv = try mod.getErrorValue(name);
3185 return WValue{ .imm32 = kv.value };
3183 const int = try mod.getErrorValue(err.name);
3184 return WValue{ .imm32 = int };
31863185 },
31873186 .error_union => |error_union| {
31883187 const err_tv: TypedValue = switch (error_union.val) {
......@@ -3320,18 +3319,15 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
33203319 .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, mod),
33213320 .int => |int| intStorageAsI32(int.storage, mod),
33223321 .ptr => |ptr| intIndexAsI32(&mod.intern_pool, ptr.addr.int, mod),
3323 .err => |err| @bitCast(i32, mod.global_error_set.get(mod.intern_pool.stringToSlice(err.name)).?),
3322 .err => |err| @bitCast(i32, @intCast(Module.ErrorInt, mod.global_error_set.getIndex(err.name).?)),
33243323 else => unreachable,
33253324 },
33263325 }
33273326
3328 switch (ty.zigTypeTag(mod)) {
3329 .ErrorSet => {
3330 const kv = func.bin_file.base.options.module.?.getErrorValue(val.getError(mod).?) catch unreachable; // passed invalid `Value` to function
3331 return @bitCast(i32, kv.value);
3332 },
3327 return switch (ty.zigTypeTag(mod)) {
3328 .ErrorSet => @bitCast(i32, val.getErrorInt(mod)),
33333329 else => unreachable, // Programmer called this function for an illegal type
3334 }
3330 };
33353331}
33363332
33373333fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, mod: *Module) i32 {
......@@ -6874,8 +6870,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
68746870 defer arena_allocator.deinit();
68756871 const arena = arena_allocator.allocator();
68766872
6877 const fqn = try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod);
6878 defer mod.gpa.free(fqn);
6873 const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod));
68796874 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
68806875
68816876 // check if we already generated code for this.
......@@ -7037,9 +7032,8 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
70377032
70387033 var lowest: ?u32 = null;
70397034 var highest: ?u32 = null;
7040 for (names) |name_ip| {
7041 const name = mod.intern_pool.stringToSlice(name_ip);
7042 const err_int = mod.global_error_set.get(name).?;
7035 for (names) |name| {
7036 const err_int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);
70437037 if (lowest) |*l| {
70447038 if (err_int < l.*) {
70457039 l.* = err_int;
src/arch/x86_64/CodeGen.zig+1-1
......@@ -8132,7 +8132,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
81328132 }));
81338133 } else unreachable;
81348134 } else if (func_value.getExternFunc(mod)) |extern_func| {
8135 const decl_name = mem.sliceTo(mod.declPtr(extern_func.decl).name, 0);
8135 const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name);
81368136 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
81378137 if (self.bin_file.cast(link.File.Coff)) |coff_file| {
81388138 const atom_index = try self.owner.getSymbolIndex(self);
src/codegen.zig+8-12
......@@ -142,11 +142,12 @@ pub fn generateLazySymbol(
142142
143143 if (lazy_sym.ty.isAnyError(mod)) {
144144 alignment.* = 4;
145 const err_names = mod.error_name_list.items;
145 const err_names = mod.global_error_set.keys();
146146 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);
147147 var offset = code.items.len;
148148 try code.resize((1 + err_names.len + 1) * 4);
149 for (err_names) |err_name| {
149 for (err_names) |err_name_nts| {
150 const err_name = mod.intern_pool.stringToSlice(err_name_nts);
150151 mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);
151152 offset += 4;
152153 try code.ensureUnusedCapacity(err_name.len + 1);
......@@ -251,15 +252,13 @@ pub fn generateSymbol(
251252 val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
252253 },
253254 .err => |err| {
254 const name = mod.intern_pool.stringToSlice(err.name);
255 const kv = try mod.getErrorValue(name);
256 try code.writer().writeInt(u16, @intCast(u16, kv.value), endian);
255 const int = try mod.getErrorValue(err.name);
256 try code.writer().writeInt(u16, @intCast(u16, int), endian);
257257 },
258258 .error_union => |error_union| {
259259 const payload_ty = typed_value.ty.errorUnionPayload(mod);
260
261260 const err_val = switch (error_union.val) {
262 .err_name => |err_name| @intCast(u16, (try mod.getErrorValue(mod.intern_pool.stringToSlice(err_name))).value),
261 .err_name => |err_name| @intCast(u16, try mod.getErrorValue(err_name)),
263262 .payload => @as(u16, 0),
264263 };
265264
......@@ -974,11 +973,8 @@ pub fn genTypedValue(
974973 }, owner_decl_index);
975974 },
976975 .ErrorSet => {
977 const err_name = mod.intern_pool.stringToSlice(
978 mod.intern_pool.indexToKey(typed_value.val.toIntern()).err.name,
979 );
980 const global_error_set = mod.global_error_set;
981 const error_index = global_error_set.get(err_name).?;
976 const err_name = mod.intern_pool.indexToKey(typed_value.val.toIntern()).err.name;
977 const error_index = mod.global_error_set.getIndex(err_name).?;
982978 return GenResult.mcv(.{ .immediate = error_index });
983979 },
984980 .ErrorUnion => {
src/codegen/c.zig+43-29
......@@ -452,6 +452,7 @@ pub const Function = struct {
452452 var promoted = f.object.dg.ctypes.promote(gpa);
453453 defer f.object.dg.ctypes.demote(promoted);
454454 const arena = promoted.arena.allocator();
455 const mod = f.object.dg.module;
455456
456457 gop.value_ptr.* = .{
457458 .fn_name = switch (key) {
......@@ -460,7 +461,7 @@ pub const Function = struct {
460461 .never_inline,
461462 => |owner_decl| try std.fmt.allocPrint(arena, "zig_{s}_{}__{d}", .{
462463 @tagName(key),
463 fmtIdent(mem.span(f.object.dg.module.declPtr(owner_decl).name)),
464 fmtIdent(mod.intern_pool.stringToSlice(mod.declPtr(owner_decl).name)),
464465 @enumToInt(owner_decl),
465466 }),
466467 },
......@@ -1465,7 +1466,7 @@ pub const DeclGen = struct {
14651466 try writer.writeAll(" .payload = {");
14661467 }
14671468 if (field_ty.hasRuntimeBits(mod)) {
1468 try writer.print(" .{ } = ", .{fmtIdent(field_name)});
1469 try writer.print(" .{ } = ", .{fmtIdent(mod.intern_pool.stringToSlice(field_name))});
14691470 try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type);
14701471 try writer.writeByte(' ');
14711472 } else for (ty.unionFields(mod).values()) |field| {
......@@ -1849,9 +1850,9 @@ pub const DeclGen = struct {
18491850 try mod.markDeclAlive(decl);
18501851
18511852 if (mod.decl_exports.get(decl_index)) |exports| {
1852 try writer.writeAll(exports.items[export_index].options.name);
1853 try writer.writeAll(mod.intern_pool.stringToSlice(exports.items[export_index].name));
18531854 } else if (decl.isExtern(mod)) {
1854 try writer.writeAll(mem.span(decl.name));
1855 try writer.writeAll(mod.intern_pool.stringToSlice(decl.name));
18551856 } else {
18561857 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
18571858 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
......@@ -1987,7 +1988,7 @@ fn renderTypeName(
19871988 try w.print("{s} {s}{}__{d}", .{
19881989 @tagName(tag)["fwd_".len..],
19891990 attributes,
1990 fmtIdent(mem.span(mod.declPtr(owner_decl).name)),
1991 fmtIdent(mod.intern_pool.stringToSlice(mod.declPtr(owner_decl).name)),
19911992 @enumToInt(owner_decl),
19921993 });
19931994 },
......@@ -2406,11 +2407,12 @@ pub fn genErrDecls(o: *Object) !void {
24062407 try writer.writeAll("enum {\n");
24072408 o.indent_writer.pushIndent();
24082409 var max_name_len: usize = 0;
2409 for (mod.error_name_list.items[1..], 1..) |name, value| {
2410 max_name_len = std.math.max(name.len, max_name_len);
2410 for (mod.global_error_set.keys()[1..], 1..) |name_nts, value| {
2411 const name = mod.intern_pool.stringToSlice(name_nts);
2412 max_name_len = @max(name.len, max_name_len);
24112413 const err_val = try mod.intern(.{ .err = .{
24122414 .ty = .anyerror_type,
2413 .name = mod.intern_pool.getString(name).unwrap().?,
2415 .name = name_nts,
24142416 } });
24152417 try o.dg.renderValue(writer, Type.anyerror, err_val.toValue(), .Other);
24162418 try writer.print(" = {d}u,\n", .{value});
......@@ -2424,7 +2426,8 @@ pub fn genErrDecls(o: *Object) !void {
24242426 defer o.dg.gpa.free(name_buf);
24252427
24262428 @memcpy(name_buf[0..name_prefix.len], name_prefix);
2427 for (mod.error_name_list.items) |name| {
2429 for (mod.global_error_set.keys()) |name_nts| {
2430 const name = mod.intern_pool.stringToSlice(name_nts);
24282431 @memcpy(name_buf[name_prefix.len..][0..name.len], name);
24292432 const identifier = name_buf[0 .. name_prefix.len + name.len];
24302433
......@@ -2446,14 +2449,15 @@ pub fn genErrDecls(o: *Object) !void {
24462449 }
24472450
24482451 const name_array_ty = try mod.arrayType(.{
2449 .len = mod.error_name_list.items.len,
2452 .len = mod.global_error_set.count(),
24502453 .child = .slice_const_u8_sentinel_0_type,
24512454 });
24522455
24532456 try writer.writeAll("static ");
24542457 try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, 0, .complete);
24552458 try writer.writeAll(" = {");
2456 for (mod.error_name_list.items, 0..) |name, value| {
2459 for (mod.global_error_set.keys(), 0..) |name_nts, value| {
2460 const name = mod.intern_pool.stringToSlice(name_nts);
24572461 if (value != 0) try writer.writeByte(',');
24582462
24592463 const len_val = try mod.intValue(Type.usize, name.len);
......@@ -2469,14 +2473,16 @@ fn genExports(o: *Object) !void {
24692473 const tracy = trace(@src());
24702474 defer tracy.end();
24712475
2476 const mod = o.dg.module;
2477 const ip = &mod.intern_pool;
24722478 const fwd_decl_writer = o.dg.fwd_decl.writer();
2473 if (o.dg.module.decl_exports.get(o.dg.decl_index.unwrap().?)) |exports| {
2479 if (mod.decl_exports.get(o.dg.decl_index.unwrap().?)) |exports| {
24742480 for (exports.items[1..], 1..) |@"export", i| {
24752481 try fwd_decl_writer.writeAll("zig_export(");
24762482 try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @intCast(u32, i) });
24772483 try fwd_decl_writer.print(", {s}, {s});\n", .{
2478 fmtStringLiteral(exports.items[0].options.name, null),
2479 fmtStringLiteral(@"export".options.name, null),
2484 fmtStringLiteral(ip.stringToSlice(exports.items[0].name), null),
2485 fmtStringLiteral(ip.stringToSlice(@"export".name), null),
24802486 });
24812487 }
24822488 }
......@@ -2680,9 +2686,10 @@ pub fn genDecl(o: *Object) !void {
26802686 if (!is_global) try w.writeAll("static ");
26812687 if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
26822688 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");
2683 if (decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section});
2689 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
2690 try w.print("zig_linksection(\"{s}\", ", .{s});
26842691 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.@"align", .complete);
2685 if (decl.@"linksection" != null) try w.writeAll(", read, write)");
2692 if (decl.@"linksection" != .none) try w.writeAll(", read, write)");
26862693 try w.writeAll(" = ");
26872694 try o.dg.renderValue(w, tv.ty, variable.init.toValue(), .StaticInitializer);
26882695 try w.writeByte(';');
......@@ -2697,9 +2704,10 @@ pub fn genDecl(o: *Object) !void {
26972704
26982705 const w = o.writer();
26992706 if (!is_global) try w.writeAll("static ");
2700 if (decl.@"linksection") |section| try w.print("zig_linksection(\"{s}\", ", .{section});
2707 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
2708 try w.print("zig_linksection(\"{s}\", ", .{s});
27012709 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, decl.@"align", .complete);
2702 if (decl.@"linksection" != null) try w.writeAll(", read)");
2710 if (decl.@"linksection" != .none) try w.writeAll(", read)");
27032711 try w.writeAll(" = ");
27042712 try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);
27052713 try w.writeAll(";\n");
......@@ -4229,7 +4237,9 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
42294237 const mod = f.object.dg.module;
42304238 const writer = f.object.writer();
42314239 const function = mod.funcPtr(ty_fn.func);
4232 try writer.print("/* dbg func:{s} */\n", .{mod.declPtr(function.owner_decl).name});
4240 try writer.print("/* dbg func:{s} */\n", .{
4241 mod.intern_pool.stringToSlice(mod.declPtr(function.owner_decl).name),
4242 });
42334243 return .none;
42344244}
42354245
......@@ -5176,6 +5186,7 @@ fn fieldLocation(
51765186 byte_offset: u32,
51775187 end: void,
51785188} {
5189 const ip = &mod.intern_pool;
51795190 return switch (container_ty.zigTypeTag(mod)) {
51805191 .Struct => switch (container_ty.containerLayout(mod)) {
51815192 .Auto, .Extern => for (field_index..container_ty.structFieldCount(mod)) |next_field_index| {
......@@ -5186,7 +5197,7 @@ fn fieldLocation(
51865197 break .{ .field = if (container_ty.isSimpleTuple(mod))
51875198 .{ .field = next_field_index }
51885199 else
5189 .{ .identifier = container_ty.structFieldName(next_field_index, mod) } };
5200 .{ .identifier = ip.stringToSlice(container_ty.structFieldName(next_field_index, mod)) } };
51905201 } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin,
51915202 .Packed => if (field_ptr_ty.ptrInfo(mod).host_size == 0)
51925203 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }
......@@ -5204,9 +5215,9 @@ fn fieldLocation(
52045215 .begin;
52055216 const field_name = container_ty.unionFields(mod).keys()[field_index];
52065217 return .{ .field = if (container_ty.unionTagTypeSafety(mod)) |_|
5207 .{ .payload_identifier = field_name }
5218 .{ .payload_identifier = ip.stringToSlice(field_name) }
52085219 else
5209 .{ .identifier = field_name } };
5220 .{ .identifier = ip.stringToSlice(field_name) } };
52105221 },
52115222 .Packed => .begin,
52125223 },
......@@ -5347,6 +5358,7 @@ fn fieldPtr(
53475358
53485359fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
53495360 const mod = f.object.dg.module;
5361 const ip = &mod.intern_pool;
53505362 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
53515363 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;
53525364
......@@ -5369,7 +5381,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
53695381 .Auto, .Extern => if (struct_ty.isSimpleTuple(mod))
53705382 .{ .field = extra.field_index }
53715383 else
5372 .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },
5384 .{ .identifier = ip.stringToSlice(struct_ty.structFieldName(extra.field_index, mod)) },
53735385 .Packed => {
53745386 const struct_obj = mod.typeToStruct(struct_ty).?;
53755387 const int_info = struct_ty.intInfo(mod);
......@@ -5431,7 +5443,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54315443 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 0)
54325444 .{ .field = extra.field_index }
54335445 else
5434 .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },
5446 .{ .identifier = ip.stringToSlice(struct_ty.structFieldName(extra.field_index, mod)) },
54355447
54365448 .union_type => |union_type| field_name: {
54375449 const union_obj = mod.unionPtr(union_type.index);
......@@ -5462,9 +5474,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
54625474 } else {
54635475 const name = union_obj.fields.keys()[extra.field_index];
54645476 break :field_name if (union_type.hasTag()) .{
5465 .payload_identifier = name,
5477 .payload_identifier = ip.stringToSlice(name),
54665478 } else .{
5467 .identifier = name,
5479 .identifier = ip.stringToSlice(name),
54685480 };
54695481 }
54705482 },
......@@ -6723,6 +6735,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
67236735
67246736fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
67256737 const mod = f.object.dg.module;
6738 const ip = &mod.intern_pool;
67266739 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
67276740 const inst_ty = f.typeOfIndex(inst);
67286741 const len = @intCast(usize, inst_ty.arrayLen(mod));
......@@ -6773,7 +6786,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
67736786 try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple(mod))
67746787 .{ .field = field_i }
67756788 else
6776 .{ .identifier = inst_ty.structFieldName(field_i, mod) });
6789 .{ .identifier = ip.stringToSlice(inst_ty.structFieldName(field_i, mod)) });
67776790 try a.assign(f, writer);
67786791 try f.writeCValue(writer, element, .Other);
67796792 try a.end(f, writer);
......@@ -6851,6 +6864,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
68516864
68526865fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
68536866 const mod = f.object.dg.module;
6867 const ip = &mod.intern_pool;
68546868 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
68556869 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
68566870
......@@ -6886,8 +6900,8 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
68866900 try writer.print("{}", .{try f.fmtIntLiteral(tag_ty, int_val)});
68876901 try a.end(f, writer);
68886902 }
6889 break :field .{ .payload_identifier = field_name };
6890 } else .{ .identifier = field_name };
6903 break :field .{ .payload_identifier = ip.stringToSlice(field_name) };
6904 } else .{ .identifier = ip.stringToSlice(field_name) };
68916905
68926906 const a = try Assignment.start(f, writer, payload_ty);
68936907 try f.writeCValueMember(writer, local, field);
src/codegen/c/type.zig+15-13
......@@ -1953,11 +1953,11 @@ pub const CType = extern union {
19531953 .name = try if (ty.isSimpleTuple(mod))
19541954 std.fmt.allocPrintZ(arena, "f{}", .{field_i})
19551955 else
1956 arena.dupeZ(u8, switch (zig_ty_tag) {
1956 arena.dupeZ(u8, mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
19571957 .Struct => ty.structFieldName(field_i, mod),
19581958 .Union => ty.unionFields(mod).keys()[field_i],
19591959 else => unreachable,
1960 }),
1960 })),
19611961 .type = store.set.typeToIndex(field_ty, mod, switch (kind) {
19621962 .forward, .forward_parameter => .forward,
19631963 .complete, .parameter, .payload => .complete,
......@@ -2102,12 +2102,13 @@ pub const CType = extern union {
21022102 }) or !mem.eql(
21032103 u8,
21042104 if (ty.isSimpleTuple(mod))
2105 std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable
2106 else switch (zig_ty_tag) {
2107 .Struct => ty.structFieldName(field_i, mod),
2108 .Union => ty.unionFields(mod).keys()[field_i],
2109 else => unreachable,
2110 },
2105 std.fmt.bufPrintZ(&name_buf, "f{}", .{field_i}) catch unreachable
2106 else
2107 mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
2108 .Struct => ty.structFieldName(field_i, mod),
2109 .Union => ty.unionFields(mod).keys()[field_i],
2110 else => unreachable,
2111 }),
21112112 mem.span(c_field.name),
21122113 ) or AlignAs.fieldAlign(ty, field_i, mod).@"align" !=
21132114 c_field.alignas.@"align") return false;
......@@ -2225,11 +2226,12 @@ pub const CType = extern union {
22252226 });
22262227 hasher.update(if (ty.isSimpleTuple(mod))
22272228 std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable
2228 else switch (zig_ty_tag) {
2229 .Struct => ty.structFieldName(field_i, mod),
2230 .Union => ty.unionFields(mod).keys()[field_i],
2231 else => unreachable,
2232 });
2229 else
2230 mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
2231 .Struct => ty.structFieldName(field_i, mod),
2232 .Union => ty.unionFields(mod).keys()[field_i],
2233 else => unreachable,
2234 }));
22332235 autoHash(hasher, AlignAs.fieldAlign(ty, field_i, mod).@"align");
22342236 }
22352237 },
src/codegen/llvm.zig+52-70
......@@ -585,13 +585,13 @@ pub const Object = struct {
585585 const slice_ty = Type.slice_const_u8_sentinel_0;
586586 const slice_alignment = slice_ty.abiAlignment(mod);
587587
588 const error_name_list = mod.error_name_list.items;
588 const error_name_list = mod.global_error_set.keys();
589589 const llvm_errors = try mod.gpa.alloc(*llvm.Value, error_name_list.len);
590590 defer mod.gpa.free(llvm_errors);
591591
592592 llvm_errors[0] = llvm_slice_ty.getUndef();
593 for (llvm_errors[1..], 0..) |*llvm_error, i| {
594 const name = error_name_list[1..][i];
593 for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name_nts| {
594 const name = mod.intern_pool.stringToSlice(name_nts);
595595 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
596596 const str_global = self.llvm_module.addGlobal(str_init.typeOf(), "");
597597 str_global.setInitializer(str_init);
......@@ -671,7 +671,7 @@ pub const Object = struct {
671671 const llvm_global = entry.value_ptr.*;
672672 // Same logic as below but for externs instead of exports.
673673 const decl = mod.declPtr(decl_index);
674 const other_global = object.getLlvmGlobal(decl.name) orelse continue;
674 const other_global = object.getLlvmGlobal(mod.intern_pool.stringToSlice(decl.name)) orelse continue;
675675 if (other_global == llvm_global) continue;
676676
677677 llvm_global.replaceAllUsesWith(other_global);
......@@ -689,8 +689,7 @@ pub const Object = struct {
689689 // case, we need to replace all uses of it with this exported global.
690690 // TODO update std.builtin.ExportOptions to have the name be a
691691 // null-terminated slice.
692 const exp_name_z = try mod.gpa.dupeZ(u8, exp.options.name);
693 defer mod.gpa.free(exp_name_z);
692 const exp_name_z = mod.intern_pool.stringToSlice(exp.name);
694693
695694 const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue;
696695 if (other_global == llvm_global) continue;
......@@ -923,9 +922,8 @@ pub const Object = struct {
923922 dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
924923 }
925924
926 if (decl.@"linksection") |section| {
925 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section|
927926 llvm_func.setSection(section);
928 }
929927
930928 // Remove all the basic blocks of a function in order to start over, generating
931929 // LLVM IR from an empty function body.
......@@ -1173,7 +1171,7 @@ pub const Object = struct {
11731171 0;
11741172 const subprogram = dib.createFunction(
11751173 di_file.?.toScope(),
1176 decl.name,
1174 mod.intern_pool.stringToSlice(decl.name),
11771175 llvm_func.getValueName(),
11781176 di_file.?,
11791177 line_number,
......@@ -1273,22 +1271,26 @@ pub const Object = struct {
12731271 if (decl.isExtern(mod)) {
12741272 var free_decl_name = false;
12751273 const decl_name = decl_name: {
1274 const decl_name = mod.intern_pool.stringToSlice(decl.name);
1275
12761276 if (mod.getTarget().isWasm() and try decl.isFunction(mod)) {
12771277 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
12781278 if (!std.mem.eql(u8, lib_name, "c")) {
12791279 free_decl_name = true;
1280 break :decl_name try std.fmt.allocPrintZ(gpa, "{s}|{s}", .{ decl.name, lib_name });
1280 break :decl_name try std.fmt.allocPrintZ(gpa, "{s}|{s}", .{
1281 decl_name, lib_name,
1282 });
12811283 }
12821284 }
12831285 }
1284 break :decl_name std.mem.span(decl.name);
1286
1287 break :decl_name decl_name;
12851288 };
12861289 defer if (free_decl_name) gpa.free(decl_name);
12871290
12881291 llvm_global.setValueName(decl_name);
12891292 if (self.getLlvmGlobal(decl_name)) |other_global| {
12901293 if (other_global != llvm_global) {
1291 log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name});
12921294 try self.extern_collisions.put(gpa, decl_index, {});
12931295 }
12941296 }
......@@ -1298,11 +1300,11 @@ pub const Object = struct {
12981300 if (self.di_map.get(decl)) |di_node| {
12991301 if (try decl.isFunction(mod)) {
13001302 const di_func = @ptrCast(*llvm.DISubprogram, di_node);
1301 const linkage_name = llvm.MDString.get(self.context, decl.name, std.mem.len(decl.name));
1303 const linkage_name = llvm.MDString.get(self.context, decl_name.ptr, decl_name.len);
13021304 di_func.replaceLinkageName(linkage_name);
13031305 } else {
13041306 const di_global = @ptrCast(*llvm.DIGlobalVariable, di_node);
1305 const linkage_name = llvm.MDString.get(self.context, decl.name, std.mem.len(decl.name));
1307 const linkage_name = llvm.MDString.get(self.context, decl_name.ptr, decl_name.len);
13061308 di_global.replaceLinkageName(linkage_name);
13071309 }
13081310 }
......@@ -1317,7 +1319,7 @@ pub const Object = struct {
13171319 }
13181320 }
13191321 } else if (exports.len != 0) {
1320 const exp_name = exports[0].options.name;
1322 const exp_name = mod.intern_pool.stringToSlice(exports[0].name);
13211323 llvm_global.setValueName2(exp_name.ptr, exp_name.len);
13221324 llvm_global.setUnnamedAddr(.False);
13231325 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);
......@@ -1332,21 +1334,19 @@ pub const Object = struct {
13321334 di_global.replaceLinkageName(linkage_name);
13331335 }
13341336 }
1335 switch (exports[0].options.linkage) {
1337 switch (exports[0].linkage) {
13361338 .Internal => unreachable,
13371339 .Strong => llvm_global.setLinkage(.External),
13381340 .Weak => llvm_global.setLinkage(.WeakODR),
13391341 .LinkOnce => llvm_global.setLinkage(.LinkOnceODR),
13401342 }
1341 switch (exports[0].options.visibility) {
1343 switch (exports[0].visibility) {
13421344 .default => llvm_global.setVisibility(.Default),
13431345 .hidden => llvm_global.setVisibility(.Hidden),
13441346 .protected => llvm_global.setVisibility(.Protected),
13451347 }
1346 if (exports[0].options.section) |section| {
1347 const section_z = try gpa.dupeZ(u8, section);
1348 defer gpa.free(section_z);
1349 llvm_global.setSection(section_z);
1348 if (mod.intern_pool.stringToSliceUnwrap(exports[0].section)) |section| {
1349 llvm_global.setSection(section);
13501350 }
13511351 if (decl.val.getVariable(mod)) |variable| {
13521352 if (variable.is_threadlocal) {
......@@ -1356,13 +1356,12 @@ pub const Object = struct {
13561356
13571357 // If a Decl is exported more than one time (which is rare),
13581358 // we add aliases for all but the first export.
1359 // TODO LLVM C API does not support deleting aliases. We need to
1360 // patch it to support this or figure out how to wrap the C++ API ourselves.
1359 // TODO LLVM C API does not support deleting aliases.
1360 // The planned solution to this is https://github.com/ziglang/zig/issues/13265
13611361 // Until then we iterate over existing aliases and make them point
13621362 // to the correct decl, or otherwise add a new alias. Old aliases are leaked.
13631363 for (exports[1..]) |exp| {
1364 const exp_name_z = try gpa.dupeZ(u8, exp.options.name);
1365 defer gpa.free(exp_name_z);
1364 const exp_name_z = mod.intern_pool.stringToSlice(exp.name);
13661365
13671366 if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| {
13681367 alias.setAliasee(llvm_global);
......@@ -1376,8 +1375,7 @@ pub const Object = struct {
13761375 }
13771376 }
13781377 } else {
1379 const fqn = try decl.getFullyQualifiedName(mod);
1380 defer gpa.free(fqn);
1378 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
13811379 llvm_global.setValueName2(fqn.ptr, fqn.len);
13821380 llvm_global.setLinkage(.Internal);
13831381 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
......@@ -2092,8 +2090,7 @@ pub const Object = struct {
20922090 const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);
20932091 offset = field_offset + field_size;
20942092
2095 const field_name = try gpa.dupeZ(u8, fields.keys()[field_and_index.index]);
2096 defer gpa.free(field_name);
2093 const field_name = mod.intern_pool.stringToSlice(fields.keys()[field_and_index.index]);
20972094
20982095 try di_fields.append(gpa, dib.createMemberType(
20992096 fwd_decl.toScope(),
......@@ -2200,12 +2197,9 @@ pub const Object = struct {
22002197 const field_size = field.ty.abiSize(mod);
22012198 const field_align = field.normalAlignment(mod);
22022199
2203 const field_name_copy = try gpa.dupeZ(u8, field_name);
2204 defer gpa.free(field_name_copy);
2205
22062200 di_fields.appendAssumeCapacity(dib.createMemberType(
22072201 fwd_decl.toScope(),
2208 field_name_copy,
2202 mod.intern_pool.stringToSlice(field_name),
22092203 null, // file
22102204 0, // line
22112205 field_size * 8, // size in bits
......@@ -2327,7 +2321,7 @@ pub const Object = struct {
23272321 if (fn_info.return_type.toType().isError(mod) and
23282322 o.module.comp.bin_file.options.error_return_tracing)
23292323 {
2330 const ptr_ty = try mod.singleMutPtrType(o.getStackTraceType());
2324 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
23312325 try param_di_types.append(try o.lowerDebugType(ptr_ty, .full));
23322326 }
23332327
......@@ -2384,7 +2378,7 @@ pub const Object = struct {
23842378 const fields: [0]*llvm.DIType = .{};
23852379 return o.di_builder.?.createStructType(
23862380 try o.namespaceToDebugScope(decl.src_namespace),
2387 decl.name, // TODO use fully qualified name
2381 mod.intern_pool.stringToSlice(decl.name), // TODO use fully qualified name
23882382 try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope),
23892383 decl.src_line + 1,
23902384 0, // size in bits
......@@ -2399,18 +2393,18 @@ pub const Object = struct {
23992393 );
24002394 }
24012395
2402 fn getStackTraceType(o: *Object) Type {
2396 fn getStackTraceType(o: *Object) Allocator.Error!Type {
24032397 const mod = o.module;
24042398
24052399 const std_pkg = mod.main_pkg.table.get("std").?;
24062400 const std_file = (mod.importPkg(std_pkg) catch unreachable).file;
24072401
2408 const builtin_str: []const u8 = "builtin";
2402 const builtin_str = try mod.intern_pool.getOrPutString(mod.gpa, "builtin");
24092403 const std_namespace = mod.namespacePtr(mod.declPtr(std_file.root_decl.unwrap().?).src_namespace);
24102404 const builtin_decl = std_namespace.decls
24112405 .getKeyAdapted(builtin_str, Module.DeclAdapter{ .mod = mod }).?;
24122406
2413 const stack_trace_str: []const u8 = "StackTrace";
2407 const stack_trace_str = try mod.intern_pool.getOrPutString(mod.gpa, "StackTrace");
24142408 // buffer is only used for int_type, `builtin` is a struct.
24152409 const builtin_ty = mod.declPtr(builtin_decl).val.toType();
24162410 const builtin_namespace = builtin_ty.getNamespace(mod).?;
......@@ -2452,16 +2446,13 @@ pub const DeclGen = struct {
24522446 const decl_index = dg.decl_index;
24532447 assert(decl.has_tv);
24542448
2455 log.debug("gen: {s} type: {}, value: {}", .{
2456 decl.name, decl.ty.fmtDebug(), decl.val.fmtDebug(),
2457 });
24582449 if (decl.val.getExternFunc(mod)) |extern_func| {
24592450 _ = try dg.resolveLlvmFunction(extern_func.decl);
24602451 } else {
24612452 const target = mod.getTarget();
24622453 var global = try dg.resolveGlobalDecl(decl_index);
24632454 global.setAlignment(decl.getAlignment(mod));
2464 if (decl.@"linksection") |section| global.setSection(section);
2455 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| global.setSection(s);
24652456 assert(decl.has_tv);
24662457 const init_val = if (decl.val.getVariable(mod)) |variable| init_val: {
24672458 break :init_val variable.init;
......@@ -2495,7 +2486,8 @@ pub const DeclGen = struct {
24952486 new_global.setLinkage(global.getLinkage());
24962487 new_global.setUnnamedAddr(global.getUnnamedAddress());
24972488 new_global.setAlignment(global.getAlignment());
2498 if (decl.@"linksection") |section| new_global.setSection(section);
2489 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
2490 new_global.setSection(s);
24992491 new_global.setInitializer(llvm_init);
25002492 // TODO: How should this work then the address space of a global changed?
25012493 global.replaceAllUsesWith(new_global);
......@@ -2513,7 +2505,7 @@ pub const DeclGen = struct {
25132505 const is_internal_linkage = !dg.module.decl_exports.contains(decl_index);
25142506 const di_global = dib.createGlobalVariableExpression(
25152507 di_file.toScope(),
2516 decl.name,
2508 mod.intern_pool.stringToSlice(decl.name),
25172509 global.getValueName(),
25182510 di_file,
25192511 line_number,
......@@ -2544,8 +2536,7 @@ pub const DeclGen = struct {
25442536
25452537 const fn_type = try dg.lowerType(zig_fn_type);
25462538
2547 const fqn = try decl.getFullyQualifiedName(mod);
2548 defer dg.gpa.free(fqn);
2539 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
25492540
25502541 const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
25512542 const llvm_fn = dg.llvmModule().addFunctionInAddressSpace(fqn, fn_type, llvm_addrspace);
......@@ -2557,7 +2548,7 @@ pub const DeclGen = struct {
25572548 llvm_fn.setUnnamedAddr(.True);
25582549 } else {
25592550 if (target.isWasm()) {
2560 dg.addFnAttrString(llvm_fn, "wasm-import-name", std.mem.sliceTo(decl.name, 0));
2551 dg.addFnAttrString(llvm_fn, "wasm-import-name", mod.intern_pool.stringToSlice(decl.name));
25612552 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
25622553 if (!std.mem.eql(u8, lib_name, "c")) {
25632554 dg.addFnAttrString(llvm_fn, "wasm-import-module", lib_name);
......@@ -2699,8 +2690,7 @@ pub const DeclGen = struct {
26992690
27002691 const mod = dg.module;
27012692 const decl = mod.declPtr(decl_index);
2702 const fqn = try decl.getFullyQualifiedName(mod);
2703 defer dg.gpa.free(fqn);
2693 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
27042694
27052695 const target = mod.getTarget();
27062696
......@@ -2716,7 +2706,7 @@ pub const DeclGen = struct {
27162706
27172707 // This is needed for declarations created by `@extern`.
27182708 if (decl.isExtern(mod)) {
2719 llvm_global.setValueName(decl.name);
2709 llvm_global.setValueName(mod.intern_pool.stringToSlice(decl.name));
27202710 llvm_global.setUnnamedAddr(.False);
27212711 llvm_global.setLinkage(.External);
27222712 if (decl.val.getVariable(mod)) |variable| {
......@@ -2811,8 +2801,7 @@ pub const DeclGen = struct {
28112801 if (gop.found_existing) return gop.value_ptr.*;
28122802
28132803 const opaque_type = mod.intern_pool.indexToKey(t.toIntern()).opaque_type;
2814 const name = try mod.opaqueFullyQualifiedName(opaque_type);
2815 defer gpa.free(name);
2804 const name = mod.intern_pool.stringToSlice(try mod.opaqueFullyQualifiedName(opaque_type));
28162805
28172806 const llvm_struct_ty = dg.context.structCreateNamed(name);
28182807 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
......@@ -2963,8 +2952,7 @@ pub const DeclGen = struct {
29632952 return int_llvm_ty;
29642953 }
29652954
2966 const name = try struct_obj.getFullyQualifiedName(mod);
2967 defer gpa.free(name);
2955 const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
29682956
29692957 const llvm_struct_ty = dg.context.structCreateNamed(name);
29702958 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
......@@ -3040,8 +3028,7 @@ pub const DeclGen = struct {
30403028 return enum_tag_llvm_ty;
30413029 }
30423030
3043 const name = try union_obj.getFullyQualifiedName(mod);
3044 defer gpa.free(name);
3031 const name = mod.intern_pool.stringToSlice(try union_obj.getFullyQualifiedName(mod));
30453032
30463033 const llvm_union_ty = dg.context.structCreateNamed(name);
30473034 gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls
......@@ -3119,7 +3106,7 @@ pub const DeclGen = struct {
31193106 if (fn_info.return_type.toType().isError(mod) and
31203107 mod.comp.bin_file.options.error_return_tracing)
31213108 {
3122 const ptr_ty = try mod.singleMutPtrType(dg.object.getStackTraceType());
3109 const ptr_ty = try mod.singleMutPtrType(try dg.object.getStackTraceType());
31233110 try llvm_params.append(try dg.lowerType(ptr_ty));
31243111 }
31253112
......@@ -3266,9 +3253,8 @@ pub const DeclGen = struct {
32663253 },
32673254 .err => |err| {
32683255 const llvm_ty = try dg.lowerType(Type.anyerror);
3269 const name = mod.intern_pool.stringToSlice(err.name);
3270 const kv = try mod.getErrorValue(name);
3271 return llvm_ty.constInt(kv.value, .False);
3256 const int = try mod.getErrorValue(err.name);
3257 return llvm_ty.constInt(int, .False);
32723258 },
32733259 .error_union => |error_union| {
32743260 const err_tv: TypedValue = switch (error_union.val) {
......@@ -5960,8 +5946,7 @@ pub const FuncGen = struct {
59605946 .base_line = self.base_line,
59615947 });
59625948
5963 const fqn = try decl.getFullyQualifiedName(mod);
5964 defer self.gpa.free(fqn);
5949 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
59655950
59665951 const is_internal_linkage = !mod.decl_exports.contains(decl_index);
59675952 const fn_ty = try mod.funcType(.{
......@@ -5981,7 +5966,7 @@ pub const FuncGen = struct {
59815966 });
59825967 const subprogram = dib.createFunction(
59835968 di_file.toScope(),
5984 decl.name,
5969 mod.intern_pool.stringToSlice(decl.name),
59855970 fqn,
59865971 di_file,
59875972 line_number,
......@@ -8629,9 +8614,8 @@ pub const FuncGen = struct {
86298614 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");
86308615 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
86318616
8632 for (names) |name_ip| {
8633 const name = mod.intern_pool.stringToSlice(name_ip);
8634 const err_int = mod.global_error_set.get(name).?;
8617 for (names) |name| {
8618 const err_int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);
86358619 const this_tag_int_value = try self.dg.lowerValue(.{
86368620 .ty = Type.err_int,
86378621 .val = try mod.intValue(Type.err_int, err_int),
......@@ -8681,8 +8665,7 @@ pub const FuncGen = struct {
86818665 defer arena_allocator.deinit();
86828666 const arena = arena_allocator.allocator();
86838667
8684 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
8685 defer self.gpa.free(fqn);
8668 const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod));
86868669 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});
86878670
86888671 const param_types = [_]*llvm.Type{try self.dg.lowerType(enum_type.tag_ty.toType())};
......@@ -8754,8 +8737,7 @@ pub const FuncGen = struct {
87548737 defer arena_allocator.deinit();
87558738 const arena = arena_allocator.allocator();
87568739
8757 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
8758 defer self.gpa.free(fqn);
8740 const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod));
87598741 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
87608742
87618743 const slice_ty = Type.slice_const_u8_sentinel_0;
src/codegen/spirv.zig+4-9
......@@ -593,7 +593,6 @@ pub const DeclGen = struct {
593593 .extern_func => unreachable, // TODO
594594 else => {
595595 const result_id = dg.spv.allocId();
596 log.debug("addDeclRef: id = {}, index = {}, name = {s}", .{ result_id.id, @enumToInt(spv_decl_index), decl.name });
597596
598597 try self.decl_deps.put(spv_decl_index, {});
599598
......@@ -664,9 +663,8 @@ pub const DeclGen = struct {
664663 => unreachable, // non-runtime values
665664 .int => try self.addInt(ty, val),
666665 .err => |err| {
667 const name = mod.intern_pool.stringToSlice(err.name);
668 const kv = try mod.getErrorValue(name);
669 try self.addConstInt(u16, @intCast(u16, kv.value));
666 const int = try mod.getErrorValue(err.name);
667 try self.addConstInt(u16, @intCast(u16, int));
670668 },
671669 .error_union => |error_union| {
672670 const payload_ty = ty.errorUnionPayload(mod);
......@@ -1288,8 +1286,7 @@ pub const DeclGen = struct {
12881286 member_index += 1;
12891287 }
12901288
1291 const name = try struct_obj.getFullyQualifiedName(self.module);
1292 defer self.module.gpa.free(name);
1289 const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(self.module));
12931290
12941291 return try self.spv.resolve(.{ .struct_type = .{
12951292 .name = try self.spv.resolveString(name),
......@@ -1500,7 +1497,6 @@ pub const DeclGen = struct {
15001497 const spv_decl_index = try self.resolveDecl(self.decl_index);
15011498
15021499 const decl_id = self.spv.declPtr(spv_decl_index).result_id;
1503 log.debug("genDecl: id = {}, index = {}, name = {s}", .{ decl_id.id, @enumToInt(spv_decl_index), decl.name });
15041500
15051501 if (decl.val.getFunction(mod)) |_| {
15061502 assert(decl.ty.zigTypeTag(mod) == .Fn);
......@@ -1542,8 +1538,7 @@ pub const DeclGen = struct {
15421538 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
15431539 try self.spv.addFunction(spv_decl_index, self.func);
15441540
1545 const fqn = try decl.getFullyQualifiedName(self.module);
1546 defer self.module.gpa.free(fqn);
1541 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(self.module));
15471542
15481543 try self.spv.sections.debug_names.emit(self.gpa, .OpName, .{
15491544 .target = decl_id,
src/link.zig-11
......@@ -502,8 +502,6 @@ pub const File = struct {
502502 /// of the final binary.
503503 pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: Module.Decl.Index) UpdateDeclError!u32 {
504504 if (build_options.only_c) @compileError("unreachable");
505 const decl = base.options.module.?.declPtr(decl_index);
506 log.debug("lowerUnnamedConst {*} ({s})", .{ decl, decl.name });
507505 switch (base.tag) {
508506 // zig fmt: off
509507 .coff => return @fieldParentPtr(Coff, "base", base).lowerUnnamedConst(tv, decl_index),
......@@ -543,7 +541,6 @@ pub const File = struct {
543541 /// May be called before or after updateDeclExports for any given Decl.
544542 pub fn updateDecl(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {
545543 const decl = module.declPtr(decl_index);
546 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty.fmt(module) });
547544 assert(decl.has_tv);
548545 if (build_options.only_c) {
549546 assert(base.tag == .c);
......@@ -566,10 +563,6 @@ pub const File = struct {
566563 /// May be called before or after updateDeclExports for any given Decl.
567564 pub fn updateFunc(base: *File, module: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) UpdateDeclError!void {
568565 const func = module.funcPtr(func_index);
569 const owner_decl = module.declPtr(func.owner_decl);
570 log.debug("updateFunc {*} ({s}), type={}", .{
571 owner_decl, owner_decl.name, owner_decl.ty.fmt(module),
572 });
573566 if (build_options.only_c) {
574567 assert(base.tag == .c);
575568 return @fieldParentPtr(C, "base", base).updateFunc(module, func, air, liveness);
......@@ -590,9 +583,6 @@ pub const File = struct {
590583
591584 pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {
592585 const decl = module.declPtr(decl_index);
593 log.debug("updateDeclLineNumber {*} ({s}), line={}", .{
594 decl, decl.name, decl.src_line + 1,
595 });
596586 assert(decl.has_tv);
597587 if (build_options.only_c) {
598588 assert(base.tag == .c);
......@@ -868,7 +858,6 @@ pub const File = struct {
868858 exports: []const *Module.Export,
869859 ) UpdateDeclExportsError!void {
870860 const decl = module.declPtr(decl_index);
871 log.debug("updateDeclExports {*} ({s})", .{ decl, decl.name });
872861 assert(decl.has_tv);
873862 if (build_options.only_c) {
874863 assert(base.tag == .c);
src/link/C.zig+5-4
......@@ -6,6 +6,7 @@ const fs = std.fs;
66
77const C = @This();
88const Module = @import("../Module.zig");
9const InternPool = @import("../InternPool.zig");
910const Compilation = @import("../Compilation.zig");
1011const codegen = @import("../codegen/c.zig");
1112const link = @import("../link.zig");
......@@ -289,11 +290,11 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
289290 }
290291
291292 {
292 var export_names = std.StringHashMapUnmanaged(void){};
293 var export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
293294 defer export_names.deinit(gpa);
294295 try export_names.ensureTotalCapacity(gpa, @intCast(u32, module.decl_exports.entries.len));
295296 for (module.decl_exports.values()) |exports| for (exports.items) |@"export"|
296 try export_names.put(gpa, @"export".options.name, {});
297 try export_names.put(gpa, @"export".name, {});
297298
298299 while (f.remaining_decls.popOrNull()) |kv| {
299300 const decl_index = kv.key;
......@@ -553,7 +554,7 @@ fn flushDecl(
553554 self: *C,
554555 f: *Flush,
555556 decl_index: Module.Decl.Index,
556 export_names: std.StringHashMapUnmanaged(void),
557 export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
557558) FlushDeclError!void {
558559 const gpa = self.base.allocator;
559560 const mod = self.base.options.module.?;
......@@ -571,7 +572,7 @@ fn flushDecl(
571572
572573 try self.flushLazyFns(f, decl_block.lazy_fns);
573574 try f.all_buffers.ensureUnusedCapacity(gpa, 1);
574 if (!(decl.isExtern(mod) and export_names.contains(mem.span(decl.name))))
575 if (!(decl.isExtern(mod) and export_names.contains(decl.name)))
575576 f.appendBufAssumeCapacity(decl_block.fwd_decl.items);
576577}
577578
src/link/Coff.zig+27-23
......@@ -1097,8 +1097,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
10971097 const atom_index = try self.createAtom();
10981098
10991099 const sym_name = blk: {
1100 const decl_name = try decl.getFullyQualifiedName(mod);
1101 defer gpa.free(decl_name);
1100 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
11021101
11031102 const index = unnamed_consts.items.len;
11041103 break :blk try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
......@@ -1324,12 +1323,10 @@ fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 {
13241323}
13251324
13261325fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []u8, complex_type: coff.ComplexType) !void {
1327 const gpa = self.base.allocator;
13281326 const mod = self.base.options.module.?;
13291327 const decl = mod.declPtr(decl_index);
13301328
1331 const decl_name = try decl.getFullyQualifiedName(mod);
1332 defer gpa.free(decl_name);
1329 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
13331330
13341331 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
13351332 const required_alignment = decl.getAlignment(mod);
......@@ -1420,6 +1417,8 @@ pub fn updateDeclExports(
14201417 @panic("Attempted to compile for object format that was disabled by build configuration");
14211418 }
14221419
1420 const ip = &mod.intern_pool;
1421
14231422 if (build_options.have_llvm) {
14241423 // Even in the case of LLVM, we need to notice certain exported symbols in order to
14251424 // detect the default subsystem.
......@@ -1431,20 +1430,20 @@ pub fn updateDeclExports(
14311430 else => std.builtin.CallingConvention.C,
14321431 };
14331432 const decl_cc = exported_decl.ty.fnCallingConvention(mod);
1434 if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and
1433 if (decl_cc == .C and ip.stringEqlSlice(exp.name, "main") and
14351434 self.base.options.link_libc)
14361435 {
14371436 mod.stage1_flags.have_c_main = true;
14381437 } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) {
1439 if (mem.eql(u8, exp.options.name, "WinMain")) {
1438 if (ip.stringEqlSlice(exp.name, "WinMain")) {
14401439 mod.stage1_flags.have_winmain = true;
1441 } else if (mem.eql(u8, exp.options.name, "wWinMain")) {
1440 } else if (ip.stringEqlSlice(exp.name, "wWinMain")) {
14421441 mod.stage1_flags.have_wwinmain = true;
1443 } else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) {
1442 } else if (ip.stringEqlSlice(exp.name, "WinMainCRTStartup")) {
14441443 mod.stage1_flags.have_winmain_crt_startup = true;
1445 } else if (mem.eql(u8, exp.options.name, "wWinMainCRTStartup")) {
1444 } else if (ip.stringEqlSlice(exp.name, "wWinMainCRTStartup")) {
14461445 mod.stage1_flags.have_wwinmain_crt_startup = true;
1447 } else if (mem.eql(u8, exp.options.name, "DllMainCRTStartup")) {
1446 } else if (ip.stringEqlSlice(exp.name, "DllMainCRTStartup")) {
14481447 mod.stage1_flags.have_dllmain_crt_startup = true;
14491448 }
14501449 }
......@@ -1453,9 +1452,6 @@ pub fn updateDeclExports(
14531452 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(mod, decl_index, exports);
14541453 }
14551454
1456 const tracy = trace(@src());
1457 defer tracy.end();
1458
14591455 const gpa = self.base.allocator;
14601456
14611457 const decl = mod.declPtr(decl_index);
......@@ -1465,12 +1461,13 @@ pub fn updateDeclExports(
14651461 const decl_metadata = self.decls.getPtr(decl_index).?;
14661462
14671463 for (exports) |exp| {
1468 log.debug("adding new export '{s}'", .{exp.options.name});
1464 const exp_name = mod.intern_pool.stringToSlice(exp.name);
1465 log.debug("adding new export '{s}'", .{exp_name});
14691466
1470 if (exp.options.section) |section_name| {
1467 if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
14711468 if (!mem.eql(u8, section_name, ".text")) {
14721469 try mod.failed_exports.putNoClobber(
1473 mod.gpa,
1470 gpa,
14741471 exp,
14751472 try Module.ErrorMsg.create(
14761473 gpa,
......@@ -1483,9 +1480,9 @@ pub fn updateDeclExports(
14831480 }
14841481 }
14851482
1486 if (exp.options.linkage == .LinkOnce) {
1483 if (exp.linkage == .LinkOnce) {
14871484 try mod.failed_exports.putNoClobber(
1488 mod.gpa,
1485 gpa,
14891486 exp,
14901487 try Module.ErrorMsg.create(
14911488 gpa,
......@@ -1497,19 +1494,19 @@ pub fn updateDeclExports(
14971494 continue;
14981495 }
14991496
1500 const sym_index = decl_metadata.getExport(self, exp.options.name) orelse blk: {
1497 const sym_index = decl_metadata.getExport(self, exp_name) orelse blk: {
15011498 const sym_index = try self.allocateSymbol();
15021499 try decl_metadata.exports.append(gpa, sym_index);
15031500 break :blk sym_index;
15041501 };
15051502 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };
15061503 const sym = self.getSymbolPtr(sym_loc);
1507 try self.setSymbolName(sym, exp.options.name);
1504 try self.setSymbolName(sym, exp_name);
15081505 sym.value = decl_sym.value;
15091506 sym.section_number = @intToEnum(coff.SectionNumber, self.text_section_index.? + 1);
15101507 sym.type = .{ .complex_type = .FUNCTION, .base_type = .NULL };
15111508
1512 switch (exp.options.linkage) {
1509 switch (exp.linkage) {
15131510 .Strong => {
15141511 sym.storage_class = .EXTERNAL;
15151512 },
......@@ -1522,9 +1519,15 @@ pub fn updateDeclExports(
15221519 }
15231520}
15241521
1525pub fn deleteDeclExport(self: *Coff, decl_index: Module.Decl.Index, name: []const u8) void {
1522pub fn deleteDeclExport(
1523 self: *Coff,
1524 decl_index: Module.Decl.Index,
1525 name_ip: InternPool.NullTerminatedString,
1526) void {
15261527 if (self.llvm_object) |_| return;
15271528 const metadata = self.decls.getPtr(decl_index) orelse return;
1529 const mod = self.base.options.module.?;
1530 const name = mod.intern_pool.stringToSlice(name_ip);
15281531 const sym_index = metadata.getExportPtr(self, name) orelse return;
15291532
15301533 const gpa = self.base.allocator;
......@@ -2540,6 +2543,7 @@ const ImportTable = @import("Coff/ImportTable.zig");
25402543const Liveness = @import("../Liveness.zig");
25412544const LlvmObject = @import("../codegen/llvm.zig").Object;
25422545const Module = @import("../Module.zig");
2546const InternPool = @import("../InternPool.zig");
25432547const Object = @import("Coff/Object.zig");
25442548const Relocation = @import("Coff/Relocation.zig");
25452549const TableSection = @import("table_section.zig").TableSection;
src/link/Dwarf.zig+8-17
......@@ -358,8 +358,9 @@ pub const DeclState = struct {
358358 struct_obj.fields.keys(),
359359 struct_obj.fields.values(),
360360 0..,
361 ) |field_name, field, field_index| {
361 ) |field_name_ip, field, field_index| {
362362 if (!field.ty.hasRuntimeBits(mod)) continue;
363 const field_name = mod.intern_pool.stringToSlice(field_name_ip);
363364 // DW.AT.member
364365 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
365366 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
......@@ -469,7 +470,8 @@ pub const DeclState = struct {
469470 // DW.AT.member
470471 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));
471472 // DW.AT.name, DW.FORM.string
472 try dbg_info_buffer.writer().print("{s}\x00", .{field_name});
473 try dbg_info_buffer.appendSlice(mod.intern_pool.stringToSlice(field_name));
474 try dbg_info_buffer.append(0);
473475 // DW.AT.type, DW.FORM.ref4
474476 const index = dbg_info_buffer.items.len;
475477 try dbg_info_buffer.resize(index + 4);
......@@ -949,8 +951,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
949951 defer tracy.end();
950952
951953 const decl = mod.declPtr(decl_index);
952 const decl_name = try decl.getFullyQualifiedName(mod);
953 defer self.allocator.free(decl_name);
954 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
954955
955956 log.debug("initDeclState {s}{*}", .{ decl_name, decl });
956957
......@@ -1273,7 +1274,6 @@ pub fn commitDeclState(
12731274 }
12741275 }
12751276
1276 log.debug("updateDeclDebugInfoAllocation for '{s}'", .{decl.name});
12771277 try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(u32, dbg_info_buffer.items.len));
12781278
12791279 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
......@@ -1345,7 +1345,6 @@ pub fn commitDeclState(
13451345 }
13461346 }
13471347
1348 log.debug("writeDeclDebugInfo for '{s}", .{decl.name});
13491348 try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);
13501349}
13511350
......@@ -2523,15 +2522,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
25232522
25242523 // TODO: don't create a zig type for this, just make the dwarf info
25252524 // without touching the zig type system.
2526 const names = try arena.alloc(InternPool.NullTerminatedString, module.global_error_set.count());
2527 {
2528 var it = module.global_error_set.keyIterator();
2529 var i: usize = 0;
2530 while (it.next()) |key| : (i += 1) {
2531 names[i] = module.intern_pool.getString(key.*).unwrap().?;
2532 }
2533 }
2534
2525 const names = try arena.dupe(InternPool.NullTerminatedString, module.global_error_set.keys());
25352526 std.mem.sort(InternPool.NullTerminatedString, names, {}, InternPool.NullTerminatedString.indexLessThan);
25362527
25372528 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });
......@@ -2682,8 +2673,8 @@ fn addDbgInfoErrorSet(
26822673
26832674 const error_names = ty.errorSetNames(mod);
26842675 for (error_names) |error_name_ip| {
2676 const int = try mod.getErrorValue(error_name_ip);
26852677 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
2686 const kv = mod.getErrorValue(error_name) catch unreachable;
26872678 // DW.AT.enumerator
26882679 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));
26892680 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
......@@ -2691,7 +2682,7 @@ fn addDbgInfoErrorSet(
26912682 dbg_info_buffer.appendSliceAssumeCapacity(error_name);
26922683 dbg_info_buffer.appendAssumeCapacity(0);
26932684 // DW.AT.const_value, DW.FORM.data8
2694 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), kv.value, target_endian);
2685 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), int, target_endian);
26952686 }
26962687
26972688 // DW.AT.enumeration_type delimit children
src/link/Elf.zig+18-15
......@@ -28,6 +28,7 @@ const File = link.File;
2828const Liveness = @import("../Liveness.zig");
2929const LlvmObject = @import("../codegen/llvm.zig").Object;
3030const Module = @import("../Module.zig");
31const InternPool = @import("../InternPool.zig");
3132const Package = @import("../Package.zig");
3233const StringTable = @import("strtab.zig").StringTable;
3334const TableSection = @import("table_section.zig").TableSection;
......@@ -2480,8 +2481,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
24802481 const mod = self.base.options.module.?;
24812482 const decl = mod.declPtr(decl_index);
24822483
2483 const decl_name = try decl.getFullyQualifiedName(mod);
2484 defer self.base.allocator.free(decl_name);
2484 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
24852485
24862486 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
24872487 const required_alignment = decl.getAlignment(mod);
......@@ -2802,8 +2802,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
28022802
28032803 const decl = mod.declPtr(decl_index);
28042804 const name_str_index = blk: {
2805 const decl_name = try decl.getFullyQualifiedName(mod);
2806 defer gpa.free(decl_name);
2805 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
28072806 const index = unnamed_consts.items.len;
28082807 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
28092808 defer gpa.free(name);
......@@ -2880,7 +2879,8 @@ pub fn updateDeclExports(
28802879 try self.global_symbols.ensureUnusedCapacity(gpa, exports.len);
28812880
28822881 for (exports) |exp| {
2883 if (exp.options.section) |section_name| {
2882 const exp_name = mod.intern_pool.stringToSlice(exp.name);
2883 if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
28842884 if (!mem.eql(u8, section_name, ".text")) {
28852885 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
28862886 mod.failed_exports.putAssumeCapacityNoClobber(
......@@ -2890,11 +2890,11 @@ pub fn updateDeclExports(
28902890 continue;
28912891 }
28922892 }
2893 const stb_bits: u8 = switch (exp.options.linkage) {
2893 const stb_bits: u8 = switch (exp.linkage) {
28942894 .Internal => elf.STB_LOCAL,
28952895 .Strong => blk: {
28962896 const entry_name = self.base.options.entry orelse "_start";
2897 if (mem.eql(u8, exp.options.name, entry_name)) {
2897 if (mem.eql(u8, exp_name, entry_name)) {
28982898 self.entry_addr = decl_sym.st_value;
28992899 }
29002900 break :blk elf.STB_GLOBAL;
......@@ -2910,10 +2910,10 @@ pub fn updateDeclExports(
29102910 },
29112911 };
29122912 const stt_bits: u8 = @truncate(u4, decl_sym.st_info);
2913 if (decl_metadata.getExport(self, exp.options.name)) |i| {
2913 if (decl_metadata.getExport(self, exp_name)) |i| {
29142914 const sym = &self.global_symbols.items[i];
29152915 sym.* = .{
2916 .st_name = try self.shstrtab.insert(gpa, exp.options.name),
2916 .st_name = try self.shstrtab.insert(gpa, exp_name),
29172917 .st_info = (stb_bits << 4) | stt_bits,
29182918 .st_other = 0,
29192919 .st_shndx = shdr_index,
......@@ -2927,7 +2927,7 @@ pub fn updateDeclExports(
29272927 };
29282928 try decl_metadata.exports.append(gpa, @intCast(u32, i));
29292929 self.global_symbols.items[i] = .{
2930 .st_name = try self.shstrtab.insert(gpa, exp.options.name),
2930 .st_name = try self.shstrtab.insert(gpa, exp_name),
29312931 .st_info = (stb_bits << 4) | stt_bits,
29322932 .st_other = 0,
29332933 .st_shndx = shdr_index,
......@@ -2944,8 +2944,7 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: Module.Decl.In
29442944 defer tracy.end();
29452945
29462946 const decl = mod.declPtr(decl_index);
2947 const decl_name = try decl.getFullyQualifiedName(mod);
2948 defer self.base.allocator.free(decl_name);
2947 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
29492948
29502949 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
29512950
......@@ -2955,11 +2954,15 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: Module.Decl.In
29552954 }
29562955}
29572956
2958pub fn deleteDeclExport(self: *Elf, decl_index: Module.Decl.Index, name: []const u8) void {
2957pub fn deleteDeclExport(
2958 self: *Elf,
2959 decl_index: Module.Decl.Index,
2960 name: InternPool.NullTerminatedString,
2961) void {
29592962 if (self.llvm_object) |_| return;
29602963 const metadata = self.decls.getPtr(decl_index) orelse return;
2961 const sym_index = metadata.getExportPtr(self, name) orelse return;
2962 log.debug("deleting export '{s}'", .{name});
2964 const mod = self.base.options.module.?;
2965 const sym_index = metadata.getExportPtr(self, mod.intern_pool.stringToSlice(name)) orelse return;
29632966 self.global_symbol_free_list.append(self.base.allocator, sym_index.*) catch {};
29642967 self.global_symbols.items[sym_index.*].st_info = 0;
29652968 sym_index.* = 0;
src/link/MachO.zig+17-12
......@@ -40,6 +40,7 @@ const Liveness = @import("../Liveness.zig");
4040const LlvmObject = @import("../codegen/llvm.zig").Object;
4141const Md5 = std.crypto.hash.Md5;
4242const Module = @import("../Module.zig");
43const InternPool = @import("../InternPool.zig");
4344const Relocation = @import("MachO/Relocation.zig");
4445const StringTable = @import("strtab.zig").StringTable;
4546const TableSection = @import("table_section.zig").TableSection;
......@@ -1921,8 +1922,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
19211922 const unnamed_consts = gop.value_ptr;
19221923
19231924 const decl = mod.declPtr(decl_index);
1924 const decl_name = try decl.getFullyQualifiedName(mod);
1925 defer gpa.free(decl_name);
1925 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
19261926
19271927 const name_str_index = blk: {
19281928 const index = unnamed_consts.items.len;
......@@ -2206,8 +2206,7 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D
22062206
22072207 const required_alignment = decl.getAlignment(mod);
22082208
2209 const decl_name = try decl.getFullyQualifiedName(module);
2210 defer gpa.free(decl_name);
2209 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(module));
22112210
22122211 const init_sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{decl_name});
22132212 defer gpa.free(init_sym_name);
......@@ -2306,8 +2305,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
23062305
23072306 const required_alignment = decl.getAlignment(mod);
23082307
2309 const decl_name = try decl.getFullyQualifiedName(mod);
2310 defer gpa.free(decl_name);
2308 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
23112309
23122310 const decl_metadata = self.decls.get(decl_index).?;
23132311 const atom_index = decl_metadata.atom;
......@@ -2403,12 +2401,14 @@ pub fn updateDeclExports(
24032401 const decl_metadata = self.decls.getPtr(decl_index).?;
24042402
24052403 for (exports) |exp| {
2406 const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{exp.options.name});
2404 const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{
2405 mod.intern_pool.stringToSlice(exp.name),
2406 });
24072407 defer gpa.free(exp_name);
24082408
24092409 log.debug("adding new export '{s}'", .{exp_name});
24102410
2411 if (exp.options.section) |section_name| {
2411 if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
24122412 if (!mem.eql(u8, section_name, "__text")) {
24132413 try mod.failed_exports.putNoClobber(
24142414 mod.gpa,
......@@ -2424,7 +2424,7 @@ pub fn updateDeclExports(
24242424 }
24252425 }
24262426
2427 if (exp.options.linkage == .LinkOnce) {
2427 if (exp.linkage == .LinkOnce) {
24282428 try mod.failed_exports.putNoClobber(
24292429 mod.gpa,
24302430 exp,
......@@ -2453,7 +2453,7 @@ pub fn updateDeclExports(
24532453 .n_value = decl_sym.n_value,
24542454 };
24552455
2456 switch (exp.options.linkage) {
2456 switch (exp.linkage) {
24572457 .Internal => {
24582458 // Symbol should be hidden, or in MachO lingo, private extern.
24592459 // We should also mark the symbol as Weak: n_desc == N_WEAK_DEF.
......@@ -2488,12 +2488,17 @@ pub fn updateDeclExports(
24882488 }
24892489}
24902490
2491pub fn deleteDeclExport(self: *MachO, decl_index: Module.Decl.Index, name: []const u8) Allocator.Error!void {
2491pub fn deleteDeclExport(
2492 self: *MachO,
2493 decl_index: Module.Decl.Index,
2494 name: InternPool.NullTerminatedString,
2495) Allocator.Error!void {
24922496 if (self.llvm_object) |_| return;
24932497 const metadata = self.decls.getPtr(decl_index) orelse return;
24942498
24952499 const gpa = self.base.allocator;
2496 const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
2500 const mod = self.base.options.module.?;
2501 const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{mod.intern_pool.stringToSlice(name)});
24972502 defer gpa.free(exp_name);
24982503 const sym_index = metadata.getExportPtr(self, exp_name) orelse return;
24992504
src/link/Plan9.zig+11-19
......@@ -287,7 +287,6 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: Module.Fn.Index, air:
287287 self.freeUnnamedConsts(decl_index);
288288
289289 _ = try self.seeDecl(decl_index);
290 log.debug("codegen decl {*} ({s})", .{ decl, decl.name });
291290
292291 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
293292 defer code_buffer.deinit();
......@@ -345,8 +344,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I
345344 }
346345 const unnamed_consts = gop.value_ptr;
347346
348 const decl_name = try decl.getFullyQualifiedName(mod);
349 defer self.base.allocator.free(decl_name);
347 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
350348
351349 const index = unnamed_consts.items.len;
352350 // name is freed when the unnamed const is freed
......@@ -403,8 +401,6 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !vo
403401
404402 _ = try self.seeDecl(decl_index);
405403
406 log.debug("codegen decl {*} ({s}) ({d})", .{ decl, decl.name, decl_index });
407
408404 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
409405 defer code_buffer.deinit();
410406 const decl_val = if (decl.val.getVariable(mod)) |variable| variable.init.toValue() else decl.val;
......@@ -435,7 +431,6 @@ fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void {
435431 const mod = self.base.options.module.?;
436432 const decl = mod.declPtr(decl_index);
437433 const is_fn = (decl.ty.zigTypeTag(mod) == .Fn);
438 log.debug("update the symbol table and got for decl {*} ({s})", .{ decl, decl.name });
439434 const sym_t: aout.Sym.Type = if (is_fn) .t else .d;
440435
441436 const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);
......@@ -446,7 +441,7 @@ fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void {
446441 const sym: aout.Sym = .{
447442 .value = undefined, // the value of stuff gets filled in in flushModule
448443 .type = decl_block.type,
449 .name = mem.span(decl.name),
444 .name = mod.intern_pool.stringToSlice(decl.name),
450445 };
451446
452447 if (decl_block.sym_index) |s| {
......@@ -567,10 +562,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
567562 var it = fentry.value_ptr.functions.iterator();
568563 while (it.next()) |entry| {
569564 const decl_index = entry.key_ptr.*;
570 const decl = mod.declPtr(decl_index);
571565 const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);
572566 const out = entry.value_ptr.*;
573 log.debug("write text decl {*} ({s}), lines {d} to {d}", .{ decl, decl.name, out.start_line + 1, out.end_line });
574567 {
575568 // connect the previous decl to the next
576569 const delta_line = @intCast(i32, out.start_line) - @intCast(i32, linecount);
......@@ -616,10 +609,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
616609 var it = self.data_decl_table.iterator();
617610 while (it.next()) |entry| {
618611 const decl_index = entry.key_ptr.*;
619 const decl = mod.declPtr(decl_index);
620612 const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);
621613 const code = entry.value_ptr.*;
622 log.debug("write data decl {*} ({s})", .{ decl, decl.name });
623614
624615 foff += code.len;
625616 iovecs[iovecs_i] = .{ .iov_base = code.ptr, .iov_len = code.len };
......@@ -695,15 +686,12 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
695686 const source_decl = mod.declPtr(source_decl_index);
696687 for (kv.value_ptr.items) |reloc| {
697688 const target_decl_index = reloc.target;
698 const target_decl = mod.declPtr(target_decl_index);
699689 const target_decl_block = self.getDeclBlock(self.decls.get(target_decl_index).?.index);
700690 const target_decl_offset = target_decl_block.offset.?;
701691
702692 const offset = reloc.offset;
703693 const addend = reloc.addend;
704694
705 log.debug("relocating the address of '{s}' + {d} into '{s}' + {d}", .{ target_decl.name, addend, source_decl.name, offset });
706
707695 const code = blk: {
708696 const is_fn = source_decl.ty.zigTypeTag(mod) == .Fn;
709697 if (is_fn) {
......@@ -737,8 +725,9 @@ fn addDeclExports(
737725 const decl_block = self.getDeclBlock(metadata.index);
738726
739727 for (exports) |exp| {
728 const exp_name = mod.intern_pool.stringToSlice(exp.name);
740729 // plan9 does not support custom sections
741 if (exp.options.section) |section_name| {
730 if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
742731 if (!mem.eql(u8, section_name, ".text") or !mem.eql(u8, section_name, ".data")) {
743732 try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
744733 self.base.allocator,
......@@ -752,10 +741,10 @@ fn addDeclExports(
752741 const sym = .{
753742 .value = decl_block.offset.?,
754743 .type = decl_block.type.toGlobal(),
755 .name = exp.options.name,
744 .name = exp_name,
756745 };
757746
758 if (metadata.getExport(self, exp.options.name)) |i| {
747 if (metadata.getExport(self, exp_name)) |i| {
759748 self.syms.items[i] = sym;
760749 } else {
761750 try self.syms.append(self.base.allocator, sym);
......@@ -956,7 +945,10 @@ pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void {
956945 try w.writeAll(sym.name);
957946 try w.writeByte(0);
958947}
948
959949pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
950 const mod = self.base.options.module.?;
951 const ip = &mod.intern_pool;
960952 const writer = buf.writer();
961953 // write the f symbols
962954 {
......@@ -980,7 +972,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
980972 const sym = self.syms.items[decl_block.sym_index.?];
981973 try self.writeSym(writer, sym);
982974 if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {
983 for (exports.items) |e| if (decl_metadata.getExport(self, e.options.name)) |exp_i| {
975 for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.name))) |exp_i| {
984976 try self.writeSym(writer, self.syms.items[exp_i]);
985977 };
986978 }
......@@ -1006,7 +998,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
1006998 const sym = self.syms.items[decl_block.sym_index.?];
1007999 try self.writeSym(writer, sym);
10081000 if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {
1009 for (exports.items) |e| if (decl_metadata.getExport(self, e.options.name)) |exp_i| {
1001 for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.name))) |exp_i| {
10101002 const s = self.syms.items[exp_i];
10111003 if (mem.eql(u8, s.name, "_start"))
10121004 self.entry_val = s.value;
src/link/SpirV.zig+3-2
......@@ -147,7 +147,7 @@ pub fn updateDeclExports(
147147 const spv_decl_index = entry.value_ptr.*;
148148
149149 for (exports) |exp| {
150 try self.spv.declareEntryPoint(spv_decl_index, exp.options.name);
150 try self.spv.declareEntryPoint(spv_decl_index, mod.intern_pool.stringToSlice(exp.name));
151151 }
152152 }
153153
......@@ -190,7 +190,8 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
190190 var error_info = std.ArrayList(u8).init(self.spv.arena);
191191 try error_info.appendSlice("zig_errors");
192192 const module = self.base.options.module.?;
193 for (module.error_name_list.items) |name| {
193 for (module.global_error_set.keys()) |name_nts| {
194 const name = module.intern_pool.stringToSlice(name_nts);
194195 // Errors can contain pretty much any character - to encode them in a string we must escape
195196 // them somehow. Easiest here is to use some established scheme, one which also preseves the
196197 // name if it contains no strange characters is nice for debugging. URI encoding fits the bill.
src/link/Wasm.zig+23-22
......@@ -1416,7 +1416,7 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi
14161416
14171417 if (decl.isExtern(mod)) {
14181418 const variable = decl.getOwnedVariable(mod).?;
1419 const name = mem.sliceTo(decl.name, 0);
1419 const name = mod.intern_pool.stringToSlice(decl.name);
14201420 const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);
14211421 return wasm.addOrUpdateImport(name, atom.sym_index, lib_name, null);
14221422 }
......@@ -1453,8 +1453,7 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.I
14531453 defer tracy.end();
14541454
14551455 const decl = mod.declPtr(decl_index);
1456 const decl_name = try decl.getFullyQualifiedName(mod);
1457 defer wasm.base.allocator.free(decl_name);
1456 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
14581457
14591458 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
14601459 try dw.updateDeclLineNumber(mod, decl_index);
......@@ -1467,8 +1466,7 @@ fn finishUpdateDecl(wasm: *Wasm, decl_index: Module.Decl.Index, code: []const u8
14671466 const atom_index = wasm.decls.get(decl_index).?;
14681467 const atom = wasm.getAtomPtr(atom_index);
14691468 const symbol = &wasm.symbols.items[atom.sym_index];
1470 const full_name = try decl.getFullyQualifiedName(mod);
1471 defer wasm.base.allocator.free(full_name);
1469 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
14721470 symbol.name = try wasm.string_table.put(wasm.base.allocator, full_name);
14731471 try atom.code.appendSlice(wasm.base.allocator, code);
14741472 try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {});
......@@ -1535,9 +1533,10 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In
15351533 const parent_atom = wasm.getAtomPtr(parent_atom_index);
15361534 const local_index = parent_atom.locals.items.len;
15371535 try parent_atom.locals.append(wasm.base.allocator, atom_index);
1538 const fqdn = try decl.getFullyQualifiedName(mod);
1539 defer wasm.base.allocator.free(fqdn);
1540 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{ fqdn, local_index });
1536 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1537 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{
1538 fqn, local_index,
1539 });
15411540 defer wasm.base.allocator.free(name);
15421541 var value_bytes = std.ArrayList(u8).init(wasm.base.allocator);
15431542 defer value_bytes.deinit();
......@@ -1690,11 +1689,12 @@ pub fn updateDeclExports(
16901689 const decl = mod.declPtr(decl_index);
16911690 const atom_index = try wasm.getOrCreateAtomForDecl(decl_index);
16921691 const atom = wasm.getAtom(atom_index);
1692 const gpa = mod.gpa;
16931693
16941694 for (exports) |exp| {
1695 if (exp.options.section) |section| {
1696 try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(
1697 mod.gpa,
1695 if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section| {
1696 try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create(
1697 gpa,
16981698 decl.srcLoc(mod),
16991699 "Unimplemented: ExportOptions.section '{s}'",
17001700 .{section},
......@@ -1702,24 +1702,24 @@ pub fn updateDeclExports(
17021702 continue;
17031703 }
17041704
1705 const export_name = try wasm.string_table.put(wasm.base.allocator, exp.options.name);
1705 const export_name = try wasm.string_table.put(wasm.base.allocator, mod.intern_pool.stringToSlice(exp.name));
17061706 if (wasm.globals.getPtr(export_name)) |existing_loc| {
17071707 if (existing_loc.index == atom.sym_index) continue;
17081708 const existing_sym: Symbol = existing_loc.getSymbol(wasm).*;
17091709
1710 const exp_is_weak = exp.options.linkage == .Internal or exp.options.linkage == .Weak;
1710 const exp_is_weak = exp.linkage == .Internal or exp.linkage == .Weak;
17111711 // When both the to-be-exported symbol and the already existing symbol
17121712 // are strong symbols, we have a linker error.
17131713 // In the other case we replace one with the other.
17141714 if (!exp_is_weak and !existing_sym.isWeak()) {
1715 try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
1716 mod.gpa,
1715 try mod.failed_exports.put(gpa, exp, try Module.ErrorMsg.create(
1716 gpa,
17171717 decl.srcLoc(mod),
17181718 \\LinkError: symbol '{s}' defined multiple times
17191719 \\ first definition in '{s}'
17201720 \\ next definition in '{s}'
17211721 ,
1722 .{ exp.options.name, wasm.name, wasm.name },
1722 .{ mod.intern_pool.stringToSlice(exp.name), wasm.name, wasm.name },
17231723 ));
17241724 continue;
17251725 } else if (exp_is_weak) {
......@@ -1736,7 +1736,7 @@ pub fn updateDeclExports(
17361736 const exported_atom = wasm.getAtom(exported_atom_index);
17371737 const sym_loc = exported_atom.symbolLoc();
17381738 const symbol = sym_loc.getSymbol(wasm);
1739 switch (exp.options.linkage) {
1739 switch (exp.linkage) {
17401740 .Internal => {
17411741 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
17421742 },
......@@ -1745,8 +1745,8 @@ pub fn updateDeclExports(
17451745 },
17461746 .Strong => {}, // symbols are strong by default
17471747 .LinkOnce => {
1748 try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(
1749 mod.gpa,
1748 try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create(
1749 gpa,
17501750 decl.srcLoc(mod),
17511751 "Unimplemented: LinkOnce",
17521752 .{},
......@@ -1755,7 +1755,7 @@ pub fn updateDeclExports(
17551755 },
17561756 }
17571757 // Ensure the symbol will be exported using the given name
1758 if (!mem.eql(u8, exp.options.name, sym_loc.getName(wasm))) {
1758 if (!mod.intern_pool.stringEqlSlice(exp.name, sym_loc.getName(wasm))) {
17591759 try wasm.export_names.put(wasm.base.allocator, sym_loc, export_name);
17601760 }
17611761
......@@ -1769,7 +1769,7 @@ pub fn updateDeclExports(
17691769
17701770 // if the symbol was previously undefined, remove it as an import
17711771 _ = wasm.imports.remove(sym_loc);
1772 _ = wasm.undefs.swapRemove(exp.options.name);
1772 _ = wasm.undefs.swapRemove(mod.intern_pool.stringToSlice(exp.name));
17731773 }
17741774}
17751775
......@@ -2987,7 +2987,8 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
29872987 // Addend for each relocation to the table
29882988 var addend: u32 = 0;
29892989 const mod = wasm.base.options.module.?;
2990 for (mod.error_name_list.items) |error_name| {
2990 for (mod.global_error_set.keys()) |error_name_nts| {
2991 const error_name = mod.intern_pool.stringToSlice(error_name_nts);
29912992 const len = @intCast(u32, error_name.len + 1); // names are 0-termianted
29922993
29932994 const slice_ty = Type.slice_const_u8_sentinel_0;
src/print_air.zig+2-1
......@@ -685,8 +685,9 @@ const Writer = struct {
685685 fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
686686 const ty_fn = w.air.instructions.items(.data)[inst].ty_fn;
687687 const func_index = ty_fn.func;
688 const ip = &w.module.intern_pool;
688689 const owner_decl = w.module.declPtr(w.module.funcPtr(func_index).owner_decl);
689 try s.print("{s}", .{owner_decl.name});
690 try s.print("{s}", .{ip.stringToSlice(owner_decl.name)});
690691 }
691692
692693 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/type.zig+14-18
......@@ -2546,7 +2546,7 @@ pub const Type = struct {
25462546 defer mod.gpa.free(field_vals);
25472547 for (field_vals, s.fields.values()) |*field_val, field| {
25482548 if (field.is_comptime) {
2549 field_val.* = try field.default_val.intern(field.ty, mod);
2549 field_val.* = field.default_val;
25502550 continue;
25512551 }
25522552 if (try field.ty.onePossibleValue(mod)) |field_opv| {
......@@ -2977,18 +2977,14 @@ pub const Type = struct {
29772977 return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names.len;
29782978 }
29792979
2980 pub fn enumFieldName(ty: Type, field_index: usize, mod: *Module) [:0]const u8 {
2981 const ip = &mod.intern_pool;
2982 const field_name = ip.indexToKey(ty.toIntern()).enum_type.names[field_index];
2983 return ip.stringToSlice(field_name);
2980 pub fn enumFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString {
2981 return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names[field_index];
29842982 }
29852983
2986 pub fn enumFieldIndex(ty: Type, field_name: []const u8, mod: *Module) ?u32 {
2984 pub fn enumFieldIndex(ty: Type, field_name: InternPool.NullTerminatedString, mod: *Module) ?u32 {
29872985 const ip = &mod.intern_pool;
29882986 const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
2989 // If the string is not interned, then the field certainly is not present.
2990 const field_name_interned = ip.getString(field_name).unwrap() orelse return null;
2991 return enum_type.nameIndex(ip, field_name_interned);
2987 return enum_type.nameIndex(ip, field_name);
29922988 }
29932989
29942990 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
......@@ -3017,19 +3013,16 @@ pub const Type = struct {
30173013 }
30183014 }
30193015
3020 pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) []const u8 {
3021 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3016 pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString {
3017 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
30223018 .struct_type => |struct_type| {
30233019 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
30243020 assert(struct_obj.haveFieldTypes());
30253021 return struct_obj.fields.keys()[field_index];
30263022 },
3027 .anon_struct_type => |anon_struct| {
3028 const name = anon_struct.names[field_index];
3029 return mod.intern_pool.stringToSlice(name);
3030 },
3023 .anon_struct_type => |anon_struct| anon_struct.names[field_index],
30313024 else => unreachable,
3032 }
3025 };
30333026 }
30343027
30353028 pub fn structFieldCount(ty: Type, mod: *Module) usize {
......@@ -3082,7 +3075,10 @@ pub const Type = struct {
30823075 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
30833076 .struct_type => |struct_type| {
30843077 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3085 return struct_obj.fields.values()[index].default_val;
3078 const val = struct_obj.fields.values()[index].default_val;
3079 // TODO: avoid using `unreachable` to indicate this.
3080 if (val == .none) return Value.@"unreachable";
3081 return val.toValue();
30863082 },
30873083 .anon_struct_type => |anon_struct| {
30883084 const val = anon_struct.values[index];
......@@ -3100,7 +3096,7 @@ pub const Type = struct {
31003096 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
31013097 const field = struct_obj.fields.values()[index];
31023098 if (field.is_comptime) {
3103 return field.default_val;
3099 return field.default_val.toValue();
31043100 } else {
31053101 return field.ty.onePossibleValue(mod);
31063102 }
src/value.zig+70-46
......@@ -24,9 +24,6 @@ pub const Value = struct {
2424 /// This union takes advantage of the fact that the first page of memory
2525 /// is unmapped, giving us 4096 possible enum tags that have no payload.
2626 legacy: extern union {
27 /// If the tag value is less than Tag.no_payload_count, then no pointer
28 /// dereference is needed.
29 tag_if_small_enough: Tag,
3027 ptr_otherwise: *Payload,
3128 },
3229
......@@ -64,8 +61,6 @@ pub const Value = struct {
6461 /// An instance of a union.
6562 @"union",
6663
67 pub const no_payload_count = 0;
68
6964 pub fn Type(comptime t: Tag) type {
7065 return switch (t) {
7166 .eu_payload,
......@@ -96,16 +91,7 @@ pub const Value = struct {
9691 }
9792 };
9893
99 pub fn initTag(small_tag: Tag) Value {
100 assert(@enumToInt(small_tag) < Tag.no_payload_count);
101 return Value{
102 .ip_index = .none,
103 .legacy = .{ .tag_if_small_enough = small_tag },
104 };
105 }
106
10794 pub fn initPayload(payload: *Payload) Value {
108 assert(@enumToInt(payload.tag) >= Tag.no_payload_count);
10995 return Value{
11096 .ip_index = .none,
11197 .legacy = .{ .ptr_otherwise = payload },
......@@ -114,11 +100,7 @@ pub const Value = struct {
114100
115101 pub fn tag(self: Value) Tag {
116102 assert(self.ip_index == .none);
117 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
118 return self.legacy.tag_if_small_enough;
119 } else {
120 return self.legacy.ptr_otherwise.tag;
121 }
103 return self.legacy.ptr_otherwise.tag;
122104 }
123105
124106 /// Prefer `castTag` to this.
......@@ -129,12 +111,7 @@ pub const Value = struct {
129111 if (@hasField(T, "base_tag")) {
130112 return self.castTag(T.base_tag);
131113 }
132 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
133 return null;
134 }
135114 inline for (@typeInfo(Tag).Enum.fields) |field| {
136 if (field.value < Tag.no_payload_count)
137 continue;
138115 const t = @intToEnum(Tag, field.value);
139116 if (self.legacy.ptr_otherwise.tag == t) {
140117 if (T == t.Type()) {
......@@ -149,9 +126,6 @@ pub const Value = struct {
149126 pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() {
150127 if (self.ip_index != .none) return null;
151128
152 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count)
153 return null;
154
155129 if (self.legacy.ptr_otherwise.tag == t)
156130 return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);
157131
......@@ -164,12 +138,7 @@ pub const Value = struct {
164138 if (self.ip_index != .none) {
165139 return Value{ .ip_index = self.ip_index, .legacy = undefined };
166140 }
167 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
168 return Value{
169 .ip_index = .none,
170 .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough },
171 };
172 } else switch (self.legacy.ptr_otherwise.tag) {
141 switch (self.legacy.ptr_otherwise.tag) {
173142 .bytes => {
174143 const bytes = self.castTag(.bytes).?.data;
175144 const new_payload = try arena.create(Payload.Bytes);
......@@ -312,6 +281,30 @@ pub const Value = struct {
312281 } };
313282 }
314283
284 /// Asserts that the value is representable as an array of bytes.
285 /// Returns the value as a null-terminated string stored in the InternPool.
286 pub fn toIpString(val: Value, ty: Type, mod: *Module) !InternPool.NullTerminatedString {
287 const ip = &mod.intern_pool;
288 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
289 .enum_literal => |enum_literal| enum_literal,
290 .ptr => |ptr| switch (ptr.len) {
291 .none => unreachable,
292 else => try arrayToIpString(val, ptr.len.toValue().toUnsignedInt(mod), mod),
293 },
294 .aggregate => |aggregate| switch (aggregate.storage) {
295 .bytes => |bytes| try ip.getOrPutString(mod.gpa, bytes),
296 .elems => try arrayToIpString(val, ty.arrayLen(mod), mod),
297 .repeated_elem => |elem| {
298 const byte = @intCast(u8, elem.toValue().toUnsignedInt(mod));
299 const len = @intCast(usize, ty.arrayLen(mod));
300 try ip.string_bytes.appendNTimes(mod.gpa, byte, len);
301 return ip.getOrPutTrailingString(mod.gpa, len);
302 },
303 },
304 else => unreachable,
305 };
306 }
307
315308 /// Asserts that the value is representable as an array of bytes.
316309 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
317310 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {
......@@ -319,11 +312,11 @@ pub const Value = struct {
319312 .enum_literal => |enum_literal| allocator.dupe(u8, mod.intern_pool.stringToSlice(enum_literal)),
320313 .ptr => |ptr| switch (ptr.len) {
321314 .none => unreachable,
322 else => arrayToAllocatedBytes(val, ptr.len.toValue().toUnsignedInt(mod), allocator, mod),
315 else => try arrayToAllocatedBytes(val, ptr.len.toValue().toUnsignedInt(mod), allocator, mod),
323316 },
324317 .aggregate => |aggregate| switch (aggregate.storage) {
325318 .bytes => |bytes| try allocator.dupe(u8, bytes),
326 .elems => arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod),
319 .elems => try arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod),
327320 .repeated_elem => |elem| {
328321 const byte = @intCast(u8, elem.toValue().toUnsignedInt(mod));
329322 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen(mod)));
......@@ -344,6 +337,23 @@ pub const Value = struct {
344337 return result;
345338 }
346339
340 fn arrayToIpString(val: Value, len_u64: u64, mod: *Module) !InternPool.NullTerminatedString {
341 const gpa = mod.gpa;
342 const ip = &mod.intern_pool;
343 const len = @intCast(usize, len_u64);
344 try ip.string_bytes.ensureUnusedCapacity(gpa, len);
345 for (0..len) |i| {
346 // I don't think elemValue has the possibility to affect ip.string_bytes. Let's
347 // assert just to be sure.
348 const prev = ip.string_bytes.items.len;
349 const elem_val = try val.elemValue(mod, i);
350 assert(ip.string_bytes.items.len == prev);
351 const byte = @intCast(u8, elem_val.toUnsignedInt(mod));
352 ip.string_bytes.appendAssumeCapacity(byte);
353 }
354 return ip.getOrPutTrailingString(gpa, len);
355 }
356
347357 pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
348358 if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern();
349359 switch (val.tag()) {
......@@ -498,7 +508,7 @@ pub const Value = struct {
498508 // Assume it is already an integer and return it directly.
499509 .simple_type, .int_type => val,
500510 .enum_literal => |enum_literal| {
501 const field_index = ty.enumFieldIndex(ip.stringToSlice(enum_literal), mod).?;
511 const field_index = ty.enumFieldIndex(enum_literal, mod).?;
502512 return switch (ip.indexToKey(ty.toIntern())) {
503513 // Assume it is already an integer and return it directly.
504514 .simple_type, .int_type => val,
......@@ -776,7 +786,7 @@ pub const Value = struct {
776786 .error_union => |error_union| error_union.val.err_name,
777787 else => unreachable,
778788 };
779 const int = mod.global_error_set.get(mod.intern_pool.stringToSlice(name)).?;
789 const int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);
780790 std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], @intCast(Int, int), endian);
781791 },
782792 .Union => switch (ty.containerLayout(mod)) {
......@@ -1028,10 +1038,10 @@ pub const Value = struct {
10281038 // TODO revisit this when we have the concept of the error tag type
10291039 const Int = u16;
10301040 const int = std.mem.readInt(Int, buffer[0..@sizeOf(Int)], endian);
1031 const name = mod.error_name_list.items[@intCast(usize, int)];
1041 const name = mod.global_error_set.keys()[@intCast(usize, int)];
10321042 return (try mod.intern(.{ .err = .{
10331043 .ty = ty.toIntern(),
1034 .name = mod.intern_pool.getString(name).unwrap().?,
1044 .name = name,
10351045 } })).toValue();
10361046 },
10371047 .Pointer => {
......@@ -2155,15 +2165,29 @@ pub const Value = struct {
21552165 /// unreachable. For error unions, prefer `errorUnionIsPayload` to find out whether
21562166 /// something is an error or not because it works without having to figure out the
21572167 /// string.
2158 pub fn getError(self: Value, mod: *const Module) ?[]const u8 {
2159 return mod.intern_pool.stringToSliceUnwrap(switch (mod.intern_pool.indexToKey(self.toIntern())) {
2160 .err => |err| err.name.toOptional(),
2168 pub fn getError(val: Value, mod: *const Module) ?[]const u8 {
2169 return switch (getErrorName(val, mod)) {
2170 .empty => null,
2171 else => |s| mod.intern_pool.stringToSlice(s),
2172 };
2173 }
2174
2175 pub fn getErrorName(val: Value, mod: *const Module) InternPool.NullTerminatedString {
2176 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
2177 .err => |err| err.name,
21612178 .error_union => |error_union| switch (error_union.val) {
2162 .err_name => |err_name| err_name.toOptional(),
2163 .payload => .none,
2179 .err_name => |err_name| err_name,
2180 .payload => .empty,
21642181 },
21652182 else => unreachable,
2166 });
2183 };
2184 }
2185
2186 pub fn getErrorInt(val: Value, mod: *const Module) Module.ErrorInt {
2187 return switch (getErrorName(val, mod)) {
2188 .empty => 0,
2189 else => |s| @intCast(Module.ErrorInt, mod.global_error_set.getIndex(s).?),
2190 };
21672191 }
21682192
21692193 /// Assumes the type is an error union. Returns true if and only if the value is
......@@ -4225,7 +4249,7 @@ pub const Value = struct {
42254249 var fields: [tags.len]std.builtin.Type.StructField = undefined;
42264250 for (&fields, tags) |*field, t| field.* = .{
42274251 .name = t.name,
4228 .type = *if (t.value < Tag.no_payload_count) void else @field(Tag, t.name).Type(),
4252 .type = *@field(Tag, t.name).Type(),
42294253 .default_value = null,
42304254 .is_comptime = false,
42314255 .alignment = 0,