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 {...@@ -1317,7 +1317,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1317 .global_zir_cache = global_zir_cache,1317 .global_zir_cache = global_zir_cache,
1318 .local_zir_cache = local_zir_cache,1318 .local_zir_cache = local_zir_cache,
1319 .emit_h = emit_h,1319 .emit_h = emit_h,
1320 .error_name_list = .{},1320 .tmp_hack_arena = std.heap.ArenaAllocator.init(gpa),
1321 };1321 };
1322 try module.init();1322 try module.init();
13231323
...@@ -2627,7 +2627,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {...@@ -2627,7 +2627,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
2627 var it = module.failed_files.iterator();2627 var it = module.failed_files.iterator();
2628 while (it.next()) |entry| {2628 while (it.next()) |entry| {
2629 if (entry.value_ptr.*) |msg| {2629 if (entry.value_ptr.*) |msg| {
2630 try addModuleErrorMsg(&bundle, msg.*);2630 try addModuleErrorMsg(module, &bundle, msg.*);
2631 } else {2631 } else {
2632 // Must be ZIR errors. Note that this may include AST errors.2632 // Must be ZIR errors. Note that this may include AST errors.
2633 // addZirErrorMessages asserts that the tree is loaded.2633 // addZirErrorMessages asserts that the tree is loaded.
...@@ -2640,7 +2640,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {...@@ -2640,7 +2640,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
2640 var it = module.failed_embed_files.iterator();2640 var it = module.failed_embed_files.iterator();
2641 while (it.next()) |entry| {2641 while (it.next()) |entry| {
2642 const msg = entry.value_ptr.*;2642 const msg = entry.value_ptr.*;
2643 try addModuleErrorMsg(&bundle, msg.*);2643 try addModuleErrorMsg(module, &bundle, msg.*);
2644 }2644 }
2645 }2645 }
2646 {2646 {
...@@ -2650,7 +2650,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {...@@ -2650,7 +2650,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
2650 // Skip errors for Decls within files that had a parse failure.2650 // Skip errors for Decls within files that had a parse failure.
2651 // We'll try again once parsing succeeds.2651 // We'll try again once parsing succeeds.
2652 if (module.declFileScope(decl_index).okToReportErrors()) {2652 if (module.declFileScope(decl_index).okToReportErrors()) {
2653 try addModuleErrorMsg(&bundle, entry.value_ptr.*.*);2653 try addModuleErrorMsg(module, &bundle, entry.value_ptr.*.*);
2654 if (module.cimport_errors.get(entry.key_ptr.*)) |cimport_errors| for (cimport_errors) |c_error| {2654 if (module.cimport_errors.get(entry.key_ptr.*)) |cimport_errors| for (cimport_errors) |c_error| {
2655 try bundle.addRootErrorMessage(.{2655 try bundle.addRootErrorMessage(.{
2656 .msg = try bundle.addString(std.mem.span(c_error.msg)),2656 .msg = try bundle.addString(std.mem.span(c_error.msg)),
...@@ -2675,12 +2675,12 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {...@@ -2675,12 +2675,12 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
2675 // Skip errors for Decls within files that had a parse failure.2675 // Skip errors for Decls within files that had a parse failure.
2676 // We'll try again once parsing succeeds.2676 // We'll try again once parsing succeeds.
2677 if (module.declFileScope(decl_index).okToReportErrors()) {2677 if (module.declFileScope(decl_index).okToReportErrors()) {
2678 try addModuleErrorMsg(&bundle, entry.value_ptr.*.*);2678 try addModuleErrorMsg(module, &bundle, entry.value_ptr.*.*);
2679 }2679 }
2680 }2680 }
2681 }2681 }
2682 for (module.failed_exports.values()) |value| {2682 for (module.failed_exports.values()) |value| {
2683 try addModuleErrorMsg(&bundle, value.*);2683 try addModuleErrorMsg(module, &bundle, value.*);
2684 }2684 }
2685 }2685 }
26862686
...@@ -2728,7 +2728,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {...@@ -2728,7 +2728,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
2728 };2728 };
2729 }2729 }
27302730
2731 try addModuleErrorMsg(&bundle, err_msg);2731 try addModuleErrorMsg(module, &bundle, err_msg);
2732 }2732 }
2733 }2733 }
27342734
...@@ -2784,8 +2784,9 @@ pub const ErrorNoteHashContext = struct {...@@ -2784,8 +2784,9 @@ pub const ErrorNoteHashContext = struct {
2784 }2784 }
2785};2785};
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 {
2788 const gpa = eb.gpa;2788 const gpa = eb.gpa;
2789 const ip = &mod.intern_pool;
2789 const err_source = module_err_msg.src_loc.file_scope.getSource(gpa) catch |err| {2790 const err_source = module_err_msg.src_loc.file_scope.getSource(gpa) catch |err| {
2790 const file_path = try module_err_msg.src_loc.file_scope.fullPath(gpa);2791 const file_path = try module_err_msg.src_loc.file_scope.fullPath(gpa);
2791 defer gpa.free(file_path);2792 defer gpa.free(file_path);
...@@ -2811,7 +2812,7 @@ pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg)...@@ -2811,7 +2812,7 @@ pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg)
2811 .src_loc = .none,2812 .src_loc = .none,
2812 });2813 });
2813 break;2814 break;
2814 } else if (module_reference.decl == null) {2815 } else if (module_reference.decl == .none) {
2815 try ref_traces.append(gpa, .{2816 try ref_traces.append(gpa, .{
2816 .decl_name = 0,2817 .decl_name = 0,
2817 .src_loc = .none,2818 .src_loc = .none,
...@@ -2824,7 +2825,7 @@ pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg)...@@ -2824,7 +2825,7 @@ pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg)
2824 const rt_file_path = try module_reference.src_loc.file_scope.fullPath(gpa);2825 const rt_file_path = try module_reference.src_loc.file_scope.fullPath(gpa);
2825 defer gpa.free(rt_file_path);2826 defer gpa.free(rt_file_path);
2826 try ref_traces.append(gpa, .{2827 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).?),
2828 .src_loc = try eb.addSourceLocation(.{2829 .src_loc = try eb.addSourceLocation(.{
2829 .src_path = try eb.addString(rt_file_path),2830 .src_path = try eb.addString(rt_file_path),
2830 .span_start = span.start,2831 .span_start = span.start,
src/InternPool.zig+33
...@@ -124,6 +124,8 @@ pub const String = enum(u32) {...@@ -124,6 +124,8 @@ pub const String = enum(u32) {
124124
125/// An index into `string_bytes`.125/// An index into `string_bytes`.
126pub const NullTerminatedString = enum(u32) {126pub const NullTerminatedString = enum(u32) {
127 /// This is distinct from `none` - it is a valid index that represents empty string.
128 empty = 0,
127 _,129 _,
128130
129 pub fn toString(self: NullTerminatedString) String {131 pub fn toString(self: NullTerminatedString) String {
...@@ -157,6 +159,8 @@ pub const NullTerminatedString = enum(u32) {...@@ -157,6 +159,8 @@ pub const NullTerminatedString = enum(u32) {
157159
158/// An index into `string_bytes` which might be `none`.160/// An index into `string_bytes` which might be `none`.
159pub const OptionalNullTerminatedString = enum(u32) {161pub const OptionalNullTerminatedString = enum(u32) {
162 /// This is distinct from `none` - it is a valid index that represents empty string.
163 empty = 0,
160 none = std.math.maxInt(u32),164 none = std.math.maxInt(u32),
161 _,165 _,
162166
...@@ -2447,6 +2451,9 @@ pub const MemoizedCall = struct {...@@ -2447,6 +2451,9 @@ pub const MemoizedCall = struct {
2447pub fn init(ip: *InternPool, gpa: Allocator) !void {2451pub fn init(ip: *InternPool, gpa: Allocator) !void {
2448 assert(ip.items.len == 0);2452 assert(ip.items.len == 0);
24492453
2454 // Reserve string index 0 for an empty string.
2455 assert((try ip.getOrPutString(gpa, "")) == .empty);
2456
2450 // So that we can use `catch unreachable` below.2457 // So that we can use `catch unreachable` below.
2451 try ip.items.ensureUnusedCapacity(gpa, static_keys.len);2458 try ip.items.ensureUnusedCapacity(gpa, static_keys.len);
2452 try ip.map.ensureUnusedCapacity(gpa, static_keys.len);2459 try ip.map.ensureUnusedCapacity(gpa, static_keys.len);
...@@ -5222,6 +5229,28 @@ pub fn getOrPutString(...@@ -5222,6 +5229,28 @@ pub fn getOrPutString(
5222 return ip.getOrPutTrailingString(gpa, s.len + 1);5229 return ip.getOrPutTrailingString(gpa, s.len + 1);
5223}5230}
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
5225/// Uses the last len bytes of ip.string_bytes as the key.5254/// Uses the last len bytes of ip.string_bytes as the key.
5226pub fn getOrPutTrailingString(5255pub fn getOrPutTrailingString(
5227 ip: *InternPool,5256 ip: *InternPool,
...@@ -5273,6 +5302,10 @@ pub fn stringToSliceUnwrap(ip: *const InternPool, s: OptionalNullTerminatedStrin...@@ -5273,6 +5302,10 @@ pub fn stringToSliceUnwrap(ip: *const InternPool, s: OptionalNullTerminatedStrin
5273 return ip.stringToSlice(s.unwrap() orelse return null);5302 return ip.stringToSlice(s.unwrap() orelse return null);
5274}5303}
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
5276pub fn typeOf(ip: *const InternPool, index: Index) Index {5309pub fn typeOf(ip: *const InternPool, index: Index) Index {
5277 // This optimization of static keys is required so that typeOf can be called5310 // This optimization of static keys is required so that typeOf can be called
5278 // on static keys that haven't been added yet during static key initialization.5311 // 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) = .{},...@@ -88,6 +88,14 @@ embed_table: std.StringHashMapUnmanaged(*EmbedFile) = .{},
88/// Stores all Type and Value objects; periodically garbage collected.88/// Stores all Type and Value objects; periodically garbage collected.
89intern_pool: InternPool = .{},89intern_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
91/// This is currently only used for string literals.99/// This is currently only used for string literals.
92memoized_decls: std.AutoHashMapUnmanaged(InternPool.Index, Decl.Index) = .{},100memoized_decls: std.AutoHashMapUnmanaged(InternPool.Index, Decl.Index) = .{},
93101
...@@ -125,13 +133,8 @@ cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, []CImportError) = .{},...@@ -125,13 +133,8 @@ cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, []CImportError) = .{},
125/// contains Decls that need to be deleted if they end up having no references to them.133/// contains Decls that need to be deleted if they end up having no references to them.
126deletion_set: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},134deletion_set: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .{},
127135
128/// Error tags and their values, tag names are duped with mod.gpa.136/// Key is the error name, index is the error tag value. Index 0 has a length-0 string.
129/// Corresponds with `error_name_list`.137global_error_set: GlobalErrorSet = .{},
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),
135138
136/// Incrementing integer used to compare against the corresponding Decl139/// Incrementing integer used to compare against the corresponding Decl
137/// field to determine whether a Decl's status applies to an ongoing update, or a140/// 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 {...@@ -182,6 +185,8 @@ reference_table: std.AutoHashMapUnmanaged(Decl.Index, struct {
182 src: LazySrcLoc,185 src: LazySrcLoc,
183}) = .{},186}) = .{},
184187
188pub const GlobalErrorSet = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void);
189
185pub const CImportError = struct {190pub const CImportError = struct {
186 offset: u32,191 offset: u32,
187 line: u32,192 line: u32,
...@@ -248,7 +253,11 @@ pub const GlobalEmitH = struct {...@@ -248,7 +253,11 @@ pub const GlobalEmitH = struct {
248pub const ErrorInt = u32;253pub const ErrorInt = u32;
249254
250pub const Export = struct {255pub 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
252 src: LazySrcLoc,261 src: LazySrcLoc,
253 /// The Decl that performs the export. Note that this is *not* the Decl being exported.262 /// The Decl that performs the export. Note that this is *not* the Decl being exported.
254 owner_decl: Decl.Index,263 owner_decl: Decl.Index,
...@@ -392,8 +401,7 @@ const ValueArena = struct {...@@ -392,8 +401,7 @@ const ValueArena = struct {
392};401};
393402
394pub const Decl = struct {403pub const Decl = struct {
395 /// Allocated with Module's allocator; outlives the ZIR code.404 name: InternPool.NullTerminatedString,
396 name: [*:0]const u8,
397 /// The most recent Type of the Decl after a successful semantic analysis.405 /// The most recent Type of the Decl after a successful semantic analysis.
398 /// Populated when `has_tv`.406 /// Populated when `has_tv`.
399 ty: Type,407 ty: Type,
...@@ -401,15 +409,11 @@ pub const Decl = struct {...@@ -401,15 +409,11 @@ pub const Decl = struct {
401 /// Populated when `has_tv`.409 /// Populated when `has_tv`.
402 val: Value,410 val: Value,
403 /// Populated when `has_tv`.411 /// Populated when `has_tv`.
404 /// Points to memory inside value_arena.412 @"linksection": InternPool.OptionalNullTerminatedString,
405 @"linksection": ?[*:0]const u8,
406 /// Populated when `has_tv`.413 /// Populated when `has_tv`.
407 @"align": u32,414 @"align": u32,
408 /// Populated when `has_tv`.415 /// Populated when `has_tv`.
409 @"addrspace": std.builtin.AddressSpace,416 @"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,
413 /// The direct parent namespace of the Decl.417 /// The direct parent namespace of the Decl.
414 /// Reference to externally owned memory.418 /// Reference to externally owned memory.
415 /// In the case of the Decl corresponding to a file, this is419 /// In the case of the Decl corresponding to a file, this is
...@@ -564,13 +568,7 @@ pub const Decl = struct {...@@ -564,13 +568,7 @@ pub const Decl = struct {
564 function_body,568 function_body,
565 };569 };
566570
567 pub fn clearName(decl: *Decl, gpa: Allocator) void {
568 gpa.free(mem.sliceTo(decl.name, 0));
569 decl.name = undefined;
570 }
571
572 pub fn clearValues(decl: *Decl, mod: *Module) void {571 pub fn clearValues(decl: *Decl, mod: *Module) void {
573 const gpa = mod.gpa;
574 if (decl.getOwnedFunctionIndex(mod).unwrap()) |func| {572 if (decl.getOwnedFunctionIndex(mod).unwrap()) |func| {
575 _ = mod.align_stack_fns.remove(func);573 _ = mod.align_stack_fns.remove(func);
576 if (mod.funcPtr(func).comptime_args != null) {574 if (mod.funcPtr(func).comptime_args != null) {
...@@ -579,19 +577,6 @@ pub const Decl = struct {...@@ -579,19 +577,6 @@ pub const Decl = struct {
579 mod.destroyFunc(func);577 mod.destroyFunc(func);
580 }578 }
581 _ = mod.memoized_decls.remove(decl.val.ip_index);579 _ = 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;
595 }580 }
596581
597 /// This name is relative to the containing namespace of the decl.582 /// This name is relative to the containing namespace of the decl.
...@@ -692,7 +677,7 @@ pub const Decl = struct {...@@ -692,7 +677,7 @@ pub const Decl = struct {
692 }677 }
693678
694 pub fn renderFullyQualifiedName(decl: Decl, mod: *Module, writer: anytype) !void {679 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);
696 if (decl.name_fully_qualified) {681 if (decl.name_fully_qualified) {
697 return writer.writeAll(unqualified_name);682 return writer.writeAll(unqualified_name);
698 }683 }
...@@ -700,24 +685,27 @@ pub const Decl = struct {...@@ -700,24 +685,27 @@ pub const Decl = struct {
700 }685 }
701686
702 pub fn renderFullyQualifiedDebugName(decl: Decl, mod: *Module, writer: anytype) !void {687 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);
704 return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, unqualified_name, writer);689 return mod.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(mod, unqualified_name, writer);
705 }690 }
706691
707 pub fn getFullyQualifiedName(decl: Decl, mod: *Module) ![:0]u8 {692 pub fn getFullyQualifiedName(decl: Decl, mod: *Module) !InternPool.NullTerminatedString {
708 var buffer = std.ArrayList(u8).init(mod.gpa);693 const gpa = mod.gpa;
709 defer buffer.deinit();694 const ip = &mod.intern_pool;
710 try decl.renderFullyQualifiedName(mod, buffer.writer());695 const start = ip.string_bytes.items.len;
696 try decl.renderFullyQualifiedName(mod, ip.string_bytes.writer(gpa));
711697
712 // Sanitize the name for nvptx which is more restrictive.698 // 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.
713 if (mod.comp.bin_file.options.target.cpu.arch.isNvptx()) {701 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.*) {
715 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',703 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
716 else => {},704 else => {},
717 };705 };
718 }706 }
719707
720 return buffer.toOwnedSliceSentinel(0);708 return ip.getOrPutTrailingString(gpa, ip.string_bytes.items.len - start);
721 }709 }
722710
723 pub fn typedValue(decl: Decl) error{AnalysisFail}!TypedValue {711 pub fn typedValue(decl: Decl) error{AnalysisFail}!TypedValue {
...@@ -804,11 +792,11 @@ pub const Decl = struct {...@@ -804,11 +792,11 @@ pub const Decl = struct {
804792
805 pub fn dump(decl: *Decl) void {793 pub fn dump(decl: *Decl) void {
806 const loc = std.zig.findLineColumn(decl.scope.source.bytes, decl.src);794 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}", .{
808 decl.scope.sub_file_path,796 decl.scope.sub_file_path,
809 loc.line + 1,797 loc.line + 1,
810 loc.column + 1,798 loc.column + 1,
811 mem.sliceTo(decl.name, 0),799 @enumToInt(decl.name),
812 @tagName(decl.analysis),800 @tagName(decl.analysis),
813 });801 });
814 if (decl.has_tv) {802 if (decl.has_tv) {
...@@ -922,15 +910,15 @@ pub const Struct = struct {...@@ -922,15 +910,15 @@ pub const Struct = struct {
922 }910 }
923 };911 };
924912
925 pub const Fields = std.StringArrayHashMapUnmanaged(Field);913 pub const Fields = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, Field);
926914
927 /// The `Type` and `Value` memory is owned by the arena of the Struct's owner_decl.915 /// The `Type` and `Value` memory is owned by the arena of the Struct's owner_decl.
928 pub const Field = struct {916 pub const Field = struct {
929 /// Uses `noreturn` to indicate `anytype`.917 /// Uses `noreturn` to indicate `anytype`.
930 /// undefined until `status` is >= `have_field_types`.918 /// undefined until `status` is >= `have_field_types`.
931 ty: Type,919 ty: Type,
932 /// Uses `unreachable_value` to indicate no default.920 /// Uses `none` to indicate no default.
933 default_val: Value,921 default_val: InternPool.Index,
934 /// Zero means to use the ABI alignment of the type.922 /// Zero means to use the ABI alignment of the type.
935 abi_align: u32,923 abi_align: u32,
936 /// undefined until `status` is `have_layout`.924 /// undefined until `status` is `have_layout`.
...@@ -982,7 +970,7 @@ pub const Struct = struct {...@@ -982,7 +970,7 @@ pub const Struct = struct {
982 /// runtime version of the struct.970 /// runtime version of the struct.
983 pub const omitted_field = std.math.maxInt(u32);971 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 {
986 return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);974 return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
987 }975 }
988976
...@@ -1141,9 +1129,9 @@ pub const Union = struct {...@@ -1141,9 +1129,9 @@ pub const Union = struct {
1141 }1129 }
1142 };1130 };
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 {
1147 return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);1135 return mod.declPtr(s.owner_decl).getFullyQualifiedName(mod);
1148 }1136 }
11491137
...@@ -1569,15 +1557,15 @@ pub const Fn = struct {...@@ -1569,15 +1557,15 @@ pub const Fn = struct {
1569pub const DeclAdapter = struct {1557pub const DeclAdapter = struct {
1570 mod: *Module,1558 mod: *Module,
15711559
1572 pub fn hash(self: @This(), s: []const u8) u32 {1560 pub fn hash(self: @This(), s: InternPool.NullTerminatedString) u32 {
1573 _ = self;1561 _ = self;
1574 return @truncate(u32, std.hash.Wyhash.hash(0, s));1562 return std.hash.uint32(@enumToInt(s));
1575 }1563 }
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 {
1578 _ = b_index;1566 _ = b_index;
1579 const b_decl = self.mod.declPtr(b_decl_index);1567 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;
1581 }1569 }
1582};1570};
15831571
...@@ -1628,16 +1616,14 @@ pub const Namespace = struct {...@@ -1628,16 +1616,14 @@ pub const Namespace = struct {
16281616
1629 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {1617 pub fn hash(ctx: @This(), decl_index: Decl.Index) u32 {
1630 const decl = ctx.module.declPtr(decl_index);1618 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));
1632 }1620 }
16331621
1634 pub fn eql(ctx: @This(), a_decl_index: Decl.Index, b_decl_index: Decl.Index, b_index: usize) bool {1622 pub fn eql(ctx: @This(), a_decl_index: Decl.Index, b_decl_index: Decl.Index, b_index: usize) bool {
1635 _ = b_index;1623 _ = b_index;
1636 const a_decl = ctx.module.declPtr(a_decl_index);1624 const a_decl = ctx.module.declPtr(a_decl_index);
1637 const b_decl = ctx.module.declPtr(b_decl_index);1625 const b_decl = ctx.module.declPtr(b_decl_index);
1638 const a_name = mem.sliceTo(a_decl.name, 0);1626 return a_decl.name == b_decl.name;
1639 const b_name = mem.sliceTo(b_decl.name, 0);
1640 return mem.eql(u8, a_name, b_name);
1641 }1627 }
1642 };1628 };
16431629
...@@ -1649,8 +1635,6 @@ pub const Namespace = struct {...@@ -1649,8 +1635,6 @@ pub const Namespace = struct {
1649 pub fn destroyDecls(ns: *Namespace, mod: *Module) void {1635 pub fn destroyDecls(ns: *Namespace, mod: *Module) void {
1650 const gpa = mod.gpa;1636 const gpa = mod.gpa;
16511637
1652 log.debug("destroyDecls {*}", .{ns});
1653
1654 var decls = ns.decls;1638 var decls = ns.decls;
1655 ns.decls = .{};1639 ns.decls = .{};
16561640
...@@ -1676,8 +1660,6 @@ pub const Namespace = struct {...@@ -1676,8 +1660,6 @@ pub const Namespace = struct {
1676 ) !void {1660 ) !void {
1677 const gpa = mod.gpa;1661 const gpa = mod.gpa;
16781662
1679 log.debug("deleteAllDecls {*}", .{ns});
1680
1681 var decls = ns.decls;1663 var decls = ns.decls;
1682 ns.decls = .{};1664 ns.decls = .{};
16831665
...@@ -1712,7 +1694,8 @@ pub const Namespace = struct {...@@ -1712,7 +1694,8 @@ pub const Namespace = struct {
1712 if (ns.parent.unwrap()) |parent| {1694 if (ns.parent.unwrap()) |parent| {
1713 const decl_index = ns.getDeclIndex(mod);1695 const decl_index = ns.getDeclIndex(mod);
1714 const decl = mod.declPtr(decl_index);1696 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);
1716 } else {1699 } else {
1717 try ns.file_scope.renderFullyQualifiedName(writer);1700 try ns.file_scope.renderFullyQualifiedName(writer);
1718 }1701 }
...@@ -1733,7 +1716,8 @@ pub const Namespace = struct {...@@ -1733,7 +1716,8 @@ pub const Namespace = struct {
1733 if (ns.parent.unwrap()) |parent| {1716 if (ns.parent.unwrap()) |parent| {
1734 const decl_index = ns.getDeclIndex(mod);1717 const decl_index = ns.getDeclIndex(mod);
1735 const decl = mod.declPtr(decl_index);1718 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);
1737 } else {1721 } else {
1738 try ns.file_scope.renderFullyQualifiedDebugName(writer);1722 try ns.file_scope.renderFullyQualifiedDebugName(writer);
1739 separator_char = ':';1723 separator_char = ':';
...@@ -1927,11 +1911,11 @@ pub const File = struct {...@@ -1927,11 +1911,11 @@ pub const File = struct {
1927 };1911 };
1928 }1912 }
19291913
1930 pub fn fullyQualifiedNameZ(file: File, gpa: Allocator) ![:0]u8 {1914 pub fn fullyQualifiedName(file: File, mod: *Module) !InternPool.NullTerminatedString {
1931 var buf = std.ArrayList(u8).init(gpa);1915 const ip = &mod.intern_pool;
1932 defer buf.deinit();1916 const start = ip.string_bytes.items.len;
1933 try file.renderFullyQualifiedName(buf.writer());1917 try file.renderFullyQualifiedName(ip.string_bytes.writer(mod.gpa));
1934 return buf.toOwnedSliceSentinel(0);1918 return ip.getOrPutTrailingString(mod.gpa, ip.string_bytes.items.len - start);
1935 }1919 }
19361920
1937 /// Returns the full path to this file relative to its package.1921 /// Returns the full path to this file relative to its package.
...@@ -2055,7 +2039,7 @@ pub const ErrorMsg = struct {...@@ -2055,7 +2039,7 @@ pub const ErrorMsg = struct {
2055 reference_trace: []Trace = &.{},2039 reference_trace: []Trace = &.{},
20562040
2057 pub const Trace = struct {2041 pub const Trace = struct {
2058 decl: ?[*:0]const u8,2042 decl: InternPool.OptionalNullTerminatedString,
2059 src_loc: SrcLoc,2043 src_loc: SrcLoc,
2060 hidden: u32 = 0,2044 hidden: u32 = 0,
2061 };2045 };
...@@ -3180,8 +3164,8 @@ pub const CompileError = error{...@@ -3180,8 +3164,8 @@ pub const CompileError = error{
31803164
3181pub fn init(mod: *Module) !void {3165pub fn init(mod: *Module) !void {
3182 const gpa = mod.gpa;3166 const gpa = mod.gpa;
3183 try mod.error_name_list.append(gpa, "(no error)");
3184 try mod.intern_pool.init(gpa);3167 try mod.intern_pool.init(gpa);
3168 try mod.global_error_set.put(gpa, .empty, {});
3185}3169}
31863170
3187pub fn deinit(mod: *Module) void {3171pub fn deinit(mod: *Module) void {
...@@ -3282,15 +3266,8 @@ pub fn deinit(mod: *Module) void {...@@ -3282,15 +3266,8 @@ pub fn deinit(mod: *Module) void {
3282 }3266 }
3283 mod.export_owners.deinit(gpa);3267 mod.export_owners.deinit(gpa);
32843268
3285 {3269 mod.global_error_set.deinit(gpa);
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 }
32923270
3293 mod.error_name_list.deinit(gpa);
3294 mod.test_functions.deinit(gpa);3271 mod.test_functions.deinit(gpa);
3295 mod.align_stack_fns.deinit(gpa);3272 mod.align_stack_fns.deinit(gpa);
3296 mod.monomorphed_funcs.deinit(gpa);3273 mod.monomorphed_funcs.deinit(gpa);
...@@ -3305,13 +3282,13 @@ pub fn deinit(mod: *Module) void {...@@ -3305,13 +3282,13 @@ pub fn deinit(mod: *Module) void {
33053282
3306 mod.memoized_decls.deinit(gpa);3283 mod.memoized_decls.deinit(gpa);
3307 mod.intern_pool.deinit(gpa);3284 mod.intern_pool.deinit(gpa);
3285 mod.tmp_hack_arena.deinit();
3308}3286}
33093287
3310pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {3288pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
3311 const gpa = mod.gpa;3289 const gpa = mod.gpa;
3312 {3290 {
3313 const decl = mod.declPtr(decl_index);3291 const decl = mod.declPtr(decl_index);
3314 log.debug("destroy {*} ({s})", .{ decl, decl.name });
3315 _ = mod.test_functions.swapRemove(decl_index);3292 _ = mod.test_functions.swapRemove(decl_index);
3316 if (decl.deletion_flag) {3293 if (decl.deletion_flag) {
3317 assert(mod.deletion_set.swapRemove(decl_index));3294 assert(mod.deletion_set.swapRemove(decl_index));
...@@ -3329,7 +3306,6 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {...@@ -3329,7 +3306,6 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
3329 decl.clearValues(mod);3306 decl.clearValues(mod);
3330 decl.dependants.deinit(gpa);3307 decl.dependants.deinit(gpa);
3331 decl.dependencies.deinit(gpa);3308 decl.dependencies.deinit(gpa);
3332 decl.clearName(gpa);
3333 decl.* = undefined;3309 decl.* = undefined;
3334 }3310 }
3335 mod.decls_free_list.append(gpa, decl_index) catch {3311 mod.decls_free_list.append(gpa, decl_index) catch {
...@@ -3391,11 +3367,7 @@ pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {...@@ -3391,11 +3367,7 @@ pub fn declIsRoot(mod: *Module, decl_index: Decl.Index) bool {
3391}3367}
33923368
3393fn freeExportList(gpa: Allocator, export_list: *ArrayListUnmanaged(*Export)) void {3369fn freeExportList(gpa: Allocator, export_list: *ArrayListUnmanaged(*Export)) void {
3394 for (export_list.items) |exp| {3370 for (export_list.items) |exp| gpa.destroy(exp);
3395 gpa.free(exp.options.name);
3396 if (exp.options.section) |s| gpa.free(s);
3397 gpa.destroy(exp);
3398 }
3399 export_list.deinit(gpa);3371 export_list.deinit(gpa);
3400}3372}
34013373
...@@ -3814,9 +3786,6 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {...@@ -3814,9 +3786,6 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
3814 if (decl.zir_decl_index != 0) {3786 if (decl.zir_decl_index != 0) {
3815 const old_zir_decl_index = decl.zir_decl_index;3787 const old_zir_decl_index = decl.zir_decl_index;
3816 const new_zir_decl_index = extra_map.get(old_zir_decl_index) orelse {3788 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 });
3820 try file.deleted_decls.append(gpa, decl_index);3789 try file.deleted_decls.append(gpa, decl_index);
3821 continue;3790 continue;
3822 };3791 };
...@@ -3824,14 +3793,7 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {...@@ -3824,14 +3793,7 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
3824 decl.zir_decl_index = new_zir_decl_index;3793 decl.zir_decl_index = new_zir_decl_index;
3825 const new_hash = decl.contentsHashZir(new_zir);3794 const new_hash = decl.contentsHashZir(new_zir);
3826 if (!std.zig.srcHashEql(old_hash, new_hash)) {3795 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 });
3830 try file.outdated_decls.append(gpa, decl_index);3796 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 });
3835 }3797 }
3836 }3798 }
38373799
...@@ -4031,8 +3993,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {...@@ -4031,8 +3993,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
4031 .complete => return,3993 .complete => return,
40323994
4033 .outdated => blk: {3995 .outdated => blk: {
4034 log.debug("re-analyzing {*} ({s})", .{ decl, decl.name });
4035
4036 // The exports this Decl performs will be re-discovered, so we remove them here3996 // The exports this Decl performs will be re-discovered, so we remove them here
4037 // prior to re-analysis.3997 // prior to re-analysis.
4038 try mod.deleteDeclExports(decl_index);3998 try mod.deleteDeclExports(decl_index);
...@@ -4047,9 +4007,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {...@@ -4047,9 +4007,6 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
4047 const dep = mod.declPtr(dep_index);4007 const dep = mod.declPtr(dep_index);
4048 dep.removeDependant(decl_index);4008 dep.removeDependant(decl_index);
4049 if (dep.dependants.count() == 0 and !dep.deletion_flag) {4009 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 });
4053 try mod.markDeclForDeletion(dep_index);4010 try mod.markDeclForDeletion(dep_index);
4054 }4011 }
4055 }4012 }
...@@ -4061,7 +4018,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {...@@ -4061,7 +4018,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
4061 .unreferenced => false,4018 .unreferenced => false,
4062 };4019 };
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);
4065 decl_prog_node.activate();4022 decl_prog_node.activate();
4066 defer decl_prog_node.end();4023 defer decl_prog_node.end();
40674024
...@@ -4190,14 +4147,11 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: Fn.Index) SemaError!void...@@ -4190,14 +4147,11 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: Fn.Index) SemaError!void
41904147
4191 if (no_bin_file and !dump_air and !dump_llvm_ir) return;4148 if (no_bin_file and !dump_air and !dump_llvm_ir) return;
41924149
4193 log.debug("analyze liveness of {s}", .{decl.name});
4194 var liveness = try Liveness.analyze(gpa, air, &mod.intern_pool);4150 var liveness = try Liveness.analyze(gpa, air, &mod.intern_pool);
4195 defer liveness.deinit(gpa);4151 defer liveness.deinit(gpa);
41964152
4197 if (dump_air) {4153 if (dump_air) {
4198 const fqn = try decl.getFullyQualifiedName(mod);4154 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
4199 defer mod.gpa.free(fqn);
4200
4201 std.debug.print("# Begin Function AIR: {s}:\n", .{fqn});4155 std.debug.print("# Begin Function AIR: {s}:\n", .{fqn});
4202 @import("print_air.zig").dump(mod, air, liveness);4156 @import("print_air.zig").dump(mod, air, liveness);
4203 std.debug.print("# End Function AIR: {s}\n\n", .{fqn});4157 std.debug.print("# End Function AIR: {s}\n\n", .{fqn});
...@@ -4354,9 +4308,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -4354,9 +4308,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
4354 if (file.root_decl != .none) return;4308 if (file.root_decl != .none) return;
43554309
4356 const gpa = mod.gpa;4310 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
4361 // Because these three things each reference each other, `undefined`4312 // Because these three things each reference each other, `undefined`
4362 // placeholders are used before being set after the struct type gains an4313 // 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 {...@@ -4394,7 +4345,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
4394 new_namespace.ty = struct_ty.toType();4345 new_namespace.ty = struct_ty.toType();
4395 file.root_decl = new_decl_index.toOptional();4346 file.root_decl = new_decl_index.toOptional();
43964347
4397 new_decl.name = try file.fullyQualifiedNameZ(gpa);4348 new_decl.name = try file.fullyQualifiedName(mod);
4398 new_decl.src_line = 0;4349 new_decl.src_line = 0;
4399 new_decl.is_pub = true;4350 new_decl.is_pub = true;
4400 new_decl.is_exported = false;4351 new_decl.is_exported = false;
...@@ -4403,7 +4354,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -4403,7 +4354,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
4403 new_decl.ty = Type.type;4354 new_decl.ty = Type.type;
4404 new_decl.val = struct_ty.toValue();4355 new_decl.val = struct_ty.toValue();
4405 new_decl.@"align" = 0;4356 new_decl.@"align" = 0;
4406 new_decl.@"linksection" = null;4357 new_decl.@"linksection" = .none;
4407 new_decl.has_tv = true;4358 new_decl.has_tv = true;
4408 new_decl.owns_tv = true;4359 new_decl.owns_tv = true;
4409 new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive.4360 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 {...@@ -4431,7 +4382,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
4431 .mod = mod,4382 .mod = mod,
4432 .gpa = gpa,4383 .gpa = gpa,
4433 .arena = sema_arena_allocator,4384 .arena = sema_arena_allocator,
4434 .perm_arena = new_decl_arena_allocator,
4435 .code = file.zir,4385 .code = file.zir,
4436 .owner_decl = new_decl,4386 .owner_decl = new_decl,
4437 .owner_decl_index = new_decl_index,4387 .owner_decl_index = new_decl_index,
...@@ -4484,8 +4434,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -4484,8 +4434,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
4484 } else {4434 } else {
4485 new_decl.analysis = .file_failure;4435 new_decl.analysis = .file_failure;
4486 }4436 }
4487
4488 try new_decl.finalizeNewArena(&new_decl_arena);
4489}4437}
44904438
4491/// Returns `true` if the Decl type changed.4439/// Returns `true` if the Decl type changed.
...@@ -4507,28 +4455,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4507,28 +4455,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
45074455
4508 decl.analysis = .in_progress;4456 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
4529 var analysis_arena = std.heap.ArenaAllocator.init(gpa);4458 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
4530 defer analysis_arena.deinit();4459 defer analysis_arena.deinit();
4531 const analysis_arena_allocator = analysis_arena.allocator();
45324460
4533 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);4461 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
4534 defer comptime_mutable_decls.deinit();4462 defer comptime_mutable_decls.deinit();
...@@ -4536,8 +4464,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4536,8 +4464,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4536 var sema: Sema = .{4464 var sema: Sema = .{
4537 .mod = mod,4465 .mod = mod,
4538 .gpa = gpa,4466 .gpa = gpa,
4539 .arena = analysis_arena_allocator,4467 .arena = analysis_arena.allocator(),
4540 .perm_arena = decl_arena_allocator,
4541 .code = zir,4468 .code = zir,
4542 .owner_decl = decl,4469 .owner_decl = decl,
4543 .owner_decl_index = decl_index,4470 .owner_decl_index = decl_index,
...@@ -4551,7 +4478,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4551,7 +4478,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4551 defer sema.deinit();4478 defer sema.deinit();
45524479
4553 if (mod.declIsRoot(decl_index)) {4480 if (mod.declIsRoot(decl_index)) {
4554 log.debug("semaDecl root {*} ({s})", .{ decl, decl.name });
4555 const main_struct_inst = Zir.main_struct_inst;4481 const main_struct_inst = Zir.main_struct_inst;
4556 const struct_index = decl.getOwnedStructIndex(mod).unwrap().?;4482 const struct_index = decl.getOwnedStructIndex(mod).unwrap().?;
4557 const struct_obj = mod.structPtr(struct_index);4483 const struct_obj = mod.structPtr(struct_index);
...@@ -4563,7 +4489,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4563,7 +4489,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4563 decl.generation = mod.generation;4489 decl.generation = mod.generation;
4564 return false;4490 return false;
4565 }4491 }
4566 log.debug("semaDecl {*} ({s})", .{ decl, decl.name });
45674492
4568 var wip_captures = try WipCaptureScope.init(gpa, decl.src_scope);4493 var wip_captures = try WipCaptureScope.init(gpa, decl.src_scope);
4569 defer wip_captures.deinit();4494 defer wip_captures.deinit();
...@@ -4619,7 +4544,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4619,7 +4544,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4619 decl.ty = InternPool.Index.type_type.toType();4544 decl.ty = InternPool.Index.type_type.toType();
4620 decl.val = ty.toValue();4545 decl.val = ty.toValue();
4621 decl.@"align" = 0;4546 decl.@"align" = 0;
4622 decl.@"linksection" = null;4547 decl.@"linksection" = .none;
4623 decl.has_tv = true;4548 decl.has_tv = true;
4624 decl.owns_tv = false;4549 decl.owns_tv = false;
4625 decl.analysis = .complete;4550 decl.analysis = .complete;
...@@ -4646,7 +4571,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4646,7 +4571,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4646 decl.clearValues(mod);4571 decl.clearValues(mod);
46474572
4648 decl.ty = decl_tv.ty;4573 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();
4650 // linksection, align, and addrspace were already set by Sema4575 // linksection, align, and addrspace were already set by Sema
4651 decl.has_tv = true;4576 decl.has_tv = true;
4652 decl.owns_tv = owns_tv;4577 decl.owns_tv = owns_tv;
...@@ -4660,7 +4585,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4660,7 +4585,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4660 return sema.fail(&block_scope, export_src, "export of inline function", .{});4585 return sema.fail(&block_scope, export_src, "export of inline function", .{});
4661 }4586 }
4662 // The scope needs to have the decl in it.4587 // 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 };
4664 try sema.analyzeExport(&block_scope, export_src, options, decl_index);4591 try sema.analyzeExport(&block_scope, export_src, options, decl_index);
4665 }4592 }
4666 return type_changed or is_inline != prev_is_inline;4593 return type_changed or is_inline != prev_is_inline;
...@@ -4693,14 +4620,13 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4693,14 +4620,13 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4693 .func => {},4620 .func => {},
46944621
4695 else => {4622 else => {
4696 log.debug("send global const to linker: {*} ({s})", .{ decl, decl.name });
4697 queue_linker_work = true;4623 queue_linker_work = true;
4698 },4624 },
4699 },4625 },
4700 }4626 }
47014627
4702 decl.ty = decl_tv.ty;4628 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();
4704 decl.@"align" = blk: {4630 decl.@"align" = blk: {
4705 const align_ref = decl.zirAlignRef(mod);4631 const align_ref = decl.zirAlignRef(mod);
4706 if (align_ref == .none) break :blk 0;4632 if (align_ref == .none) break :blk 0;
...@@ -4708,14 +4634,15 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4708,14 +4634,15 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4708 };4634 };
4709 decl.@"linksection" = blk: {4635 decl.@"linksection" = blk: {
4710 const linksection_ref = decl.zirLinksectionRef(mod);4636 const linksection_ref = decl.zirLinksectionRef(mod);
4711 if (linksection_ref == .none) break :blk null;4637 if (linksection_ref == .none) break :blk .none;
4712 const bytes = try sema.resolveConstString(&block_scope, section_src, linksection_ref, "linksection must be comptime-known");4638 const bytes = try sema.resolveConstString(&block_scope, section_src, linksection_ref, "linksection must be comptime-known");
4713 if (mem.indexOfScalar(u8, bytes, 0) != null) {4639 if (mem.indexOfScalar(u8, bytes, 0) != null) {
4714 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});4640 return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{});
4715 } else if (bytes.len == 0) {4641 } else if (bytes.len == 0) {
4716 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});4642 return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{});
4717 }4643 }
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();
4719 };4646 };
4720 decl.@"addrspace" = blk: {4647 decl.@"addrspace" = blk: {
4721 const addrspace_ctx: Sema.AddressSpaceContext = switch (mod.intern_pool.indexToKey(decl_tv.val.toIntern())) {4648 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 {...@@ -4743,7 +4670,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4743 (queue_linker_work and try sema.typeHasRuntimeBits(decl.ty));4670 (queue_linker_work and try sema.typeHasRuntimeBits(decl.ty));
47444671
4745 if (has_runtime_bits) {4672 if (has_runtime_bits) {
4746 log.debug("queue linker work for {*} ({s})", .{ decl, decl.name });
47474673
4748 // Needed for codegen_decl which will call updateDecl and then the4674 // Needed for codegen_decl which will call updateDecl and then the
4749 // codegen backend wants full access to the Decl Type.4675 // codegen backend wants full access to the Decl Type.
...@@ -4759,7 +4685,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4759,7 +4685,9 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4759 if (decl.is_exported) {4685 if (decl.is_exported) {
4760 const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) };4686 const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) };
4761 // The scope needs to have the decl in it.4687 // 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 };
4763 try sema.analyzeExport(&block_scope, export_src, options, decl_index);4691 try sema.analyzeExport(&block_scope, export_src, options, decl_index);
4764 }4692 }
47654693
...@@ -4785,10 +4713,6 @@ pub fn declareDeclDependencyType(mod: *Module, depender_index: Decl.Index, depen...@@ -4785,10 +4713,6 @@ pub fn declareDeclDependencyType(mod: *Module, depender_index: Decl.Index, depen
4785 }4713 }
4786 }4714 }
47874715
4788 log.debug("{*} ({s}) depends on {*} ({s})", .{
4789 depender, depender.name, dependee, dependee.name,
4790 });
4791
4792 if (dependee.deletion_flag) {4716 if (dependee.deletion_flag) {
4793 dependee.deletion_flag = false;4717 dependee.deletion_flag = false;
4794 assert(mod.deletion_set.swapRemove(dependee_index));4718 assert(mod.deletion_set.swapRemove(dependee_index));
...@@ -5138,6 +5062,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -5138,6 +5062,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
5138 const namespace = mod.namespacePtr(namespace_index);5062 const namespace = mod.namespacePtr(namespace_index);
5139 const gpa = mod.gpa;5063 const gpa = mod.gpa;
5140 const zir = namespace.file_scope.zir;5064 const zir = namespace.file_scope.zir;
5065 const ip = &mod.intern_pool;
51415066
5142 // zig fmt: off5067 // zig fmt: off
5143 const is_pub = (flags & 0b0001) != 0;5068 const is_pub = (flags & 0b0001) != 0;
...@@ -5157,31 +5082,31 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -5157,31 +5082,31 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
5157 // Every Decl needs a name.5082 // Every Decl needs a name.
5158 var is_named_test = false;5083 var is_named_test = false;
5159 var kind: Decl.Kind = .named;5084 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) {
5161 0 => name: {5086 0 => name: {
5162 if (export_bit) {5087 if (export_bit) {
5163 const i = iter.usingnamespace_index;5088 const i = iter.usingnamespace_index;
5164 iter.usingnamespace_index += 1;5089 iter.usingnamespace_index += 1;
5165 kind = .@"usingnamespace";5090 kind = .@"usingnamespace";
5166 break :name try std.fmt.allocPrintZ(gpa, "usingnamespace_{d}", .{i});5091 break :name try ip.getOrPutStringFmt(gpa, "usingnamespace_{d}", .{i});
5167 } else {5092 } else {
5168 const i = iter.comptime_index;5093 const i = iter.comptime_index;
5169 iter.comptime_index += 1;5094 iter.comptime_index += 1;
5170 kind = .@"comptime";5095 kind = .@"comptime";
5171 break :name try std.fmt.allocPrintZ(gpa, "comptime_{d}", .{i});5096 break :name try ip.getOrPutStringFmt(gpa, "comptime_{d}", .{i});
5172 }5097 }
5173 },5098 },
5174 1 => name: {5099 1 => name: {
5175 const i = iter.unnamed_test_index;5100 const i = iter.unnamed_test_index;
5176 iter.unnamed_test_index += 1;5101 iter.unnamed_test_index += 1;
5177 kind = .@"test";5102 kind = .@"test";
5178 break :name try std.fmt.allocPrintZ(gpa, "test_{d}", .{i});5103 break :name try ip.getOrPutStringFmt(gpa, "test_{d}", .{i});
5179 },5104 },
5180 2 => name: {5105 2 => name: {
5181 is_named_test = true;5106 is_named_test = true;
5182 const test_name = zir.nullTerminatedString(decl_doccomment_index);5107 const test_name = zir.nullTerminatedString(decl_doccomment_index);
5183 kind = .@"test";5108 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});
5185 },5110 },
5186 else => name: {5111 else => name: {
5187 const raw_name = zir.nullTerminatedString(decl_name_index);5112 const raw_name = zir.nullTerminatedString(decl_name_index);
...@@ -5189,14 +5114,12 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -5189,14 +5114,12 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
5189 is_named_test = true;5114 is_named_test = true;
5190 const test_name = zir.nullTerminatedString(decl_name_index + 1);5115 const test_name = zir.nullTerminatedString(decl_name_index + 1);
5191 kind = .@"test";5116 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});
5193 } else {5118 } else {
5194 break :name try gpa.dupeZ(u8, raw_name);5119 break :name try ip.getOrPutString(gpa, raw_name);
5195 }5120 }
5196 },5121 },
5197 };5122 };
5198 var must_free_decl_name = true;
5199 defer if (must_free_decl_name) gpa.free(decl_name);
52005123
5201 const is_exported = export_bit and decl_name_index != 0;5124 const is_exported = export_bit and decl_name_index != 0;
5202 if (kind == .@"usingnamespace") try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);5125 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...@@ -5204,7 +5127,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
5204 // We create a Decl for it regardless of analysis status.5127 // We create a Decl for it regardless of analysis status.
5205 const gop = try namespace.decls.getOrPutContextAdapted(5128 const gop = try namespace.decls.getOrPutContextAdapted(
5206 gpa,5129 gpa,
5207 @as([]const u8, mem.sliceTo(decl_name, 0)),5130 decl_name,
5208 DeclAdapter{ .mod = mod },5131 DeclAdapter{ .mod = mod },
5209 Namespace.DeclContext{ .module = mod },5132 Namespace.DeclContext{ .module = mod },
5210 );5133 );
...@@ -5214,11 +5137,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -5214,11 +5137,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
5214 const new_decl = mod.declPtr(new_decl_index);5137 const new_decl = mod.declPtr(new_decl_index);
5215 new_decl.kind = kind;5138 new_decl.kind = kind;
5216 new_decl.name = decl_name;5139 new_decl.name = decl_name;
5217 must_free_decl_name = false;
5218 if (kind == .@"usingnamespace") {5140 if (kind == .@"usingnamespace") {
5219 namespace.usingnamespace_set.putAssumeCapacity(new_decl_index, is_pub);5141 namespace.usingnamespace_set.putAssumeCapacity(new_decl_index, is_pub);
5220 }5142 }
5221 log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace });
5222 new_decl.src_line = line;5143 new_decl.src_line = line;
5223 gop.key_ptr.* = new_decl_index;5144 gop.key_ptr.* = new_decl_index;
5224 // Exported decls, comptime decls, usingnamespace decls, and5145 // Exported decls, comptime decls, usingnamespace decls, and
...@@ -5239,7 +5160,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -5239,7 +5160,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
5239 if (!comp.bin_file.options.is_test) break :blk false;5160 if (!comp.bin_file.options.is_test) break :blk false;
5240 if (decl_pkg != mod.main_pkg) break :blk false;5161 if (decl_pkg != mod.main_pkg) break :blk false;
5241 if (comp.test_filter) |test_filter| {5162 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) {
5243 break :blk false;5164 break :blk false;
5244 }5165 }
5245 }5166 }
...@@ -5270,7 +5191,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -5270,7 +5191,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
5270 gpa,5191 gpa,
5271 src_loc,5192 src_loc,
5272 "duplicate test name: {s}",5193 "duplicate test name: {s}",
5273 .{decl_name},5194 .{ip.stringToSlice(decl_name)},
5274 );5195 );
5275 errdefer msg.destroy(gpa);5196 errdefer msg.destroy(gpa);
5276 try mod.failed_decls.putNoClobber(gpa, decl_index, msg);5197 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...@@ -5281,7 +5202,6 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
5281 };5202 };
5282 try mod.errNoteNonLazy(other_src_loc, msg, "other test here", .{});5203 try mod.errNoteNonLazy(other_src_loc, msg, "other test here", .{});
5283 }5204 }
5284 log.debug("scan existing {*} ({s}) of {*}", .{ decl, decl.name, namespace });
5285 // Update the AST node of the decl; even if its contents are unchanged, it may5205 // Update the AST node of the decl; even if its contents are unchanged, it may
5286 // have been re-ordered.5206 // have been re-ordered.
5287 decl.src_node = decl_node;5207 decl.src_node = decl_node;
...@@ -5315,7 +5235,6 @@ pub fn clearDecl(...@@ -5315,7 +5235,6 @@ pub fn clearDecl(
5315 defer tracy.end();5235 defer tracy.end();
53165236
5317 const decl = mod.declPtr(decl_index);5237 const decl = mod.declPtr(decl_index);
5318 log.debug("clearing {*} ({s})", .{ decl, decl.name });
53195238
5320 const gpa = mod.gpa;5239 const gpa = mod.gpa;
5321 try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count());5240 try mod.deletion_set.ensureUnusedCapacity(gpa, decl.dependencies.count());
...@@ -5330,9 +5249,6 @@ pub fn clearDecl(...@@ -5330,9 +5249,6 @@ pub fn clearDecl(
5330 const dep = mod.declPtr(dep_index);5249 const dep = mod.declPtr(dep_index);
5331 dep.removeDependant(decl_index);5250 dep.removeDependant(decl_index);
5332 if (dep.dependants.count() == 0 and !dep.deletion_flag) {5251 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 });
5336 // We don't recursively perform a deletion here, because during the update,5252 // We don't recursively perform a deletion here, because during the update,
5337 // another reference to it may turn up.5253 // another reference to it may turn up.
5338 dep.deletion_flag = true;5254 dep.deletion_flag = true;
...@@ -5387,7 +5303,6 @@ pub fn clearDecl(...@@ -5387,7 +5303,6 @@ pub fn clearDecl(
5387/// This function is exclusively called for anonymous decls.5303/// This function is exclusively called for anonymous decls.
5388pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void {5304pub fn deleteUnusedDecl(mod: *Module, decl_index: Decl.Index) void {
5389 const decl = mod.declPtr(decl_index);5305 const decl = mod.declPtr(decl_index);
5390 log.debug("deleteUnusedDecl {d} ({s})", .{ decl_index, decl.name });
53915306
5392 assert(!mod.declIsRoot(decl_index));5307 assert(!mod.declIsRoot(decl_index));
5393 assert(mod.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index));5308 assert(mod.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index));
...@@ -5415,7 +5330,6 @@ fn markDeclForDeletion(mod: *Module, decl_index: Decl.Index) !void {...@@ -5415,7 +5330,6 @@ fn markDeclForDeletion(mod: *Module, decl_index: Decl.Index) !void {
5415/// If other decls depend on this decl, they must be aborted first.5330/// If other decls depend on this decl, they must be aborted first.
5416pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {5331pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
5417 const decl = mod.declPtr(decl_index);5332 const decl = mod.declPtr(decl_index);
5418 log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name });
54195333
5420 assert(!mod.declIsRoot(decl_index));5334 assert(!mod.declIsRoot(decl_index));
5421 assert(mod.namespacePtr(decl.src_namespace).anon_decls.swapRemove(decl_index));5335 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...@@ -5468,21 +5382,20 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void
5468 }5382 }
5469 }5383 }
5470 if (mod.comp.bin_file.cast(link.File.Elf)) |elf| {5384 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);
5472 }5386 }
5473 if (mod.comp.bin_file.cast(link.File.MachO)) |macho| {5387 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);
5475 }5389 }
5476 if (mod.comp.bin_file.cast(link.File.Wasm)) |wasm| {5390 if (mod.comp.bin_file.cast(link.File.Wasm)) |wasm| {
5477 wasm.deleteDeclExport(decl_index);5391 wasm.deleteDeclExport(decl_index);
5478 }5392 }
5479 if (mod.comp.bin_file.cast(link.File.Coff)) |coff| {5393 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);
5481 }5395 }
5482 if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| {5396 if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| {
5483 failed_kv.value.destroy(mod.gpa);5397 failed_kv.value.destroy(mod.gpa);
5484 }5398 }
5485 mod.gpa.free(exp.options.name);
5486 mod.gpa.destroy(exp);5399 mod.gpa.destroy(exp);
5487 }5400 }
5488 export_owners.deinit(mod.gpa);5401 export_owners.deinit(mod.gpa);
...@@ -5497,11 +5410,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE...@@ -5497,11 +5410,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
5497 const decl_index = func.owner_decl;5410 const decl_index = func.owner_decl;
5498 const decl = mod.declPtr(decl_index);5411 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
5505 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);5413 var comptime_mutable_decls = std.ArrayList(Decl.Index).init(gpa);
5506 defer comptime_mutable_decls.deinit();5414 defer comptime_mutable_decls.deinit();
55075415
...@@ -5512,7 +5420,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE...@@ -5512,7 +5420,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
5512 .mod = mod,5420 .mod = mod,
5513 .gpa = gpa,5421 .gpa = gpa,
5514 .arena = arena,5422 .arena = arena,
5515 .perm_arena = decl_arena_allocator,
5516 .code = decl.getFileScope(mod).zir,5423 .code = decl.getFileScope(mod).zir,
5517 .owner_decl = decl,5424 .owner_decl = decl,
5518 .owner_decl_index = decl_index,5425 .owner_decl_index = decl_index,
...@@ -5616,7 +5523,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE...@@ -5616,7 +5523,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
5616 }5523 }
56175524
5618 func.state = .in_progress;5525 func.state = .in_progress;
5619 log.debug("set {s} to in_progress", .{decl.name});
56205526
5621 const last_arg_index = inner_block.instructions.items.len;5527 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...@@ -5677,7 +5583,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
5677 sema.air_extra.items[@enumToInt(Air.ExtraIndex.main_block)] = main_block_index;5583 sema.air_extra.items[@enumToInt(Air.ExtraIndex.main_block)] = main_block_index;
56785584
5679 func.state = .success;5585 func.state = .success;
5680 log.debug("set {s} to success", .{decl.name});
56815586
5682 // Finally we must resolve the return type and parameter types so that backends5587 // Finally we must resolve the return type and parameter types so that backends
5683 // have full access to type information.5588 // have full access to type information.
...@@ -5724,7 +5629,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE...@@ -5724,7 +5629,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: Fn.Index, arena: Allocator) SemaE
57245629
5725fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {5630fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {
5726 const decl = mod.declPtr(decl_index);5631 const decl = mod.declPtr(decl_index);
5727 log.debug("mark outdated {*} ({s})", .{ decl, decl.name });
5728 try mod.comp.work_queue.writeItem(.{ .analyze_decl = decl_index });5632 try mod.comp.work_queue.writeItem(.{ .analyze_decl = decl_index });
5729 if (mod.failed_decls.fetchSwapRemove(decl_index)) |kv| {5633 if (mod.failed_decls.fetchSwapRemove(decl_index)) |kv| {
5730 kv.value.destroy(mod.gpa);5634 kv.value.destroy(mod.gpa);
...@@ -5821,7 +5725,7 @@ pub fn allocateNewDecl(...@@ -5821,7 +5725,7 @@ pub fn allocateNewDecl(
5821 .ty = undefined,5725 .ty = undefined,
5822 .val = undefined,5726 .val = undefined,
5823 .@"align" = undefined,5727 .@"align" = undefined,
5824 .@"linksection" = undefined,5728 .@"linksection" = .none,
5825 .@"addrspace" = .generic,5729 .@"addrspace" = .generic,
5826 .analysis = .unreferenced,5730 .analysis = .unreferenced,
5827 .deletion_flag = false,5731 .deletion_flag = false,
...@@ -5839,25 +5743,20 @@ pub fn allocateNewDecl(...@@ -5839,25 +5743,20 @@ pub fn allocateNewDecl(
5839 return decl_and_index.decl_index;5743 return decl_and_index.decl_index;
5840}5744}
58415745
5842/// Get error value for error tag `name`.5746pub fn getErrorValue(
5843pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged(ErrorInt).KV {5747 mod: *Module,
5748 name: InternPool.NullTerminatedString,
5749) Allocator.Error!ErrorInt {
5844 const gop = try mod.global_error_set.getOrPut(mod.gpa, name);5750 const gop = try mod.global_error_set.getOrPut(mod.gpa, name);
5845 if (gop.found_existing) {5751 return @intCast(ErrorInt, gop.index);
5846 return std.StringHashMapUnmanaged(ErrorInt).KV{5752}
5847 .key = gop.key_ptr.*,
5848 .value = gop.value_ptr.*,
5849 };
5850 }
58515753
5852 errdefer assert(mod.global_error_set.remove(name));5754pub fn getErrorValueFromSlice(
5853 try mod.error_name_list.ensureUnusedCapacity(mod.gpa, 1);5755 mod: *Module,
5854 gop.key_ptr.* = try mod.gpa.dupe(u8, name);5756 name: []const u8,
5855 gop.value_ptr.* = @intCast(ErrorInt, mod.error_name_list.items.len);5757) Allocator.Error!ErrorInt {
5856 mod.error_name_list.appendAssumeCapacity(gop.key_ptr.*);5758 const interned_name = try mod.intern_pool.getOrPutString(mod.gpa, name);
5857 return std.StringHashMapUnmanaged(ErrorInt).KV{5759 return getErrorValue(mod, interned_name);
5858 .key = gop.key_ptr.*,
5859 .value = gop.value_ptr.*,
5860 };
5861}5760}
58625761
5863pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !Decl.Index {5762pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !Decl.Index {
...@@ -5874,24 +5773,23 @@ pub fn createAnonymousDeclFromDecl(...@@ -5874,24 +5773,23 @@ pub fn createAnonymousDeclFromDecl(
5874) !Decl.Index {5773) !Decl.Index {
5875 const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope);5774 const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope);
5876 errdefer mod.destroyDecl(new_decl_index);5775 errdefer mod.destroyDecl(new_decl_index);
5877 const name = try std.fmt.allocPrintZ(mod.gpa, "{s}__anon_{d}", .{5776 const ip = &mod.intern_pool;
5878 src_decl.name, @enumToInt(new_decl_index),5777 const name = try ip.getOrPutStringFmt(mod.gpa, "{s}__anon_{d}", .{
5778 ip.stringToSlice(src_decl.name), @enumToInt(new_decl_index),
5879 });5779 });
5880 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, tv, name);5780 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, tv, name);
5881 return new_decl_index;5781 return new_decl_index;
5882}5782}
58835783
5884/// Takes ownership of `name` even if it returns an error.
5885pub fn initNewAnonDecl(5784pub fn initNewAnonDecl(
5886 mod: *Module,5785 mod: *Module,
5887 new_decl_index: Decl.Index,5786 new_decl_index: Decl.Index,
5888 src_line: u32,5787 src_line: u32,
5889 namespace: Namespace.Index,5788 namespace: Namespace.Index,
5890 typed_value: TypedValue,5789 typed_value: TypedValue,
5891 name: [:0]u8,5790 name: InternPool.NullTerminatedString,
5892) Allocator.Error!void {5791) Allocator.Error!void {
5893 assert(typed_value.ty.toIntern() == mod.intern_pool.typeOf(typed_value.val.toIntern()));5792 assert(typed_value.ty.toIntern() == mod.intern_pool.typeOf(typed_value.val.toIntern()));
5894 errdefer mod.gpa.free(name);
58955793
5896 const new_decl = mod.declPtr(new_decl_index);5794 const new_decl = mod.declPtr(new_decl_index);
58975795
...@@ -5900,7 +5798,7 @@ pub fn initNewAnonDecl(...@@ -5900,7 +5798,7 @@ pub fn initNewAnonDecl(
5900 new_decl.ty = typed_value.ty;5798 new_decl.ty = typed_value.ty;
5901 new_decl.val = typed_value.val;5799 new_decl.val = typed_value.val;
5902 new_decl.@"align" = 0;5800 new_decl.@"align" = 0;
5903 new_decl.@"linksection" = null;5801 new_decl.@"linksection" = .none;
5904 new_decl.has_tv = true;5802 new_decl.has_tv = true;
5905 new_decl.analysis = .complete;5803 new_decl.analysis = .complete;
5906 new_decl.generation = mod.generation;5804 new_decl.generation = mod.generation;
...@@ -6330,12 +6228,11 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {...@@ -6330,12 +6228,11 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
6330 // deletion set at this time.6228 // deletion set at this time.
6331 for (file.deleted_decls.items) |decl_index| {6229 for (file.deleted_decls.items) |decl_index| {
6332 const decl = mod.declPtr(decl_index);6230 const decl = mod.declPtr(decl_index);
6333 log.debug("deleted from source: {*} ({s})", .{ decl, decl.name });
63346231
6335 // Remove from the namespace it resides in, preserving declaration order.6232 // Remove from the namespace it resides in, preserving declaration order.
6336 assert(decl.zir_decl_index != 0);6233 assert(decl.zir_decl_index != 0);
6337 _ = mod.namespacePtr(decl.src_namespace).decls.orderedRemoveAdapted(6234 _ = mod.namespacePtr(decl.src_namespace).decls.orderedRemoveAdapted(
6338 @as([]const u8, mem.sliceTo(decl.name, 0)),6235 decl.name,
6339 DeclAdapter{ .mod = mod },6236 DeclAdapter{ .mod = mod },
6340 );6237 );
63416238
...@@ -6357,7 +6254,7 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {...@@ -6357,7 +6254,7 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
6357pub fn processExports(mod: *Module) !void {6254pub fn processExports(mod: *Module) !void {
6358 const gpa = mod.gpa;6255 const gpa = mod.gpa;
6359 // Map symbol names to `Export` for name collision detection.6256 // 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) = .{};
6361 defer symbol_exports.deinit(gpa);6258 defer symbol_exports.deinit(gpa);
63626259
6363 var it = mod.decl_exports.iterator();6260 var it = mod.decl_exports.iterator();
...@@ -6365,13 +6262,13 @@ pub fn processExports(mod: *Module) !void {...@@ -6365,13 +6262,13 @@ pub fn processExports(mod: *Module) !void {
6365 const exported_decl = entry.key_ptr.*;6262 const exported_decl = entry.key_ptr.*;
6366 const exports = entry.value_ptr.items;6263 const exports = entry.value_ptr.items;
6367 for (exports) |new_export| {6264 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);
6369 if (gop.found_existing) {6266 if (gop.found_existing) {
6370 new_export.status = .failed_retryable;6267 new_export.status = .failed_retryable;
6371 try mod.failed_exports.ensureUnusedCapacity(gpa, 1);6268 try mod.failed_exports.ensureUnusedCapacity(gpa, 1);
6372 const src_loc = new_export.getSrcLoc(mod);6269 const src_loc = new_export.getSrcLoc(mod);
6373 const msg = try ErrorMsg.create(gpa, src_loc, "exported symbol collision: {s}", .{6270 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),
6375 });6272 });
6376 errdefer msg.destroy(gpa);6273 errdefer msg.destroy(gpa);
6377 const other_export = gop.value_ptr.*;6274 const other_export = gop.value_ptr.*;
...@@ -6408,8 +6305,9 @@ pub fn populateTestFunctions(...@@ -6408,8 +6305,9 @@ pub fn populateTestFunctions(
6408 const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file;6305 const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file;
6409 const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?);6306 const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?);
6410 const builtin_namespace = mod.namespacePtr(root_decl.src_namespace);6307 const builtin_namespace = mod.namespacePtr(root_decl.src_namespace);
6308 const test_functions_str = try mod.intern_pool.getOrPutString(gpa, "test_functions");
6411 const decl_index = builtin_namespace.decls.getKeyAdapted(6309 const decl_index = builtin_namespace.decls.getKeyAdapted(
6412 @as([]const u8, "test_functions"),6310 test_functions_str,
6413 DeclAdapter{ .mod = mod },6311 DeclAdapter{ .mod = mod },
6414 ).?;6312 ).?;
6415 {6313 {
...@@ -6443,7 +6341,7 @@ pub fn populateTestFunctions(...@@ -6443,7 +6341,7 @@ pub fn populateTestFunctions(
64436341
6444 for (test_fn_vals, mod.test_functions.keys()) |*test_fn_val, test_decl_index| {6342 for (test_fn_vals, mod.test_functions.keys()) |*test_fn_val, test_decl_index| {
6445 const test_decl = mod.declPtr(test_decl_index);6343 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);
6447 const test_name_decl_index = n: {6345 const test_name_decl_index = n: {
6448 const test_name_decl_ty = try mod.arrayType(.{6346 const test_name_decl_ty = try mod.arrayType(.{
6449 .len = test_decl_name.len,6347 .len = test_decl_name.len,
...@@ -7156,7 +7054,7 @@ pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc...@@ -7156,7 +7054,7 @@ pub fn opaqueSrcLoc(mod: *Module, opaque_type: InternPool.Key.OpaqueType) SrcLoc
7156 return mod.declPtr(opaque_type.decl).srcLoc(mod);7054 return mod.declPtr(opaque_type.decl).srcLoc(mod);
7157}7055}
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 {
7160 return mod.declPtr(opaque_type.decl).getFullyQualifiedName(mod);7058 return mod.declPtr(opaque_type.decl).getFullyQualifiedName(mod);
7161}7059}
71627060
src/Sema.zig+655-549
...@@ -11,9 +11,6 @@ gpa: Allocator,...@@ -11,9 +11,6 @@ gpa: Allocator,
11/// Points to the temporary arena allocator of the Sema.11/// Points to the temporary arena allocator of the Sema.
12/// This arena will be cleared when the sema is destroyed.12/// This arena will be cleared when the sema is destroyed.
13arena: Allocator,13arena: Allocator,
14/// Points to the arena allocator for the owner_decl.
15/// This arena will persist until the decl is invalidated.
16perm_arena: Allocator,
17code: Zir,14code: Zir,
18air_instructions: std.MultiArrayList(Air.Inst) = .{},15air_instructions: std.MultiArrayList(Air.Inst) = .{},
19air_extra: std.ArrayListUnmanaged(u32) = .{},16air_extra: std.ArrayListUnmanaged(u32) = .{},
...@@ -740,7 +737,6 @@ pub const Block = struct {...@@ -740,7 +737,6 @@ pub const Block = struct {
740 // TODO: migrate Decl alignment to use `InternPool.Alignment`737 // TODO: migrate Decl alignment to use `InternPool.Alignment`
741 new_decl.@"align" = @intCast(u32, alignment);738 new_decl.@"align" = @intCast(u32, alignment);
742 errdefer sema.mod.abortAnonDecl(new_decl_index);739 errdefer sema.mod.abortAnonDecl(new_decl_index);
743 try new_decl.finalizeNewArena(&wad.new_decl_arena);
744 wad.finished = true;740 wad.finished = true;
745 try sema.mod.finalizeAnonDecl(new_decl_index);741 try sema.mod.finalizeAnonDecl(new_decl_index);
746 return new_decl_index;742 return new_decl_index;
...@@ -1825,6 +1821,20 @@ pub fn resolveConstString(...@@ -1825,6 +1821,20 @@ pub fn resolveConstString(
1825 return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod);1821 return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod);
1826}1822}
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
1828pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {1838pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type {
1829 const air_inst = try sema.resolveInst(zir_ref);1839 const air_inst = try sema.resolveInst(zir_ref);
1830 assert(air_inst != .var_args_param_type);1840 assert(air_inst != .var_args_param_type);
...@@ -1847,11 +1857,13 @@ fn analyzeAsType(...@@ -1847,11 +1857,13 @@ fn analyzeAsType(
18471857
1848pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {1858pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {
1849 const mod = sema.mod;1859 const mod = sema.mod;
1860 const gpa = sema.gpa;
1861 const ip = &mod.intern_pool;
1850 if (!mod.backendSupportsFeature(.error_return_trace)) return;1862 if (!mod.backendSupportsFeature(.error_return_trace)) return;
18511863
1852 assert(!block.is_comptime);1864 assert(!block.is_comptime);
1853 var err_trace_block = block.makeSubBlock();1865 var err_trace_block = block.makeSubBlock();
1854 defer err_trace_block.instructions.deinit(sema.gpa);1866 defer err_trace_block.instructions.deinit(gpa);
18551867
1856 const src: LazySrcLoc = .unneeded;1868 const src: LazySrcLoc = .unneeded;
18571869
...@@ -1866,17 +1878,19 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -1866,17 +1878,19 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
1866 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));1878 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));
18671879
1868 // st.instruction_addresses = &addrs;1880 // 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);
1870 try sema.storePtr2(&err_trace_block, src, addr_field_ptr, src, addrs_ptr, src, .store);1883 try sema.storePtr2(&err_trace_block, src, addr_field_ptr, src, addrs_ptr, src, .store);
18711884
1872 // st.index = 0;1885 // 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);
1874 try sema.storePtr2(&err_trace_block, src, index_field_ptr, src, .zero_usize, src, .store);1888 try sema.storePtr2(&err_trace_block, src, index_field_ptr, src, .zero_usize, src, .store);
18751889
1876 // @errorReturnTrace() = &st;1890 // @errorReturnTrace() = &st;
1877 _ = try err_trace_block.addUnOp(.set_err_return_trace, st_ptr);1891 _ = 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);
1880}1894}
18811895
1882/// May return Value Tags: `variable`, `undef`.1896/// May return Value Tags: `variable`, `undef`.
...@@ -2179,7 +2193,13 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError...@@ -2179,7 +2193,13 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
2179 return sema.failWithOwnedErrorMsg(msg);2193 return sema.failWithOwnedErrorMsg(msg);
2180}2194}
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 {
2183 const mod = sema.mod;2203 const mod = sema.mod;
2184 const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType(mod) else object_ty;2204 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...@@ -2207,15 +2227,16 @@ fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, objec
2207 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});2227 return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
2208}2228}
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;
2211 switch (ty.zigTypeTag(mod)) {2232 switch (ty.zigTypeTag(mod)) {
2212 .Array => return mem.eql(u8, field_name, "len"),2233 .Array => return ip.stringEqlSlice(field_name, "len"),
2213 .Pointer => {2234 .Pointer => {
2214 const ptr_info = ty.ptrInfo(mod);2235 const ptr_info = ty.ptrInfo(mod);
2215 if (ptr_info.size == .Slice) {2236 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");
2217 } else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {2238 } else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) {
2218 return mem.eql(u8, field_name, "len");2239 return ip.stringEqlSlice(field_name, "len");
2219 } else return false;2240 } else return false;
2220 },2241 },
2221 .Type, .Struct, .Union => return true,2242 .Type, .Struct, .Union => return true,
...@@ -2308,19 +2329,19 @@ pub fn fail(...@@ -2308,19 +2329,19 @@ pub fn fail(
2308fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {2329fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {
2309 @setCold(true);2330 @setCold(true);
2310 const gpa = sema.gpa;2331 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) {
2313 if (err_msg.src_loc.lazy == .unneeded) return error.NeededSourceLocation;2335 if (err_msg.src_loc.lazy == .unneeded) return error.NeededSourceLocation;
2314 var wip_errors: std.zig.ErrorBundle.Wip = undefined;2336 var wip_errors: std.zig.ErrorBundle.Wip = undefined;
2315 wip_errors.init(gpa) catch unreachable;2337 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;
2317 std.debug.print("compile error during Sema:\n", .{});2339 std.debug.print("compile error during Sema:\n", .{});
2318 var error_bundle = wip_errors.toOwnedBundle("") catch unreachable;2340 var error_bundle = wip_errors.toOwnedBundle("") catch unreachable;
2319 error_bundle.renderToStdErr(.{ .ttyconf = .no_color });2341 error_bundle.renderToStdErr(.{ .ttyconf = .no_color });
2320 crash_report.compilerPanic("unexpected compile error occurred", null, null);2342 crash_report.compilerPanic("unexpected compile error occurred", null, null);
2321 }2343 }
23222344
2323 const mod = sema.mod;
2324 ref: {2345 ref: {
2325 errdefer err_msg.destroy(gpa);2346 errdefer err_msg.destroy(gpa);
2326 if (err_msg.src_loc.lazy == .unneeded) {2347 if (err_msg.src_loc.lazy == .unneeded) {
...@@ -2330,9 +2351,9 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {...@@ -2330,9 +2351,9 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {
2330 try mod.failed_files.ensureUnusedCapacity(gpa, 1);2351 try mod.failed_files.ensureUnusedCapacity(gpa, 1);
23312352
2332 const max_references = blk: {2353 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;
2334 // Do not add multiple traces without explicit request.2355 // 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;
2336 break :blk default_reference_trace_len;2357 break :blk default_reference_trace_len;
2337 };2358 };
23382359
...@@ -2350,13 +2371,16 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {...@@ -2350,13 +2371,16 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError {
2350 if (gop.found_existing) break;2371 if (gop.found_existing) break;
2351 if (cur_reference_trace < max_references) {2372 if (cur_reference_trace < max_references) {
2352 const decl = sema.mod.declPtr(ref.referencer);2373 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 });
2354 }2378 }
2355 referenced_by = ref.referencer;2379 referenced_by = ref.referencer;
2356 }2380 }
2357 if (sema.mod.comp.reference_trace == null and cur_reference_trace > 0) {2381 if (sema.mod.comp.reference_trace == null and cur_reference_trace > 0) {
2358 try reference_stack.append(.{2382 try reference_stack.append(.{
2359 .decl = null,2383 .decl = .none,
2360 .src_loc = undefined,2384 .src_loc = undefined,
2361 .hidden = 0,2385 .hidden = 0,
2362 });2386 });
...@@ -2795,7 +2819,6 @@ fn zirStructDecl(...@@ -2795,7 +2819,6 @@ fn zirStructDecl(
2795 new_namespace.ty = struct_ty.toType();2819 new_namespace.ty = struct_ty.toType();
27962820
2797 try sema.analyzeStructDecl(new_decl, inst, struct_index);2821 try sema.analyzeStructDecl(new_decl, inst, struct_index);
2798 try new_decl.finalizeNewArena(&new_decl_arena);
2799 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);2822 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
2800 try mod.finalizeAnonDecl(new_decl_index);2823 try mod.finalizeAnonDecl(new_decl_index);
2801 return decl_val;2824 return decl_val;
...@@ -2812,6 +2835,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2812,6 +2835,7 @@ fn createAnonymousDeclTypeNamed(
2812) !Decl.Index {2835) !Decl.Index {
2813 const mod = sema.mod;2836 const mod = sema.mod;
2814 const gpa = sema.gpa;2837 const gpa = sema.gpa;
2838 const ip = &mod.intern_pool;
2815 const namespace = block.namespace;2839 const namespace = block.namespace;
2816 const src_scope = block.wip_capture_scope;2840 const src_scope = block.wip_capture_scope;
2817 const src_decl = mod.declPtr(block.src_decl);2841 const src_decl = mod.declPtr(block.src_decl);
...@@ -2827,16 +2851,19 @@ fn createAnonymousDeclTypeNamed(...@@ -2827,16 +2851,19 @@ fn createAnonymousDeclTypeNamed(
2827 // semantically analyzed.2851 // semantically analyzed.
2828 // This name is also used as the key in the parent namespace so it cannot be2852 // This name is also used as the key in the parent namespace so it cannot be
2829 // renamed.2853 // renamed.
2830 const name = try std.fmt.allocPrintZ(gpa, "{s}__{s}_{d}", .{2854
2831 src_decl.name, anon_prefix, @enumToInt(new_decl_index),2855 // This ensureUnusedCapacity protects against the src_decl slice from being
2832 });2856 // reallocated during the call to `getOrPutStringFmt`.
2833 errdefer gpa.free(name);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;
2834 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);2862 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
2835 return new_decl_index;2863 return new_decl_index;
2836 },2864 },
2837 .parent => {2865 .parent => {
2838 const name = try gpa.dupeZ(u8, mem.sliceTo(sema.mod.declPtr(block.src_decl).name, 0));2866 const name = mod.declPtr(block.src_decl).name;
2839 errdefer gpa.free(name);
2840 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);2867 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
2841 return new_decl_index;2868 return new_decl_index;
2842 },2869 },
...@@ -2846,7 +2873,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2846,7 +2873,7 @@ fn createAnonymousDeclTypeNamed(
28462873
2847 var buf = std.ArrayList(u8).init(gpa);2874 var buf = std.ArrayList(u8).init(gpa);
2848 defer buf.deinit();2875 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));
2850 try buf.appendSlice("(");2877 try buf.appendSlice("(");
28512878
2852 var arg_i: usize = 0;2879 var arg_i: usize = 0;
...@@ -2871,8 +2898,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2871,8 +2898,7 @@ fn createAnonymousDeclTypeNamed(
2871 };2898 };
28722899
2873 try buf.appendSlice(")");2900 try buf.appendSlice(")");
2874 const name = try buf.toOwnedSliceSentinel(0);2901 const name = try ip.getOrPutString(gpa, buf.items);
2875 errdefer gpa.free(name);
2876 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);2902 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
2877 return new_decl_index;2903 return new_decl_index;
2878 },2904 },
...@@ -2885,10 +2911,17 @@ fn createAnonymousDeclTypeNamed(...@@ -2885,10 +2911,17 @@ fn createAnonymousDeclTypeNamed(
2885 .dbg_var_ptr, .dbg_var_val => {2911 .dbg_var_ptr, .dbg_var_val => {
2886 if (zir_data[i].str_op.operand != ref) continue;2912 if (zir_data[i].str_op.operand != ref) continue;
28872913
2888 const name = try std.fmt.allocPrintZ(gpa, "{s}.{s}", .{2914 // This ensureUnusedCapacity protects against the src_decl
2889 src_decl.name, zir_data[i].str_op.getStr(sema.code),2915 // slice from being reallocated during the call to
2890 });2916 // `getOrPutStringFmt`.
2891 errdefer gpa.free(name);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
2893 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);2926 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, namespace, typed_value, name);
2894 return new_decl_index;2927 return new_decl_index;
...@@ -3249,7 +3282,6 @@ fn zirUnionDecl(...@@ -3249,7 +3282,6 @@ fn zirUnionDecl(
32493282
3250 _ = try mod.scanNamespace(new_namespace_index, extra_index, decls_len, new_decl);3283 _ = try mod.scanNamespace(new_namespace_index, extra_index, decls_len, new_decl);
32513284
3252 try new_decl.finalizeNewArena(&new_decl_arena);
3253 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);3285 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
3254 try mod.finalizeAnonDecl(new_decl_index);3286 try mod.finalizeAnonDecl(new_decl_index);
3255 return decl_val;3287 return decl_val;
...@@ -3315,7 +3347,6 @@ fn zirOpaqueDecl(...@@ -3315,7 +3347,6 @@ fn zirOpaqueDecl(
33153347
3316 extra_index = try mod.scanNamespace(new_namespace_index, extra_index, decls_len, new_decl);3348 extra_index = try mod.scanNamespace(new_namespace_index, extra_index, decls_len, new_decl);
33173349
3318 try new_decl.finalizeNewArena(&new_decl_arena);
3319 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);3350 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
3320 try mod.finalizeAnonDecl(new_decl_index);3351 try mod.finalizeAnonDecl(new_decl_index);
3321 return decl_val;3352 return decl_val;
...@@ -3344,8 +3375,8 @@ fn zirErrorSetDecl(...@@ -3344,8 +3375,8 @@ fn zirErrorSetDecl(
3344 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string3375 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
3345 const str_index = sema.code.extra[extra_index];3376 const str_index = sema.code.extra[extra_index];
3346 const name = sema.code.nullTerminatedString(str_index);3377 const name = sema.code.nullTerminatedString(str_index);
3347 const kv = try mod.getErrorValue(name);3378 const name_ip = try mod.intern_pool.getOrPutString(gpa, name);
3348 const name_ip = try mod.intern_pool.getOrPutString(gpa, kv.key);3379 _ = try mod.getErrorValue(name_ip);
3349 const result = names.getOrPutAssumeCapacity(name_ip);3380 const result = names.getOrPutAssumeCapacity(name_ip);
3350 assert(!result.found_existing); // verified in AstGen3381 assert(!result.found_existing); // verified in AstGen
3351 }3382 }
...@@ -3512,7 +3543,8 @@ fn indexablePtrLen(...@@ -3512,7 +3543,8 @@ fn indexablePtrLen(
3512 const is_pointer_to = object_ty.isSinglePointer(mod);3543 const is_pointer_to = object_ty.isSinglePointer(mod);
3513 const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty;3544 const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty;
3514 try checkIndexable(sema, block, src, indexable_ty);3545 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);
3516}3548}
35173549
3518fn indexablePtrLenOrNone(3550fn indexablePtrLenOrNone(
...@@ -3525,7 +3557,8 @@ fn indexablePtrLenOrNone(...@@ -3525,7 +3557,8 @@ fn indexablePtrLenOrNone(
3525 const operand_ty = sema.typeOf(operand);3557 const operand_ty = sema.typeOf(operand);
3526 try checkMemOperand(sema, block, src, operand_ty);3558 try checkMemOperand(sema, block, src, operand_ty);
3527 if (operand_ty.ptrSize(mod) == .Many) return .none;3559 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);
3529}3562}
35303563
3531fn zirAllocExtended(3564fn zirAllocExtended(
...@@ -4079,6 +4112,7 @@ fn zirFieldBasePtr(...@@ -4079,6 +4112,7 @@ fn zirFieldBasePtr(
4079fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {4112fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
4080 const mod = sema.mod;4113 const mod = sema.mod;
4081 const gpa = sema.gpa;4114 const gpa = sema.gpa;
4115 const ip = &mod.intern_pool;
4082 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;4116 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
4083 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);4117 const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index);
4084 const args = sema.code.refSlice(extra.end, extra.data.operands_len);4118 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....@@ -4122,7 +4156,7 @@ fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
4122 }4156 }
4123 if (!object_ty.indexableHasLen(mod)) continue;4157 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);
4126 };4160 };
4127 const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src);4161 const arg_len = try sema.coerce(block, Type.usize, arg_len_uncoerced, arg_src);
4128 if (len == .none) {4162 if (len == .none) {
...@@ -4308,6 +4342,7 @@ fn validateUnionInit(...@@ -4308,6 +4342,7 @@ fn validateUnionInit(
4308 union_ptr: Air.Inst.Ref,4342 union_ptr: Air.Inst.Ref,
4309) CompileError!void {4343) CompileError!void {
4310 const mod = sema.mod;4344 const mod = sema.mod;
4345 const gpa = sema.gpa;
43114346
4312 if (instrs.len != 1) {4347 if (instrs.len != 1) {
4313 const msg = msg: {4348 const msg = msg: {
...@@ -4317,7 +4352,7 @@ fn validateUnionInit(...@@ -4317,7 +4352,7 @@ fn validateUnionInit(
4317 "cannot initialize multiple union fields at once; unions can only have one active field",4352 "cannot initialize multiple union fields at once; unions can only have one active field",
4318 .{},4353 .{},
4319 );4354 );
4320 errdefer msg.destroy(sema.gpa);4355 errdefer msg.destroy(gpa);
43214356
4322 for (instrs[1..]) |inst| {4357 for (instrs[1..]) |inst| {
4323 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;4358 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
...@@ -4341,7 +4376,7 @@ fn validateUnionInit(...@@ -4341,7 +4376,7 @@ fn validateUnionInit(
4341 const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node;4376 const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node;
4342 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };4377 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };
4343 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;4378 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));
4345 // Validate the field access but ignore the index since we want the tag enum field index.4380 // Validate the field access but ignore the index since we want the tag enum field index.
4346 _ = try sema.unionFieldIndex(block, union_ty, field_name, field_src);4381 _ = try sema.unionFieldIndex(block, union_ty, field_name, field_src);
4347 const air_tags = sema.air_instructions.items(.tag);4382 const air_tags = sema.air_instructions.items(.tag);
...@@ -4444,6 +4479,7 @@ fn validateStructInit(...@@ -4444,6 +4479,7 @@ fn validateStructInit(
4444) CompileError!void {4479) CompileError!void {
4445 const mod = sema.mod;4480 const mod = sema.mod;
4446 const gpa = sema.gpa;4481 const gpa = sema.gpa;
4482 const ip = &mod.intern_pool;
44474483
4448 // Maps field index to field_ptr index of where it was already initialized.4484 // Maps field index to field_ptr index of where it was already initialized.
4449 const found_fields = try gpa.alloc(Zir.Inst.Index, struct_ty.structFieldCount(mod));4485 const found_fields = try gpa.alloc(Zir.Inst.Index, struct_ty.structFieldCount(mod));
...@@ -4457,7 +4493,10 @@ fn validateStructInit(...@@ -4457,7 +4493,10 @@ fn validateStructInit(
4457 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };4493 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_ptr_data.src_node };
4458 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;4494 const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data;
4459 struct_ptr_zir_ref = field_ptr_extra.lhs;4495 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 );
4461 const field_index = if (struct_ty.isTuple(mod))4500 const field_index = if (struct_ty.isTuple(mod))
4462 try sema.tupleFieldIndex(block, struct_ty, field_name, field_src)4501 try sema.tupleFieldIndex(block, struct_ty, field_name, field_src)
4463 else4502 else
...@@ -4504,7 +4543,7 @@ fn validateStructInit(...@@ -4504,7 +4543,7 @@ fn validateStructInit(
4504 }4543 }
4505 const field_name = struct_ty.structFieldName(i, mod);4544 const field_name = struct_ty.structFieldName(i, mod);
4506 const template = "missing struct field: {s}";4545 const template = "missing struct field: {s}";
4507 const args = .{field_name};4546 const args = .{ip.stringToSlice(field_name)};
4508 if (root_msg) |msg| {4547 if (root_msg) |msg| {
4509 try sema.errNote(block, init_src, msg, template, args);4548 try sema.errNote(block, init_src, msg, template, args);
4510 } else {4549 } else {
...@@ -4525,8 +4564,7 @@ fn validateStructInit(...@@ -4525,8 +4564,7 @@ fn validateStructInit(
45254564
4526 if (root_msg) |msg| {4565 if (root_msg) |msg| {
4527 if (mod.typeToStruct(struct_ty)) |struct_obj| {4566 if (mod.typeToStruct(struct_ty)) |struct_obj| {
4528 const fqn = try struct_obj.getFullyQualifiedName(mod);4567 const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
4529 defer gpa.free(fqn);
4530 try mod.errNoteNonLazy(4568 try mod.errNoteNonLazy(
4531 struct_obj.srcLoc(mod),4569 struct_obj.srcLoc(mod),
4532 msg,4570 msg,
...@@ -4649,7 +4687,7 @@ fn validateStructInit(...@@ -4649,7 +4687,7 @@ fn validateStructInit(
4649 }4687 }
4650 const field_name = struct_ty.structFieldName(i, mod);4688 const field_name = struct_ty.structFieldName(i, mod);
4651 const template = "missing struct field: {s}";4689 const template = "missing struct field: {s}";
4652 const args = .{field_name};4690 const args = .{ip.stringToSlice(field_name)};
4653 if (root_msg) |msg| {4691 if (root_msg) |msg| {
4654 try sema.errNote(block, init_src, msg, template, args);4692 try sema.errNote(block, init_src, msg, template, args);
4655 } else {4693 } else {
...@@ -4662,10 +4700,9 @@ fn validateStructInit(...@@ -4662,10 +4700,9 @@ fn validateStructInit(
46624700
4663 if (root_msg) |msg| {4701 if (root_msg) |msg| {
4664 if (mod.typeToStruct(struct_ty)) |struct_obj| {4702 if (mod.typeToStruct(struct_ty)) |struct_obj| {
4665 const fqn = try struct_obj.getFullyQualifiedName(sema.mod);4703 const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
4666 defer gpa.free(fqn);
4667 try sema.mod.errNoteNonLazy(4704 try sema.mod.errNoteNonLazy(
4668 struct_obj.srcLoc(sema.mod),4705 struct_obj.srcLoc(mod),
4669 msg,4706 msg,
4670 "struct '{s}' declared here",4707 "struct '{s}' declared here",
4671 .{fqn},4708 .{fqn},
...@@ -4949,7 +4986,7 @@ fn failWithBadMemberAccess(...@@ -4949,7 +4986,7 @@ fn failWithBadMemberAccess(
4949 block: *Block,4986 block: *Block,
4950 agg_ty: Type,4987 agg_ty: Type,
4951 field_src: LazySrcLoc,4988 field_src: LazySrcLoc,
4952 field_name: []const u8,4989 field_name_nts: InternPool.NullTerminatedString,
4953) CompileError {4990) CompileError {
4954 const mod = sema.mod;4991 const mod = sema.mod;
4955 const kw_name = switch (agg_ty.zigTypeTag(mod)) {4992 const kw_name = switch (agg_ty.zigTypeTag(mod)) {
...@@ -4959,6 +4996,7 @@ fn failWithBadMemberAccess(...@@ -4959,6 +4996,7 @@ fn failWithBadMemberAccess(
4959 .Enum => "enum",4996 .Enum => "enum",
4960 else => unreachable,4997 else => unreachable,
4961 };4998 };
4999 const field_name = mod.intern_pool.stringToSlice(field_name_nts);
4962 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (sema.mod.declIsRoot(some)) {5000 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (sema.mod.declIsRoot(some)) {
4963 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{s}'", .{5001 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{s}'", .{
4964 agg_ty.fmt(sema.mod), field_name,5002 agg_ty.fmt(sema.mod), field_name,
...@@ -4980,22 +5018,23 @@ fn failWithBadStructFieldAccess(...@@ -4980,22 +5018,23 @@ fn failWithBadStructFieldAccess(
4980 block: *Block,5018 block: *Block,
4981 struct_obj: *Module.Struct,5019 struct_obj: *Module.Struct,
4982 field_src: LazySrcLoc,5020 field_src: LazySrcLoc,
4983 field_name: []const u8,5021 field_name: InternPool.NullTerminatedString,
4984) CompileError {5022) CompileError {
5023 const mod = sema.mod;
4985 const gpa = sema.gpa;5024 const gpa = sema.gpa;
5025 const ip = &mod.intern_pool;
49865026
4987 const fqn = try struct_obj.getFullyQualifiedName(sema.mod);5027 const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
4988 defer gpa.free(fqn);
49895028
4990 const msg = msg: {5029 const msg = msg: {
4991 const msg = try sema.errMsg(5030 const msg = try sema.errMsg(
4992 block,5031 block,
4993 field_src,5032 field_src,
4994 "no field named '{s}' in struct '{s}'",5033 "no field named '{s}' in struct '{s}'",
4995 .{ field_name, fqn },5034 .{ ip.stringToSlice(field_name), fqn },
4996 );5035 );
4997 errdefer msg.destroy(gpa);5036 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", .{});
4999 break :msg msg;5038 break :msg msg;
5000 };5039 };
5001 return sema.failWithOwnedErrorMsg(msg);5040 return sema.failWithOwnedErrorMsg(msg);
...@@ -5006,22 +5045,23 @@ fn failWithBadUnionFieldAccess(...@@ -5006,22 +5045,23 @@ fn failWithBadUnionFieldAccess(
5006 block: *Block,5045 block: *Block,
5007 union_obj: *Module.Union,5046 union_obj: *Module.Union,
5008 field_src: LazySrcLoc,5047 field_src: LazySrcLoc,
5009 field_name: []const u8,5048 field_name: InternPool.NullTerminatedString,
5010) CompileError {5049) CompileError {
5050 const mod = sema.mod;
5011 const gpa = sema.gpa;5051 const gpa = sema.gpa;
5052 const ip = &mod.intern_pool;
50125053
5013 const fqn = try union_obj.getFullyQualifiedName(sema.mod);5054 const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod));
5014 defer gpa.free(fqn);
50155055
5016 const msg = msg: {5056 const msg = msg: {
5017 const msg = try sema.errMsg(5057 const msg = try sema.errMsg(
5018 block,5058 block,
5019 field_src,5059 field_src,
5020 "no field named '{s}' in union '{s}'",5060 "no field named '{s}' in union '{s}'",
5021 .{ field_name, fqn },5061 .{ ip.stringToSlice(field_name), fqn },
5022 );5062 );
5023 errdefer msg.destroy(gpa);5063 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", .{});
5025 break :msg msg;5065 break :msg msg;
5026 };5066 };
5027 return sema.failWithOwnedErrorMsg(msg);5067 return sema.failWithOwnedErrorMsg(msg);
...@@ -5772,7 +5812,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -5772,7 +5812,7 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
5772 const src = inst_data.src();5812 const src = inst_data.src();
5773 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };5813 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
5774 const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };5814 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));
5776 const decl_index = if (extra.namespace != .none) index_blk: {5816 const decl_index = if (extra.namespace != .none) index_blk: {
5777 const container_ty = try sema.resolveType(block, operand_src, extra.namespace);5817 const container_ty = try sema.resolveType(block, operand_src, extra.namespace);
5778 const container_namespace = container_ty.getNamespaceIndex(mod).unwrap().?;5818 const container_namespace = container_ty.getNamespaceIndex(mod).unwrap().?;
...@@ -5875,19 +5915,14 @@ pub fn analyzeExport(...@@ -5875,19 +5915,14 @@ pub fn analyzeExport(
5875 const new_export = try gpa.create(Export);5915 const new_export = try gpa.create(Export);
5876 errdefer gpa.destroy(new_export);5916 errdefer gpa.destroy(new_export);
58775917
5878 const symbol_name = try gpa.dupe(u8, borrowed_options.name);5918 const symbol_name = try mod.intern_pool.getOrPutString(gpa, borrowed_options.name);
5879 errdefer gpa.free(symbol_name);5919 const section = try mod.intern_pool.getOrPutStringOpt(gpa, borrowed_options.section);
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);
58835920
5884 new_export.* = .{5921 new_export.* = .{
5885 .options = .{5922 .name = symbol_name,
5886 .name = symbol_name,5923 .linkage = borrowed_options.linkage,
5887 .linkage = borrowed_options.linkage,5924 .section = section,
5888 .section = section,5925 .visibility = borrowed_options.visibility,
5889 .visibility = borrowed_options.visibility,
5890 },
5891 .src = src,5926 .src = src,
5892 .owner_decl = sema.owner_decl_index,5927 .owner_decl = sema.owner_decl_index,
5893 .src_decl = block.src_decl,5928 .src_decl = block.src_decl,
...@@ -6121,23 +6156,25 @@ fn addDbgVar(...@@ -6121,23 +6156,25 @@ fn addDbgVar(
6121}6156}
61226157
6123fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6158fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6159 const mod = sema.mod;
6124 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;6160 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
6125 const src = inst_data.src();6161 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));
6127 const decl_index = try sema.lookupIdentifier(block, src, decl_name);6163 const decl_index = try sema.lookupIdentifier(block, src, decl_name);
6128 try sema.addReferencedBy(block, src, decl_index);6164 try sema.addReferencedBy(block, src, decl_index);
6129 return sema.analyzeDeclRef(decl_index);6165 return sema.analyzeDeclRef(decl_index);
6130}6166}
61316167
6132fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6168fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6169 const mod = sema.mod;
6133 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;6170 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
6134 const src = inst_data.src();6171 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));
6136 const decl = try sema.lookupIdentifier(block, src, decl_name);6173 const decl = try sema.lookupIdentifier(block, src, decl_name);
6137 return sema.analyzeDeclVal(block, src, decl);6174 return sema.analyzeDeclVal(block, src, decl);
6138}6175}
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 {
6141 const mod = sema.mod;6178 const mod = sema.mod;
6142 var namespace = block.namespace;6179 var namespace = block.namespace;
6143 while (true) {6180 while (true) {
...@@ -6156,7 +6193,7 @@ fn lookupInNamespace(...@@ -6156,7 +6193,7 @@ fn lookupInNamespace(
6156 block: *Block,6193 block: *Block,
6157 src: LazySrcLoc,6194 src: LazySrcLoc,
6158 namespace_index: Namespace.Index,6195 namespace_index: Namespace.Index,
6159 ident_name: []const u8,6196 ident_name: InternPool.NullTerminatedString,
6160 observe_usingnamespace: bool,6197 observe_usingnamespace: bool,
6161) CompileError!?Decl.Index {6198) CompileError!?Decl.Index {
6162 const mod = sema.mod;6199 const mod = sema.mod;
...@@ -6249,9 +6286,6 @@ fn lookupInNamespace(...@@ -6249,9 +6286,6 @@ fn lookupInNamespace(
6249 return decl_index;6286 return decl_index;
6250 }6287 }
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 });
6255 // TODO This dependency is too strong. Really, it should only be a dependency6289 // TODO This dependency is too strong. Really, it should only be a dependency
6256 // on the non-existence of `ident_name` in the namespace. We can lessen the number of6290 // on the non-existence of `ident_name` in the namespace. We can lessen the number of
6257 // outdated declarations by making this dependency more sophisticated.6291 // outdated declarations by making this dependency more sophisticated.
...@@ -6276,10 +6310,12 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {...@@ -6276,10 +6310,12 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
6276}6310}
62776311
6278pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {6312pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
6313 const mod = sema.mod;
6314 const gpa = sema.gpa;
6279 const src = sema.src;6315 const src = sema.src;
62806316
6281 if (!sema.mod.backendSupportsFeature(.error_return_trace)) return .none;6317 if (!mod.backendSupportsFeature(.error_return_trace)) return .none;
6282 if (!sema.mod.comp.bin_file.options.error_return_tracing) return .none;6318 if (!mod.comp.bin_file.options.error_return_tracing) return .none;
62836319
6284 if (block.is_comptime)6320 if (block.is_comptime)
6285 return .none;6321 return .none;
...@@ -6292,7 +6328,8 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref...@@ -6292,7 +6328,8 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
6292 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,6328 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
6293 else => |e| return e,6329 else => |e| return e,
6294 };6330 };
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) {
6296 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,6333 error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
6297 else => |e| return e,6334 else => |e| return e,
6298 };6335 };
...@@ -6316,6 +6353,7 @@ fn popErrorReturnTrace(...@@ -6316,6 +6353,7 @@ fn popErrorReturnTrace(
6316 saved_error_trace_index: Air.Inst.Ref,6353 saved_error_trace_index: Air.Inst.Ref,
6317) CompileError!void {6354) CompileError!void {
6318 const mod = sema.mod;6355 const mod = sema.mod;
6356 const gpa = sema.gpa;
6319 var is_non_error: ?bool = null;6357 var is_non_error: ?bool = null;
6320 var is_non_error_inst: Air.Inst.Ref = undefined;6358 var is_non_error_inst: Air.Inst.Ref = undefined;
6321 if (operand != .none) {6359 if (operand != .none) {
...@@ -6332,13 +6370,14 @@ fn popErrorReturnTrace(...@@ -6332,13 +6370,14 @@ fn popErrorReturnTrace(
6332 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);6370 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
6333 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6371 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
6334 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);6372 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);
6336 try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);6375 try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store);
6337 } else if (is_non_error == null) {6376 } else if (is_non_error == null) {
6338 // The result might be an error. If it is, we leave the error trace alone. If it isn't, we need6377 // The result might be an error. If it is, we leave the error trace alone. If it isn't, we need
6339 // to pop any error trace that may have been propagated from our arguments.6378 // 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);
6342 const cond_block_inst = try block.addInstAsIndex(.{6381 const cond_block_inst = try block.addInstAsIndex(.{
6343 .tag = .block,6382 .tag = .block,
6344 .data = .{6383 .data = .{
...@@ -6350,28 +6389,29 @@ fn popErrorReturnTrace(...@@ -6350,28 +6389,29 @@ fn popErrorReturnTrace(
6350 });6389 });
63516390
6352 var then_block = block.makeSubBlock();6391 var then_block = block.makeSubBlock();
6353 defer then_block.instructions.deinit(sema.gpa);6392 defer then_block.instructions.deinit(gpa);
63546393
6355 // If non-error, then pop the error return trace by restoring the index.6394 // If non-error, then pop the error return trace by restoring the index.
6356 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");6395 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
6357 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);6396 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
6358 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6397 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
6359 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);6398 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);
6361 try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);6401 try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store);
6362 _ = try then_block.addBr(cond_block_inst, Air.Inst.Ref.void_value);6402 _ = try then_block.addBr(cond_block_inst, Air.Inst.Ref.void_value);
63636403
6364 // Otherwise, do nothing6404 // Otherwise, do nothing
6365 var else_block = block.makeSubBlock();6405 var else_block = block.makeSubBlock();
6366 defer else_block.instructions.deinit(sema.gpa);6406 defer else_block.instructions.deinit(gpa);
6367 _ = try else_block.addBr(cond_block_inst, Air.Inst.Ref.void_value);6407 _ = 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 +
6370 then_block.instructions.items.len + else_block.instructions.items.len +6410 then_block.instructions.items.len + else_block.instructions.items.len +
6371 @typeInfo(Air.Block).Struct.fields.len + 1); // +1 for the sole .cond_br instruction in the .block6411 @typeInfo(Air.Block).Struct.fields.len + 1); // +1 for the sole .cond_br instruction in the .block
63726412
6373 const cond_br_inst = @intCast(Air.Inst.Index, sema.air_instructions.len);6413 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 = .{
6375 .operand = is_non_error_inst,6415 .operand = is_non_error_inst,
6376 .payload = sema.addExtraAssumeCapacity(Air.CondBr{6416 .payload = sema.addExtraAssumeCapacity(Air.CondBr{
6377 .then_body_len = @intCast(u32, then_block.instructions.items.len),6417 .then_body_len = @intCast(u32, then_block.instructions.items.len),
...@@ -6414,7 +6454,7 @@ fn zirCall(...@@ -6414,7 +6454,7 @@ fn zirCall(
6414 .direct => .{ .direct = try sema.resolveInst(extra.data.callee) },6454 .direct => .{ .direct = try sema.resolveInst(extra.data.callee) },
6415 .field => blk: {6455 .field => blk: {
6416 const object_ptr = try sema.resolveInst(extra.data.obj_ptr);6456 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));
6418 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };6458 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
6419 break :blk try sema.fieldCallBind(block, callee_src, object_ptr, field_name, field_name_src);6459 break :blk try sema.fieldCallBind(block, callee_src, object_ptr, field_name, field_name_src);
6420 },6460 },
...@@ -6509,7 +6549,8 @@ fn zirCall(...@@ -6509,7 +6549,8 @@ fn zirCall(
6509 if (input_is_error or (pop_error_return_trace and modifier != .always_tail and return_ty.isError(mod))) {6549 if (input_is_error or (pop_error_return_trace and modifier != .always_tail and return_ty.isError(mod))) {
6510 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");6550 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
6511 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);6551 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
6514 // Insert a save instruction before the arg resolution + call instructions we just generated6555 // Insert a save instruction before the arg resolution + call instructions we just generated
6515 const save_inst = try block.insertInst(block_index, .{6556 const save_inst = try block.insertInst(block_index, .{
...@@ -7436,9 +7477,10 @@ fn instantiateGenericCall(...@@ -7436,9 +7477,10 @@ fn instantiateGenericCall(
7436) CompileError!Air.Inst.Ref {7477) CompileError!Air.Inst.Ref {
7437 const mod = sema.mod;7478 const mod = sema.mod;
7438 const gpa = sema.gpa;7479 const gpa = sema.gpa;
7480 const ip = &mod.intern_pool;
74397481
7440 const func_val = try sema.resolveConstValue(block, func_src, func, "generic function being called must be comptime-known");7482 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())) {
7442 .func => |function| function.index,7484 .func => |function| function.index,
7443 .ptr => |ptr| mod.declPtr(ptr.addr.decl).val.getFunctionIndex(mod).unwrap().?,7485 .ptr => |ptr| mod.declPtr(ptr.addr.decl).val.getFunctionIndex(mod).unwrap().?,
7444 else => unreachable,7486 else => unreachable,
...@@ -7567,9 +7609,12 @@ fn instantiateGenericCall(...@@ -7567,9 +7609,12 @@ fn instantiateGenericCall(
7567 const new_decl_index = try mod.allocateNewDecl(namespace_index, fn_owner_decl.src_node, src_decl.src_scope);7609 const new_decl_index = try mod.allocateNewDecl(namespace_index, fn_owner_decl.src_node, src_decl.src_scope);
7568 const new_decl = mod.declPtr(new_decl_index);7610 const new_decl = mod.declPtr(new_decl_index);
7569 // TODO better names for generic function instantiations7611 // TODO better names for generic function instantiations
7570 const decl_name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{7612 // The ensureUnusedCapacity here protects against fn_owner_decl.name slice being
7571 fn_owner_decl.name, @enumToInt(new_decl_index),7613 // reallocated during getOrPutStringFmt.
7572 });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;
7573 new_decl.name = decl_name;7618 new_decl.name = decl_name;
7574 new_decl.src_line = fn_owner_decl.src_line;7619 new_decl.src_line = fn_owner_decl.src_line;
7575 new_decl.is_pub = fn_owner_decl.is_pub;7620 new_decl.is_pub = fn_owner_decl.is_pub;
...@@ -7590,12 +7635,8 @@ fn instantiateGenericCall(...@@ -7590,12 +7635,8 @@ fn instantiateGenericCall(
7590 assert(new_decl.dependencies.keys().len == 0);7635 assert(new_decl.dependencies.keys().len == 0);
7591 try mod.declareDeclDependencyType(new_decl_index, module_fn.owner_decl, .function_body);7636 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
7596 const new_func = sema.resolveGenericInstantiationType(7638 const new_func = sema.resolveGenericInstantiationType(
7597 block,7639 block,
7598 new_decl_arena_allocator,
7599 fn_zir,7640 fn_zir,
7600 new_decl,7641 new_decl,
7601 new_decl_index,7642 new_decl_index,
...@@ -7608,7 +7649,6 @@ fn instantiateGenericCall(...@@ -7608,7 +7649,6 @@ fn instantiateGenericCall(
7608 bound_arg_src,7649 bound_arg_src,
7609 ) catch |err| switch (err) {7650 ) catch |err| switch (err) {
7610 error.GenericPoison, error.ComptimeReturn => {7651 error.GenericPoison, error.ComptimeReturn => {
7611 new_decl_arena.deinit();
7612 // Resolving the new function type below will possibly declare more decl dependencies7652 // Resolving the new function type below will possibly declare more decl dependencies
7613 // and so we remove them all here in case of error.7653 // and so we remove them all here in case of error.
7614 for (new_decl.dependencies.keys()) |dep_index| {7654 for (new_decl.dependencies.keys()) |dep_index| {
...@@ -7623,10 +7663,6 @@ fn instantiateGenericCall(...@@ -7623,10 +7663,6 @@ fn instantiateGenericCall(
7623 },7663 },
7624 else => {7664 else => {
7625 assert(mod.monomorphed_funcs.removeContext(new_module_func_index, .{ .mod = mod }));7665 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 }
7630 // TODO look up the compile error that happened here and attach a note to it7666 // TODO look up the compile error that happened here and attach a note to it
7631 // pointing here, at the generic instantiation callsite.7667 // pointing here, at the generic instantiation callsite.
7632 if (sema.owner_func) |owner_func| {7668 if (sema.owner_func) |owner_func| {
...@@ -7637,9 +7673,7 @@ fn instantiateGenericCall(...@@ -7637,9 +7673,7 @@ fn instantiateGenericCall(
7637 return err;7673 return err;
7638 },7674 },
7639 };7675 };
7640 errdefer new_decl_arena.deinit();
76417676
7642 try new_decl.finalizeNewArena(&new_decl_arena);
7643 break :callee new_func;7677 break :callee new_func;
7644 } else gop.key_ptr.*;7678 } else gop.key_ptr.*;
7645 const callee = mod.funcPtr(callee_index);7679 const callee = mod.funcPtr(callee_index);
...@@ -7729,7 +7763,6 @@ fn instantiateGenericCall(...@@ -7729,7 +7763,6 @@ fn instantiateGenericCall(
7729fn resolveGenericInstantiationType(7763fn resolveGenericInstantiationType(
7730 sema: *Sema,7764 sema: *Sema,
7731 block: *Block,7765 block: *Block,
7732 new_decl_arena_allocator: Allocator,
7733 fn_zir: Zir,7766 fn_zir: Zir,
7734 new_decl: *Decl,7767 new_decl: *Decl,
7735 new_decl_index: Decl.Index,7768 new_decl_index: Decl.Index,
...@@ -7755,7 +7788,6 @@ fn resolveGenericInstantiationType(...@@ -7755,7 +7788,6 @@ fn resolveGenericInstantiationType(
7755 .mod = mod,7788 .mod = mod,
7756 .gpa = gpa,7789 .gpa = gpa,
7757 .arena = sema.arena,7790 .arena = sema.arena,
7758 .perm_arena = new_decl_arena_allocator,
7759 .code = fn_zir,7791 .code = fn_zir,
7760 .owner_decl = new_decl,7792 .owner_decl = new_decl,
7761 .owner_decl_index = new_decl_index,7793 .owner_decl_index = new_decl_index,
...@@ -7764,7 +7796,8 @@ fn resolveGenericInstantiationType(...@@ -7764,7 +7796,8 @@ fn resolveGenericInstantiationType(
7764 .fn_ret_ty = Type.void,7796 .fn_ret_ty = Type.void,
7765 .owner_func = null,7797 .owner_func = null,
7766 .owner_func_index = .none,7798 .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),
7768 .comptime_args_fn_inst = module_fn.zir_body_inst,7801 .comptime_args_fn_inst = module_fn.zir_body_inst,
7769 .preallocated_new_func = new_module_func.toOptional(),7802 .preallocated_new_func = new_module_func.toOptional(),
7770 .is_generic_instantiation = true,7803 .is_generic_instantiation = true,
...@@ -7931,10 +7964,6 @@ fn resolveGenericInstantiationType(...@@ -7931,10 +7964,6 @@ fn resolveGenericInstantiationType(
7931 new_decl.owns_tv = true;7964 new_decl.owns_tv = true;
7932 new_decl.analysis = .complete;7965 new_decl.analysis = .complete;
79337966
7934 log.debug("generic function '{s}' instantiated with type {}", .{
7935 new_decl.name, new_decl.ty.fmtDebug(),
7936 });
7937
7938 // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field7967 // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field
7939 // will be populated, ensuring it will have `analyzeBody` called with the ZIR7968 // will be populated, ensuring it will have `analyzeBody` called with the ZIR
7940 // parameters mapped appropriately.7969 // parameters mapped appropriately.
...@@ -8134,13 +8163,13 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -8134,13 +8163,13 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
8134 _ = block;8163 _ = block;
8135 const mod = sema.mod;8164 const mod = sema.mod;
8136 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;8165 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);
8138 // Create an error set type with only this error value, and return the value.8168 // Create an error set type with only this error value, and return the value.
8139 const kv = try sema.mod.getErrorValue(name);8169 const error_set_type = try mod.singleErrorSetTypeNts(name);
8140 const error_set_type = try mod.singleErrorSetType(kv.key);
8141 return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{8170 return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
8142 .ty = error_set_type.toIntern(),8171 .ty = error_set_type.toIntern(),
8143 .name = try mod.intern_pool.getOrPutString(sema.gpa, kv.key),8172 .name = name,
8144 } })).toValue());8173 } })).toValue());
8145}8174}
81468175
...@@ -8162,7 +8191,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -8162,7 +8191,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
8162 const err_name = mod.intern_pool.indexToKey(val.toIntern()).err.name;8191 const err_name = mod.intern_pool.indexToKey(val.toIntern()).err.name;
8163 return sema.addConstant(Type.err_int, try mod.intValue(8192 return sema.addConstant(Type.err_int, try mod.intValue(
8164 Type.err_int,8193 Type.err_int,
8165 (try mod.getErrorValue(mod.intern_pool.stringToSlice(err_name))).value,8194 try mod.getErrorValue(err_name),
8166 ));8195 ));
8167 }8196 }
81688197
...@@ -8173,8 +8202,8 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -8173,8 +8202,8 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
8173 switch (names.len) {8202 switch (names.len) {
8174 0 => return sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)),8203 0 => return sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)),
8175 1 => {8204 1 => {
8176 const name = mod.intern_pool.stringToSlice(names[0]);8205 const int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(names[0]).?);
8177 return sema.addIntUnsigned(Type.err_int, mod.global_error_set.get(name).?);8206 return sema.addIntUnsigned(Type.err_int, int);
8178 },8207 },
8179 else => {},8208 else => {},
8180 }8209 }
...@@ -8197,11 +8226,11 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -8197,11 +8226,11 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
81978226
8198 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {8227 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
8199 const int = try sema.usizeCast(block, operand_src, value.toUnsignedInt(mod));8228 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)
8201 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});8230 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
8202 return sema.addConstant(Type.anyerror, (try mod.intern(.{ .err = .{8231 return sema.addConstant(Type.anyerror, (try mod.intern(.{ .err = .{
8203 .ty = .anyerror_type,8232 .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],
8205 } })).toValue());8234 } })).toValue());
8206 }8235 }
8207 try sema.requireRuntimeBlock(block, src, operand_src);8236 try sema.requireRuntimeBlock(block, src, operand_src);
...@@ -8917,7 +8946,7 @@ fn handleExternLibName(...@@ -8917,7 +8946,7 @@ fn handleExternLibName(
8917const FuncLinkSection = union(enum) {8946const FuncLinkSection = union(enum) {
8918 generic,8947 generic,
8919 default,8948 default,
8920 explicit: []const u8,8949 explicit: InternPool.NullTerminatedString,
8921};8950};
89228951
8923fn funcCommon(8952fn funcCommon(
...@@ -9186,9 +9215,9 @@ fn funcCommon(...@@ -9186,9 +9215,9 @@ fn funcCommon(
9186 };9215 };
91879216
9188 sema.owner_decl.@"linksection" = switch (section) {9217 sema.owner_decl.@"linksection" = switch (section) {
9189 .generic => undefined,9218 .generic => .none,
9190 .default => null,9219 .default => .none,
9191 .explicit => |section_name| try sema.perm_arena.dupeZ(u8, section_name),9220 .explicit => |section_name| section_name.toOptional(),
9192 };9221 };
9193 sema.owner_decl.@"align" = alignment orelse 0;9222 sema.owner_decl.@"align" = alignment orelse 0;
9194 sema.owner_decl.@"addrspace" = address_space orelse .generic;9223 sema.owner_decl.@"addrspace" = address_space orelse .generic;
...@@ -9572,11 +9601,12 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -9572,11 +9601,12 @@ fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
9572 const tracy = trace(@src());9601 const tracy = trace(@src());
9573 defer tracy.end();9602 defer tracy.end();
95749603
9604 const mod = sema.mod;
9575 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;9605 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
9576 const src = inst_data.src();9606 const src = inst_data.src();
9577 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };9607 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
9578 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;9608 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));
9580 const object = try sema.resolveInst(extra.lhs);9610 const object = try sema.resolveInst(extra.lhs);
9581 return sema.fieldVal(block, src, object, field_name, field_name_src);9611 return sema.fieldVal(block, src, object, field_name, field_name_src);
9582}9612}
...@@ -9585,11 +9615,12 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index, initializing: b...@@ -9585,11 +9615,12 @@ fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index, initializing: b
9585 const tracy = trace(@src());9615 const tracy = trace(@src());
9586 defer tracy.end();9616 defer tracy.end();
95879617
9618 const mod = sema.mod;
9588 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;9619 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
9589 const src = inst_data.src();9620 const src = inst_data.src();
9590 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };9621 const field_name_src: LazySrcLoc = .{ .node_offset_field_name = inst_data.src_node };
9591 const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data;9622 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));
9593 const object_ptr = try sema.resolveInst(extra.lhs);9624 const object_ptr = try sema.resolveInst(extra.lhs);
9594 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, initializing);9625 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, initializing);
9595}9626}
...@@ -9603,7 +9634,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -9603,7 +9634,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
9603 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };9634 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
9604 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;9635 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
9605 const object = try sema.resolveInst(extra.lhs);9636 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");
9607 return sema.fieldVal(block, src, object, field_name, field_name_src);9638 return sema.fieldVal(block, src, object, field_name, field_name_src);
9608}9639}
96099640
...@@ -9616,7 +9647,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -9616,7 +9647,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
9616 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };9647 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
9617 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;9648 const extra = sema.code.extraData(Zir.Inst.FieldNamed, inst_data.payload_index).data;
9618 const object_ptr = try sema.resolveInst(extra.lhs);9649 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");
9620 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);9651 return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src, false);
9621}9652}
96229653
...@@ -10434,6 +10465,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10434,6 +10465,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1043410465
10435 const mod = sema.mod;10466 const mod = sema.mod;
10436 const gpa = sema.gpa;10467 const gpa = sema.gpa;
10468 const ip = &mod.intern_pool;
10437 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;10469 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
10438 const src = inst_data.src();10470 const src = inst_data.src();
10439 const src_node_offset = inst_data.src_node;10471 const src_node_offset = inst_data.src_node;
...@@ -10605,7 +10637,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10605,7 +10637,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10605 i,10637 i,
10606 msg,10638 msg,
10607 "unhandled enumeration value: '{s}'",10639 "unhandled enumeration value: '{s}'",
10608 .{field_name},10640 .{ip.stringToSlice(field_name)},
10609 );10641 );
10610 }10642 }
10611 try mod.errNoteNonLazy(10643 try mod.errNoteNonLazy(
...@@ -10689,7 +10721,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10689,7 +10721,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10689 errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);10721 errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);
1069010722
10691 for (operand_ty.errorSetNames(mod)) |error_name_ip| {10723 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);
10693 if (!seen_errors.contains(error_name) and special_prong != .@"else") {10725 if (!seen_errors.contains(error_name) and special_prong != .@"else") {
10694 const msg = maybe_msg orelse blk: {10726 const msg = maybe_msg orelse blk: {
10695 maybe_msg = try sema.errMsg(10727 maybe_msg = try sema.errMsg(
...@@ -10758,7 +10790,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -10758,7 +10790,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
10758 var names: Module.Fn.InferredErrorSet.NameMap = .{};10790 var names: Module.Fn.InferredErrorSet.NameMap = .{};
10759 try names.ensureUnusedCapacity(sema.arena, error_names.len);10791 try names.ensureUnusedCapacity(sema.arena, error_names.len);
10760 for (error_names) |error_name_ip| {10792 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);
10762 if (seen_errors.contains(error_name)) continue;10794 if (seen_errors.contains(error_name)) continue;
1076310795
10764 names.putAssumeCapacityNoClobber(error_name_ip, {});10796 names.putAssumeCapacityNoClobber(error_name_ip, {});
...@@ -12062,7 +12094,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12062,7 +12094,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12062 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };12094 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
12063 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };12095 const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
12064 const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs);12096 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");
12066 const ty = try sema.resolveTypeFields(unresolved_ty);12098 const ty = try sema.resolveTypeFields(unresolved_ty);
12067 const ip = &mod.intern_pool;12099 const ip = &mod.intern_pool;
1206812100
...@@ -12070,19 +12102,17 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12070,19 +12102,17 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12070 switch (ip.indexToKey(ty.toIntern())) {12102 switch (ip.indexToKey(ty.toIntern())) {
12071 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {12103 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
12072 .Slice => {12104 .Slice => {
12073 if (mem.eql(u8, field_name, "ptr")) break :hf true;12105 if (ip.stringEqlSlice(field_name, "ptr")) break :hf true;
12074 if (mem.eql(u8, field_name, "len")) break :hf true;12106 if (ip.stringEqlSlice(field_name, "len")) break :hf true;
12075 break :hf false;12107 break :hf false;
12076 },12108 },
12077 else => {},12109 else => {},
12078 },12110 },
12079 .anon_struct_type => |anon_struct| {12111 .anon_struct_type => |anon_struct| {
12080 if (anon_struct.names.len != 0) {12112 if (anon_struct.names.len != 0) {
12081 // If the string is not interned, then the field certainly is not present.12113 break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names, field_name) != null;
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;
12084 } else {12114 } 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;
12086 break :hf field_index < ty.structFieldCount(mod);12116 break :hf field_index < ty.structFieldCount(mod);
12087 }12117 }
12088 },12118 },
...@@ -12097,11 +12127,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -12097,11 +12127,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
12097 break :hf union_obj.fields.contains(field_name);12127 break :hf union_obj.fields.contains(field_name);
12098 },12128 },
12099 .enum_type => |enum_type| {12129 .enum_type => |enum_type| {
12100 // If the string is not interned, then the field certainly is not present.12130 break :hf enum_type.nameIndex(ip, field_name) != null;
12101 const name_interned = ip.getString(field_name).unwrap() orelse break :hf false;
12102 break :hf enum_type.nameIndex(ip, name_interned) != null;
12103 },12131 },
12104 .array_type => break :hf mem.eql(u8, field_name, "len"),12132 .array_type => break :hf ip.stringEqlSlice(field_name, "len"),
12105 else => {},12133 else => {},
12106 }12134 }
12107 return sema.fail(block, ty_src, "type '{}' does not support '@hasField'", .{12135 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...@@ -12123,7 +12151,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
12123 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };12151 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
12124 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };12152 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
12125 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);12153 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
12128 try sema.checkNamespaceType(block, lhs_src, container_type);12156 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...@@ -12218,14 +12246,12 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
12218fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {12246fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
12219 const mod = sema.mod;12247 const mod = sema.mod;
12220 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;12248 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
12221 const err_name = inst_data.get(sema.code);12249 const name = try mod.intern_pool.getOrPutString(sema.gpa, inst_data.get(sema.code));
1222212250 _ = try mod.getErrorValue(name);
12223 // Return the error code from the function.12251 const error_set_type = try mod.singleErrorSetTypeNts(name);
12224 const kv = try mod.getErrorValue(err_name);
12225 const error_set_type = try mod.singleErrorSetType(kv.key);
12226 return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{12252 return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
12227 .ty = error_set_type.toIntern(),12253 .ty = error_set_type.toIntern(),
12228 .name = mod.intern_pool.getString(kv.key).unwrap().?,12254 .name = name,
12229 } })).toValue());12255 } })).toValue());
12230}12256}
1223112257
...@@ -15730,12 +15756,7 @@ fn zirThis(...@@ -15730,12 +15756,7 @@ fn zirThis(
15730 return sema.analyzeDeclVal(block, src, this_decl_index);15756 return sema.analyzeDeclVal(block, src, this_decl_index);
15731}15757}
1573215758
15733fn zirClosureCapture(15759fn zirClosureCapture(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
15734 sema: *Sema,
15735 block: *Block,
15736 inst: Zir.Inst.Index,
15737) CompileError!void {
15738 // TODO: Compile error when closed over values are modified
15739 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;15760 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
15740 // Closures are not necessarily constant values. For example, the15761 // Closures are not necessarily constant values. For example, the
15741 // code might do something like this:15762 // code might do something like this:
...@@ -15754,13 +15775,8 @@ fn zirClosureCapture(...@@ -15754,13 +15775,8 @@ fn zirClosureCapture(
15754 try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, capture);15775 try block.wip_capture_scope.captures.putNoClobber(sema.gpa, inst, capture);
15755}15776}
1575615777
15757fn zirClosureGet(15778fn zirClosureGet(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15758 sema: *Sema,
15759 block: *Block,
15760 inst: Zir.Inst.Index,
15761) CompileError!Air.Inst.Ref {
15762 const mod = sema.mod;15779 const mod = sema.mod;
15763 // TODO CLOSURE: Test this with inline functions
15764 const inst_data = sema.code.instructions.items(.data)[inst].inst_node;15780 const inst_data = sema.code.instructions.items(.data)[inst].inst_node;
15765 var scope: *CaptureScope = mod.declPtr(block.src_decl).src_scope.?;15781 var scope: *CaptureScope = mod.declPtr(block.src_decl).src_scope.?;
15766 // Note: The target closure must be in this scope list.15782 // Note: The target closure must be in this scope list.
...@@ -15896,7 +15912,7 @@ fn zirBuiltinSrc(...@@ -15896,7 +15912,7 @@ fn zirBuiltinSrc(
15896 const func_name_val = blk: {15912 const func_name_val = blk: {
15897 var anon_decl = try block.startAnonDecl();15913 var anon_decl = try block.startAnonDecl();
15898 defer anon_decl.deinit();15914 defer anon_decl.deinit();
15899 const name = mem.span(fn_owner_decl.name);15915 const name = mod.intern_pool.stringToSlice(fn_owner_decl.name);
15900 const new_decl_ty = try mod.arrayType(.{15916 const new_decl_ty = try mod.arrayType(.{
15901 .len = name.len,15917 .len = name.len,
15902 .child = .u8_type,15918 .child = .u8_type,
...@@ -15965,6 +15981,7 @@ fn zirBuiltinSrc(...@@ -15965,6 +15981,7 @@ fn zirBuiltinSrc(
15965fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {15981fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
15966 const mod = sema.mod;15982 const mod = sema.mod;
15967 const gpa = sema.gpa;15983 const gpa = sema.gpa;
15984 const ip = &mod.intern_pool;
15968 const inst_data = sema.code.instructions.items(.data)[inst].un_node;15985 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
15969 const src = inst_data.src();15986 const src = inst_data.src();
15970 const ty = try sema.resolveType(block, src, inst_data.operand);15987 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...@@ -15995,7 +16012,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15995 block,16012 block,
15996 src,16013 src,
15997 type_info_ty.getNamespaceIndex(mod).unwrap().?,16014 type_info_ty.getNamespaceIndex(mod).unwrap().?,
15998 "Fn",16015 try ip.getOrPutString(gpa, "Fn"),
15999 )).?;16016 )).?;
16000 try mod.declareDeclDependency(sema.owner_decl_index, fn_info_decl_index);16017 try mod.declareDeclDependency(sema.owner_decl_index, fn_info_decl_index);
16001 try sema.ensureDeclAnalyzed(fn_info_decl_index);16018 try sema.ensureDeclAnalyzed(fn_info_decl_index);
...@@ -16006,7 +16023,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16006,7 +16023,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16006 block,16023 block,
16007 src,16024 src,
16008 fn_info_ty.getNamespaceIndex(mod).unwrap().?,16025 fn_info_ty.getNamespaceIndex(mod).unwrap().?,
16009 "Param",16026 try ip.getOrPutString(gpa, "Param"),
16010 )).?;16027 )).?;
16011 try mod.declareDeclDependency(sema.owner_decl_index, param_info_decl_index);16028 try mod.declareDeclDependency(sema.owner_decl_index, param_info_decl_index);
16012 try sema.ensureDeclAnalyzed(param_info_decl_index);16029 try sema.ensureDeclAnalyzed(param_info_decl_index);
...@@ -16018,8 +16035,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16018,8 +16035,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16018 const info = mod.typeToFunc(ty).?;16035 const info = mod.typeToFunc(ty).?;
16019 const param_ty = info.param_types[i];16036 const param_ty = info.param_types[i];
16020 const is_generic = param_ty == .generic_poison_type;16037 const is_generic = param_ty == .generic_poison_type;
16021 const param_ty_val = try mod.intern_pool.get(gpa, .{ .opt = .{16038 const param_ty_val = try ip.get(gpa, .{ .opt = .{
16022 .ty = try mod.intern_pool.get(gpa, .{ .opt_type = .type_type }),16039 .ty = try ip.get(gpa, .{ .opt_type = .type_type }),
16023 .val = if (is_generic) .none else param_ty,16040 .val = if (is_generic) .none else param_ty,
16024 } });16041 } });
1602516042
...@@ -16070,7 +16087,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16070,7 +16087,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1607016087
16071 const info = mod.typeToFunc(ty).?;16088 const info = mod.typeToFunc(ty).?;
16072 const ret_ty_opt = try mod.intern(.{ .opt = .{16089 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 }),
16074 .val = if (info.return_type == .generic_poison_type) .none else info.return_type,16091 .val = if (info.return_type == .generic_poison_type) .none else info.return_type,
16075 } });16092 } });
1607616093
...@@ -16104,7 +16121,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16104,7 +16121,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16104 block,16121 block,
16105 src,16122 src,
16106 type_info_ty.getNamespaceIndex(mod).unwrap().?,16123 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16107 "Int",16124 try ip.getOrPutString(gpa, "Int"),
16108 )).?;16125 )).?;
16109 try mod.declareDeclDependency(sema.owner_decl_index, int_info_decl_index);16126 try mod.declareDeclDependency(sema.owner_decl_index, int_info_decl_index);
16110 try sema.ensureDeclAnalyzed(int_info_decl_index);16127 try sema.ensureDeclAnalyzed(int_info_decl_index);
...@@ -16133,7 +16150,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16133,7 +16150,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16133 block,16150 block,
16134 src,16151 src,
16135 type_info_ty.getNamespaceIndex(mod).unwrap().?,16152 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16136 "Float",16153 try ip.getOrPutString(gpa, "Float"),
16137 )).?;16154 )).?;
16138 try mod.declareDeclDependency(sema.owner_decl_index, float_info_decl_index);16155 try mod.declareDeclDependency(sema.owner_decl_index, float_info_decl_index);
16139 try sema.ensureDeclAnalyzed(float_info_decl_index);16156 try sema.ensureDeclAnalyzed(float_info_decl_index);
...@@ -16166,7 +16183,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16166,7 +16183,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16166 block,16183 block,
16167 src,16184 src,
16168 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,16185 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,
16169 "Pointer",16186 try ip.getOrPutString(gpa, "Pointer"),
16170 )).?;16187 )).?;
16171 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);16188 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
16172 try sema.ensureDeclAnalyzed(decl_index);16189 try sema.ensureDeclAnalyzed(decl_index);
...@@ -16178,7 +16195,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16178,7 +16195,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16178 block,16195 block,
16179 src,16196 src,
16180 pointer_ty.getNamespaceIndex(mod).unwrap().?,16197 pointer_ty.getNamespaceIndex(mod).unwrap().?,
16181 "Size",16198 try ip.getOrPutString(gpa, "Size"),
16182 )).?;16199 )).?;
16183 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);16200 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
16184 try sema.ensureDeclAnalyzed(decl_index);16201 try sema.ensureDeclAnalyzed(decl_index);
...@@ -16219,7 +16236,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16219,7 +16236,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16219 block,16236 block,
16220 src,16237 src,
16221 type_info_ty.getNamespaceIndex(mod).unwrap().?,16238 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16222 "Array",16239 try ip.getOrPutString(gpa, "Array"),
16223 )).?;16240 )).?;
16224 try mod.declareDeclDependency(sema.owner_decl_index, array_field_ty_decl_index);16241 try mod.declareDeclDependency(sema.owner_decl_index, array_field_ty_decl_index);
16225 try sema.ensureDeclAnalyzed(array_field_ty_decl_index);16242 try sema.ensureDeclAnalyzed(array_field_ty_decl_index);
...@@ -16251,7 +16268,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16251,7 +16268,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16251 block,16268 block,
16252 src,16269 src,
16253 type_info_ty.getNamespaceIndex(mod).unwrap().?,16270 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16254 "Vector",16271 try ip.getOrPutString(gpa, "Vector"),
16255 )).?;16272 )).?;
16256 try mod.declareDeclDependency(sema.owner_decl_index, vector_field_ty_decl_index);16273 try mod.declareDeclDependency(sema.owner_decl_index, vector_field_ty_decl_index);
16257 try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);16274 try sema.ensureDeclAnalyzed(vector_field_ty_decl_index);
...@@ -16281,7 +16298,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16281,7 +16298,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16281 block,16298 block,
16282 src,16299 src,
16283 type_info_ty.getNamespaceIndex(mod).unwrap().?,16300 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16284 "Optional",16301 try ip.getOrPutString(gpa, "Optional"),
16285 )).?;16302 )).?;
16286 try mod.declareDeclDependency(sema.owner_decl_index, optional_field_ty_decl_index);16303 try mod.declareDeclDependency(sema.owner_decl_index, optional_field_ty_decl_index);
16287 try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);16304 try sema.ensureDeclAnalyzed(optional_field_ty_decl_index);
...@@ -16312,7 +16329,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16312,7 +16329,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16312 block,16329 block,
16313 src,16330 src,
16314 type_info_ty.getNamespaceIndex(mod).unwrap().?,16331 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16315 "Error",16332 try ip.getOrPutString(gpa, "Error"),
16316 )).?;16333 )).?;
16317 try mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);16334 try mod.declareDeclDependency(sema.owner_decl_index, set_field_ty_decl_index);
16318 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);16335 try sema.ensureDeclAnalyzed(set_field_ty_decl_index);
...@@ -16332,7 +16349,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16332,7 +16349,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16332 const names = ty.errorSetNames(mod);16349 const names = ty.errorSetNames(mod);
16333 const vals = try sema.arena.alloc(InternPool.Index, names.len);16350 const vals = try sema.arena.alloc(InternPool.Index, names.len);
16334 for (vals, names) |*field_val, name_ip| {16351 for (vals, names) |*field_val, name_ip| {
16335 const name = mod.intern_pool.stringToSlice(name_ip);16352 const name = ip.stringToSlice(name_ip);
16336 const name_val = v: {16353 const name_val = v: {
16337 var anon_decl = try block.startAnonDecl();16354 var anon_decl = try block.startAnonDecl();
16338 defer anon_decl.deinit();16355 defer anon_decl.deinit();
...@@ -16415,7 +16432,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16415,7 +16432,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16415 block,16432 block,
16416 src,16433 src,
16417 type_info_ty.getNamespaceIndex(mod).unwrap().?,16434 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16418 "ErrorUnion",16435 try ip.getOrPutString(gpa, "ErrorUnion"),
16419 )).?;16436 )).?;
16420 try mod.declareDeclDependency(sema.owner_decl_index, error_union_field_ty_decl_index);16437 try mod.declareDeclDependency(sema.owner_decl_index, error_union_field_ty_decl_index);
16421 try sema.ensureDeclAnalyzed(error_union_field_ty_decl_index);16438 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...@@ -16440,7 +16457,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16440 },16457 },
16441 .Enum => {16458 .Enum => {
16442 // TODO: look into memoizing this result.16459 // 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
16445 const is_exhaustive = Value.makeBool(enum_type.tag_mode != .nonexhaustive);16462 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...@@ -16452,7 +16469,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16452 block,16469 block,
16453 src,16470 src,
16454 type_info_ty.getNamespaceIndex(mod).unwrap().?,16471 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16455 "EnumField",16472 try ip.getOrPutString(gpa, "EnumField"),
16456 )).?;16473 )).?;
16457 try mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);16474 try mod.declareDeclDependency(sema.owner_decl_index, enum_field_ty_decl_index);
16458 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);16475 try sema.ensureDeclAnalyzed(enum_field_ty_decl_index);
...@@ -16462,8 +16479,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16462,8 +16479,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1646216479
16463 const enum_field_vals = try sema.arena.alloc(InternPool.Index, enum_type.names.len);16480 const enum_field_vals = try sema.arena.alloc(InternPool.Index, enum_type.names.len);
16464 for (enum_field_vals, 0..) |*field_val, i| {16481 for (enum_field_vals, 0..) |*field_val, i| {
16465 const name_ip = mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names[i];16482 const name_ip = ip.indexToKey(ty.toIntern()).enum_type.names[i];
16466 const name = mod.intern_pool.stringToSlice(name_ip);16483 const name = ip.stringToSlice(name_ip);
16467 const name_val = v: {16484 const name_val = v: {
16468 var anon_decl = try block.startAnonDecl();16485 var anon_decl = try block.startAnonDecl();
16469 defer anon_decl.deinit();16486 defer anon_decl.deinit();
...@@ -16532,7 +16549,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16532,7 +16549,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16532 block,16549 block,
16533 src,16550 src,
16534 type_info_ty.getNamespaceIndex(mod).unwrap().?,16551 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16535 "Enum",16552 try ip.getOrPutString(gpa, "Enum"),
16536 )).?;16553 )).?;
16537 try mod.declareDeclDependency(sema.owner_decl_index, type_enum_ty_decl_index);16554 try mod.declareDeclDependency(sema.owner_decl_index, type_enum_ty_decl_index);
16538 try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);16555 try sema.ensureDeclAnalyzed(type_enum_ty_decl_index);
...@@ -16570,7 +16587,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16570,7 +16587,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16570 block,16587 block,
16571 src,16588 src,
16572 type_info_ty.getNamespaceIndex(mod).unwrap().?,16589 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16573 "Union",16590 try ip.getOrPutString(gpa, "Union"),
16574 )).?;16591 )).?;
16575 try mod.declareDeclDependency(sema.owner_decl_index, type_union_ty_decl_index);16592 try mod.declareDeclDependency(sema.owner_decl_index, type_union_ty_decl_index);
16576 try sema.ensureDeclAnalyzed(type_union_ty_decl_index);16593 try sema.ensureDeclAnalyzed(type_union_ty_decl_index);
...@@ -16583,7 +16600,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16583,7 +16600,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16583 block,16600 block,
16584 src,16601 src,
16585 type_info_ty.getNamespaceIndex(mod).unwrap().?,16602 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16586 "UnionField",16603 try ip.getOrPutString(gpa, "UnionField"),
16587 )).?;16604 )).?;
16588 try mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);16605 try mod.declareDeclDependency(sema.owner_decl_index, union_field_ty_decl_index);
16589 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);16606 try sema.ensureDeclAnalyzed(union_field_ty_decl_index);
...@@ -16601,7 +16618,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16601,7 +16618,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1660116618
16602 for (union_field_vals, 0..) |*field_val, i| {16619 for (union_field_vals, 0..) |*field_val, i| {
16603 const field = union_fields.values()[i];16620 const field = union_fields.values()[i];
16604 const name = union_fields.keys()[i];16621 const name = ip.stringToSlice(union_fields.keys()[i]);
16605 const name_val = v: {16622 const name_val = v: {
16606 var anon_decl = try block.startAnonDecl();16623 var anon_decl = try block.startAnonDecl();
16607 defer anon_decl.deinit();16624 defer anon_decl.deinit();
...@@ -16682,7 +16699,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16682,7 +16699,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16682 block,16699 block,
16683 src,16700 src,
16684 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,16701 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,
16685 "ContainerLayout",16702 try ip.getOrPutString(gpa, "ContainerLayout"),
16686 )).?;16703 )).?;
16687 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);16704 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
16688 try sema.ensureDeclAnalyzed(decl_index);16705 try sema.ensureDeclAnalyzed(decl_index);
...@@ -16721,7 +16738,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16721,7 +16738,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16721 block,16738 block,
16722 src,16739 src,
16723 type_info_ty.getNamespaceIndex(mod).unwrap().?,16740 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16724 "Struct",16741 try ip.getOrPutString(gpa, "Struct"),
16725 )).?;16742 )).?;
16726 try mod.declareDeclDependency(sema.owner_decl_index, type_struct_ty_decl_index);16743 try mod.declareDeclDependency(sema.owner_decl_index, type_struct_ty_decl_index);
16727 try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);16744 try sema.ensureDeclAnalyzed(type_struct_ty_decl_index);
...@@ -16734,7 +16751,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16734,7 +16751,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16734 block,16751 block,
16735 src,16752 src,
16736 type_info_ty.getNamespaceIndex(mod).unwrap().?,16753 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16737 "StructField",16754 try ip.getOrPutString(gpa, "StructField"),
16738 )).?;16755 )).?;
16739 try mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);16756 try mod.declareDeclDependency(sema.owner_decl_index, struct_field_ty_decl_index);
16740 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);16757 try sema.ensureDeclAnalyzed(struct_field_ty_decl_index);
...@@ -16749,11 +16766,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16749,11 +16766,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16749 var struct_field_vals: []InternPool.Index = &.{};16766 var struct_field_vals: []InternPool.Index = &.{};
16750 defer gpa.free(struct_field_vals);16767 defer gpa.free(struct_field_vals);
16751 fv: {16768 fv: {
16752 const struct_type = switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {16769 const struct_type = switch (ip.indexToKey(struct_ty.toIntern())) {
16753 .anon_struct_type => |tuple| {16770 .anon_struct_type => |tuple| {
16754 struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);16771 struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);
16755 for (struct_field_vals, 0..) |*struct_field_val, i| {16772 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;
16757 const field_ty = anon_struct_type.types[i];16774 const field_ty = anon_struct_type.types[i];
16758 const field_val = anon_struct_type.values[i];16775 const field_val = anon_struct_type.values[i];
16759 const name_val = v: {16776 const name_val = v: {
...@@ -16761,7 +16778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16761,7 +16778,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16761 defer anon_decl.deinit();16778 defer anon_decl.deinit();
16762 const bytes = if (tuple.names.len != 0)16779 const bytes = if (tuple.names.len != 0)
16763 // https://github.com/ziglang/zig/issues/1570916780 // 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]))
16765 else16782 else
16766 try std.fmt.allocPrint(sema.arena, "{d}", .{i});16783 try std.fmt.allocPrint(sema.arena, "{d}", .{i});
16767 const new_decl_ty = try mod.arrayType(.{16784 const new_decl_ty = try mod.arrayType(.{
...@@ -16815,7 +16832,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16815,7 +16832,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16815 struct_field_vals,16832 struct_field_vals,
16816 struct_obj.fields.keys(),16833 struct_obj.fields.keys(),
16817 struct_obj.fields.values(),16834 struct_obj.fields.values(),
16818 ) |*field_val, name, field| {16835 ) |*field_val, name_nts, field| {
16836 const name = ip.stringToSlice(name_nts);
16819 const name_val = v: {16837 const name_val = v: {
16820 var anon_decl = try block.startAnonDecl();16838 var anon_decl = try block.startAnonDecl();
16821 defer anon_decl.deinit();16839 defer anon_decl.deinit();
...@@ -16838,10 +16856,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16838,10 +16856,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16838 } });16856 } });
16839 };16857 };
1684016858
16841 const opt_default_val = if (field.default_val.toIntern() == .unreachable_value)16859 const opt_default_val = if (field.default_val == .none)
16842 null16860 null
16843 else16861 else
16844 field.default_val;16862 field.default_val.toValue();
16845 const default_val_ptr = try sema.optRefValue(block, field.ty, opt_default_val);16863 const default_val_ptr = try sema.optRefValue(block, field.ty, opt_default_val);
16846 const alignment = field.alignment(mod, layout);16864 const alignment = field.alignment(mod, layout);
1684716865
...@@ -16908,7 +16926,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16908,7 +16926,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16908 block,16926 block,
16909 src,16927 src,
16910 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,16928 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod).unwrap().?,
16911 "ContainerLayout",16929 try ip.getOrPutString(gpa, "ContainerLayout"),
16912 )).?;16930 )).?;
16913 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);16931 try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
16914 try sema.ensureDeclAnalyzed(decl_index);16932 try sema.ensureDeclAnalyzed(decl_index);
...@@ -16945,7 +16963,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -16945,7 +16963,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
16945 block,16963 block,
16946 src,16964 src,
16947 type_info_ty.getNamespaceIndex(mod).unwrap().?,16965 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16948 "Opaque",16966 try ip.getOrPutString(gpa, "Opaque"),
16949 )).?;16967 )).?;
16950 try mod.declareDeclDependency(sema.owner_decl_index, type_opaque_ty_decl_index);16968 try mod.declareDeclDependency(sema.owner_decl_index, type_opaque_ty_decl_index);
16951 try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);16969 try sema.ensureDeclAnalyzed(type_opaque_ty_decl_index);
...@@ -16982,6 +17000,8 @@ fn typeInfoDecls(...@@ -16982,6 +17000,8 @@ fn typeInfoDecls(
16982 opt_namespace: Module.Namespace.OptionalIndex,17000 opt_namespace: Module.Namespace.OptionalIndex,
16983) CompileError!InternPool.Index {17001) CompileError!InternPool.Index {
16984 const mod = sema.mod;17002 const mod = sema.mod;
17003 const gpa = sema.gpa;
17004
16985 var decls_anon_decl = try block.startAnonDecl();17005 var decls_anon_decl = try block.startAnonDecl();
16986 defer decls_anon_decl.deinit();17006 defer decls_anon_decl.deinit();
1698717007
...@@ -16990,7 +17010,7 @@ fn typeInfoDecls(...@@ -16990,7 +17010,7 @@ fn typeInfoDecls(
16990 block,17010 block,
16991 src,17011 src,
16992 type_info_ty.getNamespaceIndex(mod).unwrap().?,17012 type_info_ty.getNamespaceIndex(mod).unwrap().?,
16993 "Declaration",17013 try mod.intern_pool.getOrPutString(gpa, "Declaration"),
16994 )).?;17014 )).?;
16995 try mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);17015 try mod.declareDeclDependency(sema.owner_decl_index, declaration_ty_decl_index);
16996 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);17016 try sema.ensureDeclAnalyzed(declaration_ty_decl_index);
...@@ -16999,10 +17019,10 @@ fn typeInfoDecls(...@@ -16999,10 +17019,10 @@ fn typeInfoDecls(
16999 };17019 };
17000 try sema.queueFullTypeResolution(declaration_ty);17020 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);
17003 defer decl_vals.deinit();17023 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);
17006 defer seen_namespaces.deinit();17026 defer seen_namespaces.deinit();
1700717027
17008 if (opt_namespace.unwrap()) |namespace_index| {17028 if (opt_namespace.unwrap()) |namespace_index| {
...@@ -17061,7 +17081,7 @@ fn typeInfoNamespaceDecls(...@@ -17061,7 +17081,7 @@ fn typeInfoNamespaceDecls(
17061 const name_val = v: {17081 const name_val = v: {
17062 var anon_decl = try block.startAnonDecl();17082 var anon_decl = try block.startAnonDecl();
17063 defer anon_decl.deinit();17083 defer anon_decl.deinit();
17064 const name = mem.span(decl.name);17084 const name = mod.intern_pool.stringToSlice(decl.name);
17065 const new_decl_ty = try mod.arrayType(.{17085 const new_decl_ty = try mod.arrayType(.{
17066 .len = name.len,17086 .len = name.len,
17067 .child = .u8_type,17087 .child = .u8_type,
...@@ -17696,15 +17716,14 @@ fn zirRetErrValue(...@@ -17696,15 +17716,14 @@ fn zirRetErrValue(
17696) CompileError!Zir.Inst.Index {17716) CompileError!Zir.Inst.Index {
17697 const mod = sema.mod;17717 const mod = sema.mod;
17698 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;17718 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);
17700 const src = inst_data.src();17721 const src = inst_data.src();
17701
17702 // Return the error code from the function.17722 // Return the error code from the function.
17703 const kv = try mod.getErrorValue(err_name);17723 const error_set_type = try mod.singleErrorSetTypeNts(err_name);
17704 const error_set_type = try mod.singleErrorSetType(err_name);
17705 const result_inst = try sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{17724 const result_inst = try sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
17706 .ty = error_set_type.toIntern(),17725 .ty = error_set_type.toIntern(),
17707 .name = try mod.intern_pool.getOrPutString(sema.gpa, kv.key),17726 .name = err_name,
17708 } })).toValue());17727 } })).toValue());
17709 return sema.analyzeRet(block, result_inst, src);17728 return sema.analyzeRet(block, result_inst, src);
17710}17729}
...@@ -18177,7 +18196,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -18177,7 +18196,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
18177 const init_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };18196 const init_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
18178 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;18197 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
18179 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);18198 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");
18181 const init = try sema.resolveInst(extra.init);18200 const init = try sema.resolveInst(extra.init);
18182 return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src);18201 return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src);
18183}18202}
...@@ -18189,7 +18208,7 @@ fn unionInit(...@@ -18189,7 +18208,7 @@ fn unionInit(
18189 init_src: LazySrcLoc,18208 init_src: LazySrcLoc,
18190 union_ty: Type,18209 union_ty: Type,
18191 union_ty_src: LazySrcLoc,18210 union_ty_src: LazySrcLoc,
18192 field_name: []const u8,18211 field_name: InternPool.NullTerminatedString,
18193 field_src: LazySrcLoc,18212 field_src: LazySrcLoc,
18194) CompileError!Air.Inst.Ref {18213) CompileError!Air.Inst.Ref {
18195 const mod = sema.mod;18214 const mod = sema.mod;
...@@ -18257,7 +18276,7 @@ fn zirStructInit(...@@ -18257,7 +18276,7 @@ fn zirStructInit(
18257 const field_type_data = zir_datas[item.data.field_type].pl_node;18276 const field_type_data = zir_datas[item.data.field_type].pl_node;
18258 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };18277 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };
18259 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;18278 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));
18261 const field_index = if (resolved_ty.isTuple(mod))18280 const field_index = if (resolved_ty.isTuple(mod))
18262 try sema.tupleFieldIndex(block, resolved_ty, field_name, field_src)18281 try sema.tupleFieldIndex(block, resolved_ty, field_name, field_src)
18263 else18282 else
...@@ -18298,7 +18317,7 @@ fn zirStructInit(...@@ -18298,7 +18317,7 @@ fn zirStructInit(
18298 const field_type_data = zir_datas[item.data.field_type].pl_node;18317 const field_type_data = zir_datas[item.data.field_type].pl_node;
18299 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };18318 const field_src: LazySrcLoc = .{ .node_offset_initializer = field_type_data.src_node };
18300 const field_type_extra = sema.code.extraData(Zir.Inst.FieldType, field_type_data.payload_index).data;18319 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));
18302 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);18321 const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src);
18303 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);18322 const tag_ty = resolved_ty.unionTagTypeHypothetical(mod);
18304 const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);18323 const enum_field_index = @intCast(u32, tag_ty.enumFieldIndex(field_name, mod).?);
...@@ -18347,12 +18366,12 @@ fn finishStructInit(...@@ -18347,12 +18366,12 @@ fn finishStructInit(
18347 is_ref: bool,18366 is_ref: bool,
18348) CompileError!Air.Inst.Ref {18367) CompileError!Air.Inst.Ref {
18349 const mod = sema.mod;18368 const mod = sema.mod;
18350 const gpa = sema.gpa;18369 const ip = &mod.intern_pool;
1835118370
18352 var root_msg: ?*Module.ErrorMsg = null;18371 var root_msg: ?*Module.ErrorMsg = null;
18353 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);18372 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())) {
18356 .anon_struct_type => |anon_struct| {18375 .anon_struct_type => |anon_struct| {
18357 for (anon_struct.types, anon_struct.values, 0..) |field_ty, default_val, i| {18376 for (anon_struct.types, anon_struct.values, 0..) |field_ty, default_val, i| {
18358 if (field_inits[i] != .none) continue;18377 if (field_inits[i] != .none) continue;
...@@ -18366,9 +18385,9 @@ fn finishStructInit(...@@ -18366,9 +18385,9 @@ fn finishStructInit(
18366 root_msg = try sema.errMsg(block, init_src, template, .{i});18385 root_msg = try sema.errMsg(block, init_src, template, .{i});
18367 }18386 }
18368 } else {18387 } else {
18369 const field_name = mod.intern_pool.stringToSlice(anon_struct.names[i]);18388 const field_name = anon_struct.names[i];
18370 const template = "missing struct field: {s}";18389 const template = "missing struct field: {s}";
18371 const args = .{field_name};18390 const args = .{ip.stringToSlice(field_name)};
18372 if (root_msg) |msg| {18391 if (root_msg) |msg| {
18373 try sema.errNote(block, init_src, msg, template, args);18392 try sema.errNote(block, init_src, msg, template, args);
18374 } else {18393 } else {
...@@ -18385,17 +18404,17 @@ fn finishStructInit(...@@ -18385,17 +18404,17 @@ fn finishStructInit(
18385 for (struct_obj.fields.values(), 0..) |field, i| {18404 for (struct_obj.fields.values(), 0..) |field, i| {
18386 if (field_inits[i] != .none) continue;18405 if (field_inits[i] != .none) continue;
1838718406
18388 if (field.default_val.toIntern() == .unreachable_value) {18407 if (field.default_val == .none) {
18389 const field_name = struct_obj.fields.keys()[i];18408 const field_name = struct_obj.fields.keys()[i];
18390 const template = "missing struct field: {s}";18409 const template = "missing struct field: {s}";
18391 const args = .{field_name};18410 const args = .{ip.stringToSlice(field_name)};
18392 if (root_msg) |msg| {18411 if (root_msg) |msg| {
18393 try sema.errNote(block, init_src, msg, template, args);18412 try sema.errNote(block, init_src, msg, template, args);
18394 } else {18413 } else {
18395 root_msg = try sema.errMsg(block, init_src, template, args);18414 root_msg = try sema.errMsg(block, init_src, template, args);
18396 }18415 }
18397 } else {18416 } 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());
18399 }18418 }
18400 }18419 }
18401 },18420 },
...@@ -18404,10 +18423,9 @@ fn finishStructInit(...@@ -18404,10 +18423,9 @@ fn finishStructInit(
1840418423
18405 if (root_msg) |msg| {18424 if (root_msg) |msg| {
18406 if (mod.typeToStruct(struct_ty)) |struct_obj| {18425 if (mod.typeToStruct(struct_ty)) |struct_obj| {
18407 const fqn = try struct_obj.getFullyQualifiedName(sema.mod);18426 const fqn = ip.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
18408 defer gpa.free(fqn);18427 try mod.errNoteNonLazy(
18409 try sema.mod.errNoteNonLazy(18428 struct_obj.srcLoc(mod),
18410 struct_obj.srcLoc(sema.mod),
18411 msg,18429 msg,
18412 "struct '{s}' declared here",18430 "struct '{s}' declared here",
18413 .{fqn},18431 .{fqn},
...@@ -18826,11 +18844,13 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -18826,11 +18844,13 @@ fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
18826 const ty_src = inst_data.src();18844 const ty_src = inst_data.src();
18827 const field_src = inst_data.src();18845 const field_src = inst_data.src();
18828 const aggregate_ty = try sema.resolveType(block, ty_src, extra.container_type);18846 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");
18830 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);18848 return sema.fieldType(block, aggregate_ty, field_name, field_src, ty_src);
18831}18849}
1883218850
18833fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {18851fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
18852 const mod = sema.mod;
18853 const ip = &mod.intern_pool;
18834 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;18854 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
18835 const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;18855 const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data;
18836 const ty_src = inst_data.src();18856 const ty_src = inst_data.src();
...@@ -18843,7 +18863,8 @@ fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -18843,7 +18863,8 @@ fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
18843 error.GenericPoison => return Air.Inst.Ref.generic_poison_type,18863 error.GenericPoison => return Air.Inst.Ref.generic_poison_type,
18844 else => |e| return e,18864 else => |e| return e,
18845 };18865 };
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);
18847 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);18868 return sema.fieldType(block, aggregate_ty, field_name, field_name_src, ty_src);
18848}18869}
1884918870
...@@ -18851,7 +18872,7 @@ fn fieldType(...@@ -18851,7 +18872,7 @@ fn fieldType(
18851 sema: *Sema,18872 sema: *Sema,
18852 block: *Block,18873 block: *Block,
18853 aggregate_ty: Type,18874 aggregate_ty: Type,
18854 field_name: []const u8,18875 field_name: InternPool.NullTerminatedString,
18855 field_src: LazySrcLoc,18876 field_src: LazySrcLoc,
18856 ty_src: LazySrcLoc,18877 ty_src: LazySrcLoc,
18857) CompileError!Air.Inst.Ref {18878) CompileError!Air.Inst.Ref {
...@@ -19050,13 +19071,14 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19050,13 +19071,14 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19050 const operand = try sema.resolveInst(inst_data.operand);19071 const operand = try sema.resolveInst(inst_data.operand);
19051 const operand_ty = sema.typeOf(operand);19072 const operand_ty = sema.typeOf(operand);
19052 const mod = sema.mod;19073 const mod = sema.mod;
19074 const ip = &mod.intern_pool;
1905319075
19054 try sema.resolveTypeLayout(operand_ty);19076 try sema.resolveTypeLayout(operand_ty);
19055 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {19077 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
19056 .EnumLiteral => {19078 .EnumLiteral => {
19057 const val = try sema.resolveConstValue(block, .unneeded, operand, "");19079 const val = try sema.resolveConstValue(block, .unneeded, operand, "");
19058 const tag_name = mod.intern_pool.indexToKey(val.toIntern()).enum_literal;19080 const tag_name = ip.indexToKey(val.toIntern()).enum_literal;
19059 const bytes = mod.intern_pool.stringToSlice(tag_name);19081 const bytes = ip.stringToSlice(tag_name);
19060 return sema.addStrLit(block, bytes);19082 return sema.addStrLit(block, bytes);
19061 },19083 },
19062 .Enum => operand_ty,19084 .Enum => operand_ty,
...@@ -19089,7 +19111,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19089,7 +19111,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19089 const enum_decl = mod.declPtr(enum_decl_index);19111 const enum_decl = mod.declPtr(enum_decl_index);
19090 const msg = msg: {19112 const msg = msg: {
19091 const msg = try sema.errMsg(block, src, "no field with value '{}' in enum '{s}'", .{19113 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),
19093 });19115 });
19094 errdefer msg.destroy(sema.gpa);19116 errdefer msg.destroy(sema.gpa);
19095 try mod.errNoteNonLazy(enum_decl.srcLoc(mod), msg, "declared here", .{});19117 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...@@ -19098,7 +19120,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19098 return sema.failWithOwnedErrorMsg(msg);19120 return sema.failWithOwnedErrorMsg(msg);
19099 };19121 };
19100 const field_name = enum_ty.enumFieldName(field_index, mod);19122 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));
19102 }19124 }
19103 try sema.requireRuntimeBlock(block, src, operand_src);19125 try sema.requireRuntimeBlock(block, src, operand_src);
19104 if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) {19126 if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) {
...@@ -19119,6 +19141,7 @@ fn zirReify(...@@ -19119,6 +19141,7 @@ fn zirReify(
19119) CompileError!Air.Inst.Ref {19141) CompileError!Air.Inst.Ref {
19120 const mod = sema.mod;19142 const mod = sema.mod;
19121 const gpa = sema.gpa;19143 const gpa = sema.gpa;
19144 const ip = &mod.intern_pool;
19122 const name_strategy = @intToEnum(Zir.Inst.NameStrategy, extended.small);19145 const name_strategy = @intToEnum(Zir.Inst.NameStrategy, extended.small);
19123 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;19146 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
19124 const src = LazySrcLoc.nodeOffset(extra.node);19147 const src = LazySrcLoc.nodeOffset(extra.node);
...@@ -19127,11 +19150,10 @@ fn zirReify(...@@ -19127,11 +19150,10 @@ fn zirReify(
19127 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };19150 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
19128 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);19151 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
19129 const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime-known");19152 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;
19131 const target = mod.getTarget();19154 const target = mod.getTarget();
19132 if (try union_val.val.toValue().anyUndef(mod)) return sema.failWithUseOfUndef(block, src);19155 if (try union_val.val.toValue().anyUndef(mod)) return sema.failWithUseOfUndef(block, src);
19133 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag.toValue(), mod).?;19156 const tag_index = type_info_ty.unionTagFieldIndex(union_val.tag.toValue(), mod).?;
19134 const ip = &mod.intern_pool;
19135 switch (@intToEnum(std.builtin.TypeId, tag_index)) {19157 switch (@intToEnum(std.builtin.TypeId, tag_index)) {
19136 .Type => return Air.Inst.Ref.type_type,19158 .Type => return Air.Inst.Ref.type_type,
19137 .Void => return Air.Inst.Ref.void_type,19159 .Void => return Air.Inst.Ref.void_type,
...@@ -19145,8 +19167,14 @@ fn zirReify(...@@ -19145,8 +19167,14 @@ fn zirReify(
19145 .EnumLiteral => return Air.Inst.Ref.enum_literal_type,19167 .EnumLiteral => return Air.Inst.Ref.enum_literal_type,
19146 .Int => {19168 .Int => {
19147 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19169 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19148 const signedness_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("signedness").?);19170 const signedness_val = try union_val.val.toValue().fieldValue(
19149 const bits_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("bits").?);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
19151 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);19179 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
19152 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));19180 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
...@@ -19155,8 +19183,12 @@ fn zirReify(...@@ -19155,8 +19183,12 @@ fn zirReify(
19155 },19183 },
19156 .Vector => {19184 .Vector => {
19157 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19185 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19158 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);19186 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19159 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);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
19161 const len = @intCast(u32, len_val.toUnsignedInt(mod));19193 const len = @intCast(u32, len_val.toUnsignedInt(mod));
19162 const child_ty = child_val.toType();19194 const child_ty = child_val.toType();
...@@ -19171,7 +19203,9 @@ fn zirReify(...@@ -19171,7 +19203,9 @@ fn zirReify(
19171 },19203 },
19172 .Float => {19204 .Float => {
19173 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19205 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
19176 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));19210 const bits = @intCast(u16, bits_val.toUnsignedInt(mod));
19177 const ty = switch (bits) {19211 const ty = switch (bits) {
...@@ -19186,14 +19220,30 @@ fn zirReify(...@@ -19186,14 +19220,30 @@ fn zirReify(
19186 },19220 },
19187 .Pointer => {19221 .Pointer => {
19188 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19222 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19189 const size_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("size").?);19223 const size_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19190 const is_const_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_const").?);19224 try ip.getOrPutString(gpa, "size"),
19191 const is_volatile_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_volatile").?);19225 ).?);
19192 const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);19226 const is_const_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19193 const address_space_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("address_space").?);19227 try ip.getOrPutString(gpa, "is_const"),
19194 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);19228 ).?);
19195 const is_allowzero_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_allowzero").?);19229 const is_volatile_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19196 const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);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
19198 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {19248 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
19199 return sema.fail(block, src, "alignment must fit in 'u32'", .{});19249 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
...@@ -19279,9 +19329,15 @@ fn zirReify(...@@ -19279,9 +19329,15 @@ fn zirReify(
19279 },19329 },
19280 .Array => {19330 .Array => {
19281 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19331 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19282 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("len").?);19332 const len_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19283 const child_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("child").?);19333 try ip.getOrPutString(gpa, "len"),
19284 const sentinel_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("sentinel").?);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
19286 const len = len_val.toUnsignedInt(mod);19342 const len = len_val.toUnsignedInt(mod);
19287 const child_ty = child_val.toType();19343 const child_ty = child_val.toType();
...@@ -19298,7 +19354,9 @@ fn zirReify(...@@ -19298,7 +19354,9 @@ fn zirReify(
19298 },19354 },
19299 .Optional => {19355 .Optional => {
19300 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19356 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
19303 const child_ty = child_val.toType();19361 const child_ty = child_val.toType();
1930419362
...@@ -19307,8 +19365,12 @@ fn zirReify(...@@ -19307,8 +19365,12 @@ fn zirReify(
19307 },19365 },
19308 .ErrorUnion => {19366 .ErrorUnion => {
19309 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19367 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").?);19368 const error_set_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19311 const payload_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("payload").?);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
19313 const error_set_ty = error_set_val.toType();19375 const error_set_ty = error_set_val.toType();
19314 const payload_ty = payload_val.toType();19376 const payload_ty = payload_val.toType();
...@@ -19330,14 +19392,17 @@ fn zirReify(...@@ -19330,14 +19392,17 @@ fn zirReify(
19330 for (0..len) |i| {19392 for (0..len) |i| {
19331 const elem_val = try payload_val.elemValue(mod, i);19393 const elem_val = try payload_val.elemValue(mod, i);
19332 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);19394 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);19399 const name = try name_val.toIpString(Type.slice_const_u8, mod);
19336 const kv = try mod.getErrorValue(name_str);19400 _ = try mod.getErrorValue(name);
19337 const name_ip = try mod.intern_pool.getOrPutString(gpa, kv.key);19401 const gop = names.getOrPutAssumeCapacity(name);
19338 const gop = names.getOrPutAssumeCapacity(name_ip);
19339 if (gop.found_existing) {19402 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 });
19341 }19406 }
19342 }19407 }
1934319408
...@@ -19346,11 +19411,21 @@ fn zirReify(...@@ -19346,11 +19411,21 @@ fn zirReify(
19346 },19411 },
19347 .Struct => {19412 .Struct => {
19348 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19413 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19349 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);19414 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19350 const backing_integer_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("backing_integer").?);19415 try ip.getOrPutString(gpa, "layout"),
19351 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);19416 ).?);
19352 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);19417 const backing_integer_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19353 const is_tuple_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_tuple").?);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
19355 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);19430 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
1935619431
...@@ -19367,10 +19442,18 @@ fn zirReify(...@@ -19367,10 +19442,18 @@ fn zirReify(
19367 },19442 },
19368 .Enum => {19443 .Enum => {
19369 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19444 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").?);19445 const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19371 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);19446 try ip.getOrPutString(gpa, "tag_type"),
19372 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);19447 ).?);
19373 const is_exhaustive_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_exhaustive").?);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
19375 // Decls19458 // Decls
19376 if (decls_val.sliceLen(mod) > 0) {19459 if (decls_val.sliceLen(mod) > 0) {
...@@ -19396,7 +19479,7 @@ fn zirReify(...@@ -19396,7 +19479,7 @@ fn zirReify(
1939619479
19397 // Define our empty enum decl19480 // Define our empty enum decl
19398 const fields_len = @intCast(u32, try sema.usizeCast(block, src, fields_val.sliceLen(mod)));19481 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, .{
19400 .decl = new_decl_index,19483 .decl = new_decl_index,
19401 .namespace = .none,19484 .namespace = .none,
19402 .fields_len = fields_len,19485 .fields_len = fields_len,
...@@ -19407,35 +19490,36 @@ fn zirReify(...@@ -19407,35 +19490,36 @@ fn zirReify(
19407 .explicit,19490 .explicit,
19408 .tag_ty = int_tag_ty.toIntern(),19491 .tag_ty = int_tag_ty.toIntern(),
19409 });19492 });
19410 errdefer mod.intern_pool.remove(incomplete_enum.index);19493 errdefer ip.remove(incomplete_enum.index);
1941119494
19412 new_decl.val = incomplete_enum.index.toValue();19495 new_decl.val = incomplete_enum.index.toValue();
1941319496
19414 for (0..fields_len) |field_i| {19497 for (0..fields_len) |field_i| {
19415 const elem_val = try fields_val.elemValue(mod, field_i);19498 const elem_val = try fields_val.elemValue(mod, field_i);
19416 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);19499 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19417 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);19500 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19418 const value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("value").?);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(19507 const field_name = try name_val.toIpString(Type.slice_const_u8, mod);
19421 Type.slice_const_u8,
19422 sema.arena,
19423 mod,
19424 );
19425 const field_name_ip = try mod.intern_pool.getOrPutString(gpa, field_name);
1942619508
19427 if (!try sema.intFitsInType(value_val, int_tag_ty, null)) {19509 if (!try sema.intFitsInType(value_val, int_tag_ty, null)) {
19428 // TODO: better source location19510 // TODO: better source location
19429 return sema.fail(block, src, "field '{s}' with enumeration value '{}' is too large for backing int type '{}'", .{19511 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),
19431 value_val.fmtValue(Type.comptime_int, mod),19513 value_val.fmtValue(Type.comptime_int, mod),
19432 int_tag_ty.fmt(mod),19514 int_tag_ty.fmt(mod),
19433 });19515 });
19434 }19516 }
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| {
19437 const msg = msg: {19519 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 });
19439 errdefer msg.destroy(gpa);19523 errdefer msg.destroy(gpa);
19440 _ = other_index; // TODO: this note is incorrect19524 _ = other_index; // TODO: this note is incorrect
19441 try sema.errNote(block, src, msg, "other field here", .{});19525 try sema.errNote(block, src, msg, "other field here", .{});
...@@ -19444,7 +19528,7 @@ fn zirReify(...@@ -19444,7 +19528,7 @@ fn zirReify(
19444 return sema.failWithOwnedErrorMsg(msg);19528 return sema.failWithOwnedErrorMsg(msg);
19445 }19529 }
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| {
19448 const msg = msg: {19532 const msg = msg: {
19449 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});19533 const msg = try sema.errMsg(block, src, "enum tag value {} already taken", .{value_val.fmtValue(Type.comptime_int, mod)});
19450 errdefer msg.destroy(gpa);19534 errdefer msg.destroy(gpa);
...@@ -19462,7 +19546,9 @@ fn zirReify(...@@ -19462,7 +19546,9 @@ fn zirReify(
19462 },19546 },
19463 .Opaque => {19547 .Opaque => {
19464 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19548 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
19467 // Decls19553 // Decls
19468 if (decls_val.sliceLen(mod) > 0) {19554 if (decls_val.sliceLen(mod) > 0) {
...@@ -19496,22 +19582,29 @@ fn zirReify(...@@ -19496,22 +19582,29 @@ fn zirReify(
19496 .decl = new_decl_index,19582 .decl = new_decl_index,
19497 .namespace = new_namespace_index,19583 .namespace = new_namespace_index,
19498 } });19584 } });
19499 errdefer mod.intern_pool.remove(opaque_ty);19585 errdefer ip.remove(opaque_ty);
1950019586
19501 new_decl.val = opaque_ty.toValue();19587 new_decl.val = opaque_ty.toValue();
19502 new_namespace.ty = opaque_ty.toType();19588 new_namespace.ty = opaque_ty.toType();
1950319589
19504 try new_decl.finalizeNewArena(&new_decl_arena);
19505 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);19590 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
19506 try mod.finalizeAnonDecl(new_decl_index);19591 try mod.finalizeAnonDecl(new_decl_index);
19507 return decl_val;19592 return decl_val;
19508 },19593 },
19509 .Union => {19594 .Union => {
19510 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19595 const fields = ip.typeOf(union_val.val).toType().structFields(mod);
19511 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("layout").?);19596 const layout_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19512 const tag_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("tag_type").?);19597 try ip.getOrPutString(gpa, "layout"),
19513 const fields_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("fields").?);19598 ).?);
19514 const decls_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("decls").?);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
19516 // Decls19609 // Decls
19517 if (decls_val.sliceLen(mod) > 0) {19610 if (decls_val.sliceLen(mod) > 0) {
...@@ -19555,7 +19648,7 @@ fn zirReify(...@@ -19555,7 +19648,7 @@ fn zirReify(
19555 const union_obj = mod.unionPtr(union_index);19648 const union_obj = mod.unionPtr(union_index);
19556 errdefer mod.destroyUnion(union_index);19649 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 = .{
19559 .index = union_index,19652 .index = union_index,
19560 .runtime_tag = if (!tag_type_val.isNull(mod))19653 .runtime_tag = if (!tag_type_val.isNull(mod))
19561 .tagged19654 .tagged
...@@ -19566,7 +19659,7 @@ fn zirReify(...@@ -19566,7 +19659,7 @@ fn zirReify(
19566 .ReleaseFast, .ReleaseSmall => .none,19659 .ReleaseFast, .ReleaseSmall => .none,
19567 },19660 },
19568 } });19661 } });
19569 errdefer mod.intern_pool.remove(union_ty);19662 errdefer ip.remove(union_ty);
1957019663
19571 new_decl.val = union_ty.toValue();19664 new_decl.val = union_ty.toValue();
19572 new_namespace.ty = union_ty.toType();19665 new_namespace.ty = union_ty.toType();
...@@ -19579,7 +19672,7 @@ fn zirReify(...@@ -19579,7 +19672,7 @@ fn zirReify(
19579 if (tag_type_val.optionalValue(mod)) |payload_val| {19672 if (tag_type_val.optionalValue(mod)) |payload_val| {
19580 union_obj.tag_ty = payload_val.toType();19673 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())) {
19583 .enum_type => |x| x,19676 .enum_type => |x| x,
19584 else => return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{}),19677 else => return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{}),
19585 };19678 };
...@@ -19597,26 +19690,26 @@ fn zirReify(...@@ -19597,26 +19690,26 @@ fn zirReify(
19597 for (0..fields_len) |i| {19690 for (0..fields_len) |i| {
19598 const elem_val = try fields_val.elemValue(mod, i);19691 const elem_val = try fields_val.elemValue(mod, i);
19599 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);19692 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19600 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);19693 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19601 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);19694 try ip.getOrPutString(gpa, "name"),
19602 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);19695 ).?);
1960319696 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19604 const field_name = try name_val.toAllocatedBytes(19697 try ip.getOrPutString(gpa, "type"),
19605 Type.slice_const_u8,19698 ).?);
19606 new_decl_arena_allocator,19699 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19607 mod,19700 try ip.getOrPutString(gpa, "alignment"),
19608 );19701 ).?);
1960919702
19610 const field_name_ip = try mod.intern_pool.getOrPutString(gpa, field_name);19703 const field_name = try name_val.toIpString(Type.slice_const_u8, mod);
1961119704
19612 if (enum_field_names.len != 0) {19705 if (enum_field_names.len != 0) {
19613 enum_field_names[i] = field_name_ip;19706 enum_field_names[i] = field_name;
19614 }19707 }
1961519708
19616 if (explicit_enum_info) |tag_info| {19709 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 {
19618 const msg = msg: {19711 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) });
19620 errdefer msg.destroy(gpa);19713 errdefer msg.destroy(gpa);
19621 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);19714 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
19622 break :msg msg;19715 break :msg msg;
...@@ -19632,7 +19725,7 @@ fn zirReify(...@@ -19632,7 +19725,7 @@ fn zirReify(
19632 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);19725 const gop = union_obj.fields.getOrPutAssumeCapacity(field_name);
19633 if (gop.found_existing) {19726 if (gop.found_existing) {
19634 // TODO: better source location19727 // 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)});
19636 }19729 }
1963719730
19638 const field_ty = type_val.toType();19731 const field_ty = type_val.toType();
...@@ -19688,7 +19781,7 @@ fn zirReify(...@@ -19688,7 +19781,7 @@ fn zirReify(
19688 for (tag_info.names, 0..) |field_name, field_index| {19781 for (tag_info.names, 0..) |field_name, field_index| {
19689 if (explicit_tags_seen[field_index]) continue;19782 if (explicit_tags_seen[field_index]) continue;
19690 try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{19783 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),
19692 });19785 });
19693 }19786 }
19694 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);19787 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
...@@ -19700,19 +19793,30 @@ fn zirReify(...@@ -19700,19 +19793,30 @@ fn zirReify(
19700 union_obj.tag_ty = try sema.generateUnionTagTypeSimple(block, enum_field_names, null);19793 union_obj.tag_ty = try sema.generateUnionTagTypeSimple(block, enum_field_names, null);
19701 }19794 }
1970219795
19703 try new_decl.finalizeNewArena(&new_decl_arena);
19704 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);19796 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
19705 try mod.finalizeAnonDecl(new_decl_index);19797 try mod.finalizeAnonDecl(new_decl_index);
19706 return decl_val;19798 return decl_val;
19707 },19799 },
19708 .Fn => {19800 .Fn => {
19709 const fields = ip.typeOf(union_val.val).toType().structFields(mod);19801 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").?);19802 const calling_convention_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19711 const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("alignment").?);19803 try ip.getOrPutString(gpa, "calling_convention"),
19712 const is_generic_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_generic").?);19804 ).?);
19713 const is_var_args_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("is_var_args").?);19805 const alignment_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex(
19714 const return_type_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("return_type").?);19806 try ip.getOrPutString(gpa, "alignment"),
19715 const params_val = try union_val.val.toValue().fieldValue(mod, fields.getIndex("params").?);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
19717 const is_generic = is_generic_val.toBool();19821 const is_generic = is_generic_val.toBool();
19718 if (is_generic) {19822 if (is_generic) {
...@@ -19746,9 +19850,15 @@ fn zirReify(...@@ -19746,9 +19850,15 @@ fn zirReify(
19746 for (param_types, 0..) |*param_type, i| {19850 for (param_types, 0..) |*param_type, i| {
19747 const elem_val = try params_val.elemValue(mod, i);19851 const elem_val = try params_val.elemValue(mod, i);
19748 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);19852 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").?);19853 const param_is_generic_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19750 const param_is_noalias_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_noalias").?);19854 try ip.getOrPutString(gpa, "is_generic"),
19751 const opt_param_type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);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
19753 if (param_is_generic_val.toBool()) {19863 if (param_is_generic_val.toBool()) {
19754 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});19864 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});
...@@ -19801,6 +19911,7 @@ fn reifyStruct(...@@ -19801,6 +19911,7 @@ fn reifyStruct(
19801) CompileError!Air.Inst.Ref {19911) CompileError!Air.Inst.Ref {
19802 const mod = sema.mod;19912 const mod = sema.mod;
19803 const gpa = sema.gpa;19913 const gpa = sema.gpa;
19914 const ip = &mod.intern_pool;
1980419915
19805 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);19916 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
19806 errdefer new_decl_arena.deinit();19917 errdefer new_decl_arena.deinit();
...@@ -19839,11 +19950,11 @@ fn reifyStruct(...@@ -19839,11 +19950,11 @@ fn reifyStruct(
19839 const struct_obj = mod.structPtr(struct_index);19950 const struct_obj = mod.structPtr(struct_index);
19840 errdefer mod.destroyStruct(struct_index);19951 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 = .{
19843 .index = struct_index.toOptional(),19954 .index = struct_index.toOptional(),
19844 .namespace = new_namespace_index.toOptional(),19955 .namespace = new_namespace_index.toOptional(),
19845 } });19956 } });
19846 errdefer mod.intern_pool.remove(struct_ty);19957 errdefer ip.remove(struct_ty);
1984719958
19848 new_decl.val = struct_ty.toValue();19959 new_decl.val = struct_ty.toValue();
19849 new_namespace.ty = struct_ty.toType();19960 new_namespace.ty = struct_ty.toType();
...@@ -19854,12 +19965,22 @@ fn reifyStruct(...@@ -19854,12 +19965,22 @@ fn reifyStruct(
19854 var i: usize = 0;19965 var i: usize = 0;
19855 while (i < fields_len) : (i += 1) {19966 while (i < fields_len) : (i += 1) {
19856 const elem_val = try fields_val.elemValue(mod, i);19967 const elem_val = try fields_val.elemValue(mod, i);
19857 const elem_fields = mod.intern_pool.typeOf(elem_val.toIntern()).toType().structFields(mod);19968 const elem_fields = ip.typeOf(elem_val.toIntern()).toType().structFields(mod);
19858 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex("name").?);19969 const name_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19859 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex("type").?);19970 try ip.getOrPutString(gpa, "name"),
19860 const default_value_val = try elem_val.fieldValue(mod, elem_fields.getIndex("default_value").?);19971 ).?);
19861 const is_comptime_val = try elem_val.fieldValue(mod, elem_fields.getIndex("is_comptime").?);19972 const type_val = try elem_val.fieldValue(mod, elem_fields.getIndex(
19862 const alignment_val = try elem_val.fieldValue(mod, elem_fields.getIndex("alignment").?);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
19864 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {19985 if (!try sema.intFitsInType(alignment_val, Type.u32, null)) {
19865 return sema.fail(block, src, "alignment must fit in 'u32'", .{});19986 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
...@@ -19874,19 +19995,15 @@ fn reifyStruct(...@@ -19874,19 +19995,15 @@ fn reifyStruct(
19874 return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{});19995 return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{});
19875 }19996 }
1987619997
19877 const field_name = try name_val.toAllocatedBytes(19998 const field_name = try name_val.toIpString(Type.slice_const_u8, mod);
19878 Type.slice_const_u8,
19879 new_decl_arena_allocator,
19880 mod,
19881 );
1988219999
19883 if (is_tuple) {20000 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 {
19885 return sema.fail(20002 return sema.fail(
19886 block,20003 block,
19887 src,20004 src,
19888 "tuple cannot have non-numeric field '{s}'",20005 "tuple cannot have non-numeric field '{s}'",
19889 .{field_name},20006 .{ip.stringToSlice(field_name)},
19890 );20007 );
19891 };20008 };
1989220009
...@@ -19902,16 +20019,16 @@ fn reifyStruct(...@@ -19902,16 +20019,16 @@ fn reifyStruct(
19902 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);20019 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
19903 if (gop.found_existing) {20020 if (gop.found_existing) {
19904 // TODO: better source location20021 // 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)});
19906 }20023 }
1990720024
19908 const field_ty = type_val.toType();20025 const field_ty = type_val.toType();
19909 const default_val = if (default_value_val.optionalValue(mod)) |opt_val|20026 const default_val = if (default_value_val.optionalValue(mod)) |opt_val|
19910 try sema.pointerDeref(block, src, opt_val, try mod.singleConstPtrType(field_ty)) orelse20027 (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")20028 return sema.failWithNeededComptime(block, src, "struct field default value must be comptime-known")).toIntern()
19912 else20029 else
19913 Value.@"unreachable";20030 .none;
19914 if (is_comptime_val.toBool() and default_val.toIntern() == .unreachable_value) {20031 if (is_comptime_val.toBool() and default_val == .none) {
19915 return sema.fail(block, src, "comptime field without default initialization value", .{});20032 return sema.fail(block, src, "comptime field without default initialization value", .{});
19916 }20033 }
1991720034
...@@ -20000,7 +20117,6 @@ fn reifyStruct(...@@ -20000,7 +20117,6 @@ fn reifyStruct(
20000 struct_obj.status = .have_layout;20117 struct_obj.status = .have_layout;
20001 }20118 }
2000220119
20003 try new_decl.finalizeNewArena(&new_decl_arena);
20004 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);20120 const decl_val = sema.analyzeDeclVal(block, src, new_decl_index);
20005 try mod.finalizeAnonDecl(new_decl_index);20121 try mod.finalizeAnonDecl(new_decl_index);
20006 return decl_val;20122 return decl_val;
...@@ -20871,7 +20987,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -20871,7 +20987,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
20871 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;20987 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2087220988
20873 const ty = try sema.resolveType(block, lhs_src, extra.lhs);20989 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
20876 const mod = sema.mod;20992 const mod = sema.mod;
20877 try sema.resolveTypeLayout(ty);20993 try sema.resolveTypeLayout(ty);
...@@ -20889,7 +21005,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -20889,7 +21005,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
20889 }21005 }
2089021006
20891 const field_index = if (ty.isTuple(mod)) blk: {21007 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")) {
20893 return sema.fail(block, src, "no offset available for 'len' field of tuple", .{});21009 return sema.fail(block, src, "no offset available for 'len' field of tuple", .{});
20894 }21010 }
20895 break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src);21011 break :blk try sema.tupleFieldIndex(block, ty, field_name, rhs_src);
...@@ -21351,6 +21467,8 @@ fn resolveExportOptions(...@@ -21351,6 +21467,8 @@ fn resolveExportOptions(
21351 zir_ref: Zir.Inst.Ref,21467 zir_ref: Zir.Inst.Ref,
21352) CompileError!std.builtin.ExportOptions {21468) CompileError!std.builtin.ExportOptions {
21353 const mod = sema.mod;21469 const mod = sema.mod;
21470 const gpa = sema.gpa;
21471 const ip = &mod.intern_pool;
21354 const export_options_ty = try sema.getBuiltinType("ExportOptions");21472 const export_options_ty = try sema.getBuiltinType("ExportOptions");
21355 const air_ref = try sema.resolveInst(zir_ref);21473 const air_ref = try sema.resolveInst(zir_ref);
21356 const options = try sema.coerce(block, export_options_ty, air_ref, src);21474 const options = try sema.coerce(block, export_options_ty, air_ref, src);
...@@ -21360,16 +21478,16 @@ fn resolveExportOptions(...@@ -21360,16 +21478,16 @@ fn resolveExportOptions(
21360 const section_src = sema.maybeOptionsSrc(block, src, "section");21478 const section_src = sema.maybeOptionsSrc(block, src, "section");
21361 const visibility_src = sema.maybeOptionsSrc(block, src, "visibility");21479 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);
21364 const name_val = try sema.resolveConstValue(block, name_src, name_operand, "name of exported value must be comptime-known");21482 const name_val = try sema.resolveConstValue(block, name_src, name_operand, "name of exported value must be comptime-known");
21365 const name_ty = Type.slice_const_u8;21483 const name_ty = Type.slice_const_u8;
21366 const name = try name_val.toAllocatedBytes(name_ty, sema.arena, mod);21484 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);
21369 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_operand, "linkage of exported value must be comptime-known");21487 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_operand, "linkage of exported value must be comptime-known");
21370 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);21488 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);
21373 const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known");21491 const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known");
21374 const section_ty = Type.slice_const_u8;21492 const section_ty = Type.slice_const_u8;
21375 const section = if (section_opt_val.optionalValue(mod)) |section_val|21493 const section = if (section_opt_val.optionalValue(mod)) |section_val|
...@@ -21377,7 +21495,7 @@ fn resolveExportOptions(...@@ -21377,7 +21495,7 @@ fn resolveExportOptions(
21377 else21495 else
21378 null;21496 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);
21381 const visibility_val = try sema.resolveConstValue(block, visibility_src, visibility_operand, "visibility of exported value must be comptime-known");21499 const visibility_val = try sema.resolveConstValue(block, visibility_src, visibility_operand, "visibility of exported value must be comptime-known");
21382 const visibility = mod.toEnum(std.builtin.SymbolVisibility, visibility_val);21500 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...@@ -22217,10 +22335,11 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
22217 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };22335 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
2221822336
22219 const parent_ty = try sema.resolveType(block, ty_src, extra.parent_type);22337 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");
22221 const field_ptr = try sema.resolveInst(extra.field_ptr);22339 const field_ptr = try sema.resolveInst(extra.field_ptr);
22222 const field_ptr_ty = sema.typeOf(field_ptr);22340 const field_ptr_ty = sema.typeOf(field_ptr);
22223 const mod = sema.mod;22341 const mod = sema.mod;
22342 const ip = &mod.intern_pool;
2222422343
22225 if (parent_ty.zigTypeTag(mod) != .Struct and parent_ty.zigTypeTag(mod) != .Union) {22344 if (parent_ty.zigTypeTag(mod) != .Struct and parent_ty.zigTypeTag(mod) != .Union) {
22226 return sema.fail(block, ty_src, "expected struct or union type, found '{}'", .{parent_ty.fmt(sema.mod)});22345 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...@@ -22230,7 +22349,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
22230 const field_index = switch (parent_ty.zigTypeTag(mod)) {22349 const field_index = switch (parent_ty.zigTypeTag(mod)) {
22231 .Struct => blk: {22350 .Struct => blk: {
22232 if (parent_ty.isTuple(mod)) {22351 if (parent_ty.isTuple(mod)) {
22233 if (mem.eql(u8, field_name, "len")) {22352 if (ip.stringEqlSlice(field_name, "len")) {
22234 return sema.fail(block, src, "cannot get @fieldParentPtr of 'len' field of tuple", .{});22353 return sema.fail(block, src, "cannot get @fieldParentPtr of 'len' field of tuple", .{});
22235 }22354 }
22236 break :blk try sema.tupleFieldIndex(block, parent_ty, field_name, name_src);22355 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...@@ -22276,7 +22395,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
22276 const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);22395 const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
2227722396
22278 if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {22397 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())) {
22280 .ptr => |ptr| switch (ptr.addr) {22399 .ptr => |ptr| switch (ptr.addr) {
22281 .field => |field| field,22400 .field => |field| field,
22282 else => null,22401 else => null,
...@@ -22291,7 +22410,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -22291,7 +22410,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
22291 src,22410 src,
22292 "field '{s}' has index '{d}' but pointer value is index '{d}' of struct '{}'",22411 "field '{s}' has index '{d}' but pointer value is index '{d}' of struct '{}'",
22293 .{22412 .{
22294 field_name,22413 ip.stringToSlice(field_name),
22295 field_index,22414 field_index,
22296 field.index,22415 field.index,
22297 parent_ty.fmt(sema.mod),22416 parent_ty.fmt(sema.mod),
...@@ -22807,6 +22926,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -22807,6 +22926,8 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2280722926
22808fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {22927fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
22809 const mod = sema.mod;22928 const mod = sema.mod;
22929 const gpa = sema.gpa;
22930 const ip = &mod.intern_pool;
22810 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;22931 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
22811 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;22932 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
22812 const src = inst_data.src();22933 const src = inst_data.src();
...@@ -22824,7 +22945,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -22824,7 +22945,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
22824 const dest_elem_ty = dest_ptr_ty.elemType2(mod);22945 const dest_elem_ty = dest_ptr_ty.elemType2(mod);
2282522946
22826 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |ptr_val| rs: {22947 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);
22828 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse22949 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse
22829 break :rs dest_src;22950 break :rs dest_src;
22830 const len_u64 = (try len_val.getUnsignedIntAdvanced(mod, sema)).?;22951 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...@@ -23068,11 +23189,11 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
23068 if (val.isGenericPoison()) {23189 if (val.isGenericPoison()) {
23069 break :blk FuncLinkSection{ .generic = {} };23190 break :blk FuncLinkSection{ .generic = {} };
23070 }23191 }
23071 break :blk FuncLinkSection{ .explicit = try val.toAllocatedBytes(ty, sema.arena, sema.mod) };23192 break :blk FuncLinkSection{ .explicit = try val.toIpString(ty, mod) };
23072 } else if (extra.data.bits.has_section_ref) blk: {23193 } else if (extra.data.bits.has_section_ref) blk: {
23073 const section_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);23194 const section_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
23074 extra_index += 1;23195 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) {
23076 error.GenericPoison => {23197 error.GenericPoison => {
23077 break :blk FuncLinkSection{ .generic = {} };23198 break :blk FuncLinkSection{ .generic = {} };
23078 },23199 },
...@@ -23272,6 +23393,8 @@ fn resolvePrefetchOptions(...@@ -23272,6 +23393,8 @@ fn resolvePrefetchOptions(
23272 zir_ref: Zir.Inst.Ref,23393 zir_ref: Zir.Inst.Ref,
23273) CompileError!std.builtin.PrefetchOptions {23394) CompileError!std.builtin.PrefetchOptions {
23274 const mod = sema.mod;23395 const mod = sema.mod;
23396 const gpa = sema.gpa;
23397 const ip = &mod.intern_pool;
23275 const options_ty = try sema.getBuiltinType("PrefetchOptions");23398 const options_ty = try sema.getBuiltinType("PrefetchOptions");
23276 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);23399 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2327723400
...@@ -23279,13 +23402,13 @@ fn resolvePrefetchOptions(...@@ -23279,13 +23402,13 @@ fn resolvePrefetchOptions(
23279 const locality_src = sema.maybeOptionsSrc(block, src, "locality");23402 const locality_src = sema.maybeOptionsSrc(block, src, "locality");
23280 const cache_src = sema.maybeOptionsSrc(block, src, "cache");23403 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);
23283 const rw_val = try sema.resolveConstValue(block, rw_src, rw, "prefetch read/write must be comptime-known");23406 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);
23286 const locality_val = try sema.resolveConstValue(block, locality_src, locality, "prefetch locality must be comptime-known");23409 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);
23289 const cache_val = try sema.resolveConstValue(block, cache_src, cache, "prefetch cache must be comptime-known");23412 const cache_val = try sema.resolveConstValue(block, cache_src, cache, "prefetch cache must be comptime-known");
2329023413
23291 return std.builtin.PrefetchOptions{23414 return std.builtin.PrefetchOptions{
...@@ -23336,6 +23459,8 @@ fn resolveExternOptions(...@@ -23336,6 +23459,8 @@ fn resolveExternOptions(
23336 zir_ref: Zir.Inst.Ref,23459 zir_ref: Zir.Inst.Ref,
23337) CompileError!std.builtin.ExternOptions {23460) CompileError!std.builtin.ExternOptions {
23338 const mod = sema.mod;23461 const mod = sema.mod;
23462 const gpa = sema.gpa;
23463 const ip = &mod.intern_pool;
23339 const options_inst = try sema.resolveInst(zir_ref);23464 const options_inst = try sema.resolveInst(zir_ref);
23340 const extern_options_ty = try sema.getBuiltinType("ExternOptions");23465 const extern_options_ty = try sema.getBuiltinType("ExternOptions");
23341 const options = try sema.coerce(block, extern_options_ty, options_inst, src);23466 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
...@@ -23345,18 +23470,18 @@ fn resolveExternOptions(...@@ -23345,18 +23470,18 @@ fn resolveExternOptions(
23345 const linkage_src = sema.maybeOptionsSrc(block, src, "linkage");23470 const linkage_src = sema.maybeOptionsSrc(block, src, "linkage");
23346 const thread_local_src = sema.maybeOptionsSrc(block, src, "thread_local");23471 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);
23349 const name_val = try sema.resolveConstValue(block, name_src, name_ref, "name of the extern symbol must be comptime-known");23474 const name_val = try sema.resolveConstValue(block, name_src, name_ref, "name of the extern symbol must be comptime-known");
23350 const name = try name_val.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);23475 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);
23353 const library_name_val = try sema.resolveConstValue(block, library_src, library_name_inst, "library in which extern symbol is must be comptime-known");23478 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);
23356 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_ref, "linkage of the extern symbol must be comptime-known");23481 const linkage_val = try sema.resolveConstValue(block, linkage_src, linkage_ref, "linkage of the extern symbol must be comptime-known");
23357 const linkage = mod.toEnum(std.builtin.GlobalLinkage, linkage_val);23482 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);
23360 const is_thread_local_val = try sema.resolveConstValue(block, thread_local_src, is_thread_local, "threadlocality of the extern symbol must be comptime-known");23485 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
23362 const library_name = if (library_name_val.optionalValue(mod)) |payload| blk: {23487 const library_name = if (library_name_val.optionalValue(mod)) |payload| blk: {
...@@ -23425,7 +23550,7 @@ fn zirBuiltinExtern(...@@ -23425,7 +23550,7 @@ fn zirBuiltinExtern(
23425 const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node, null);23550 const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace, sema.owner_decl.src_node, null);
23426 errdefer mod.destroyDecl(new_decl_index);23551 errdefer mod.destroyDecl(new_decl_index);
23427 const new_decl = mod.declPtr(new_decl_index);23552 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
23430 {23555 {
23431 const new_var = try mod.intern(.{ .variable = .{23556 const new_var = try mod.intern(.{ .variable = .{
...@@ -23444,7 +23569,7 @@ fn zirBuiltinExtern(...@@ -23444,7 +23569,7 @@ fn zirBuiltinExtern(
23444 new_decl.ty = ty;23569 new_decl.ty = ty;
23445 new_decl.val = new_var.toValue();23570 new_decl.val = new_var.toValue();
23446 new_decl.@"align" = 0;23571 new_decl.@"align" = 0;
23447 new_decl.@"linksection" = null;23572 new_decl.@"linksection" = .none;
23448 new_decl.has_tv = true;23573 new_decl.has_tv = true;
23449 new_decl.analysis = .complete;23574 new_decl.analysis = .complete;
23450 new_decl.generation = mod.generation;23575 new_decl.generation = mod.generation;
...@@ -24265,12 +24390,13 @@ fn safetyPanic(...@@ -24265,12 +24390,13 @@ fn safetyPanic(
24265 panic_id: PanicId,24390 panic_id: PanicId,
24266) CompileError!void {24391) CompileError!void {
24267 const mod = sema.mod;24392 const mod = sema.mod;
24393 const gpa = sema.gpa;
24268 const panic_messages_ty = try sema.getBuiltinType("panic_messages");24394 const panic_messages_ty = try sema.getBuiltinType("panic_messages");
24269 const msg_decl_index = (try sema.namespaceLookup(24395 const msg_decl_index = (try sema.namespaceLookup(
24270 block,24396 block,
24271 sema.src,24397 sema.src,
24272 panic_messages_ty.getNamespaceIndex(mod).unwrap().?,24398 panic_messages_ty.getNamespaceIndex(mod).unwrap().?,
24273 @tagName(panic_id),24399 try mod.intern_pool.getOrPutString(gpa, @tagName(panic_id)),
24274 )).?;24400 )).?;
2427524401
24276 const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index);24402 const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index);
...@@ -24302,14 +24428,13 @@ fn fieldVal(...@@ -24302,14 +24428,13 @@ fn fieldVal(
24302 block: *Block,24428 block: *Block,
24303 src: LazySrcLoc,24429 src: LazySrcLoc,
24304 object: Air.Inst.Ref,24430 object: Air.Inst.Ref,
24305 field_name: []const u8,24431 field_name: InternPool.NullTerminatedString,
24306 field_name_src: LazySrcLoc,24432 field_name_src: LazySrcLoc,
24307) CompileError!Air.Inst.Ref {24433) CompileError!Air.Inst.Ref {
24308 // When editing this function, note that there is corresponding logic to be edited24434 // When editing this function, note that there is corresponding logic to be edited
24309 // in `fieldPtr`. This function takes a value and returns a value.24435 // in `fieldPtr`. This function takes a value and returns a value.
2431024436
24311 const mod = sema.mod;24437 const mod = sema.mod;
24312 const gpa = sema.gpa;
24313 const ip = &mod.intern_pool;24438 const ip = &mod.intern_pool;
24314 const object_src = src; // TODO better source location24439 const object_src = src; // TODO better source location
24315 const object_ty = sema.typeOf(object);24440 const object_ty = sema.typeOf(object);
...@@ -24326,12 +24451,12 @@ fn fieldVal(...@@ -24326,12 +24451,12 @@ fn fieldVal(
2432624451
24327 switch (inner_ty.zigTypeTag(mod)) {24452 switch (inner_ty.zigTypeTag(mod)) {
24328 .Array => {24453 .Array => {
24329 if (mem.eql(u8, field_name, "len")) {24454 if (ip.stringEqlSlice(field_name, "len")) {
24330 return sema.addConstant(24455 return sema.addConstant(
24331 Type.usize,24456 Type.usize,
24332 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),24457 try mod.intValue(Type.usize, inner_ty.arrayLen(mod)),
24333 );24458 );
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) {
24335 const ptr_info = object_ty.ptrInfo(mod);24460 const ptr_info = object_ty.ptrInfo(mod);
24336 const result_ty = try Type.ptr(sema.arena, mod, .{24461 const result_ty = try Type.ptr(sema.arena, mod, .{
24337 .pointee_type = ptr_info.pointee_type.childType(mod),24462 .pointee_type = ptr_info.pointee_type.childType(mod),
...@@ -24352,20 +24477,20 @@ fn fieldVal(...@@ -24352,20 +24477,20 @@ fn fieldVal(
24352 block,24477 block,
24353 field_name_src,24478 field_name_src,
24354 "no member named '{s}' in '{}'",24479 "no member named '{s}' in '{}'",
24355 .{ field_name, object_ty.fmt(mod) },24480 .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
24356 );24481 );
24357 }24482 }
24358 },24483 },
24359 .Pointer => {24484 .Pointer => {
24360 const ptr_info = inner_ty.ptrInfo(mod);24485 const ptr_info = inner_ty.ptrInfo(mod);
24361 if (ptr_info.size == .Slice) {24486 if (ptr_info.size == .Slice) {
24362 if (mem.eql(u8, field_name, "ptr")) {24487 if (ip.stringEqlSlice(field_name, "ptr")) {
24363 const slice = if (is_pointer_to)24488 const slice = if (is_pointer_to)
24364 try sema.analyzeLoad(block, src, object, object_src)24489 try sema.analyzeLoad(block, src, object, object_src)
24365 else24490 else
24366 object;24491 object;
24367 return sema.analyzeSlicePtr(block, object_src, slice, inner_ty);24492 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")) {
24369 const slice = if (is_pointer_to)24494 const slice = if (is_pointer_to)
24370 try sema.analyzeLoad(block, src, object, object_src)24495 try sema.analyzeLoad(block, src, object, object_src)
24371 else24496 else
...@@ -24376,7 +24501,7 @@ fn fieldVal(...@@ -24376,7 +24501,7 @@ fn fieldVal(
24376 block,24501 block,
24377 field_name_src,24502 field_name_src,
24378 "no member named '{s}' in '{}'",24503 "no member named '{s}' in '{}'",
24379 .{ field_name, object_ty.fmt(mod) },24504 .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
24380 );24505 );
24381 }24506 }
24382 }24507 }
...@@ -24392,13 +24517,12 @@ fn fieldVal(...@@ -24392,13 +24517,12 @@ fn fieldVal(
2439224517
24393 switch (try child_type.zigTypeTagOrPoison(mod)) {24518 switch (try child_type.zigTypeTagOrPoison(mod)) {
24394 .ErrorSet => {24519 .ErrorSet => {
24395 const name = try ip.getOrPutString(gpa, field_name);
24396 switch (ip.indexToKey(child_type.toIntern())) {24520 switch (ip.indexToKey(child_type.toIntern())) {
24397 .error_set_type => |error_set_type| blk: {24521 .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;
24399 const msg = msg: {24523 const msg = msg: {
24400 const msg = try sema.errMsg(block, src, "no error named '{s}' in '{}'", .{24524 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),
24402 });24526 });
24403 errdefer msg.destroy(sema.gpa);24527 errdefer msg.destroy(sema.gpa);
24404 try sema.addDeclaredHereNote(msg, child_type);24528 try sema.addDeclaredHereNote(msg, child_type);
...@@ -24419,10 +24543,10 @@ fn fieldVal(...@@ -24419,10 +24543,10 @@ fn fieldVal(
24419 const error_set_type = if (!child_type.isAnyError(mod))24543 const error_set_type = if (!child_type.isAnyError(mod))
24420 child_type24544 child_type
24421 else24545 else
24422 try mod.singleErrorSetTypeNts(name);24546 try mod.singleErrorSetTypeNts(field_name);
24423 return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{24547 return sema.addConstant(error_set_type, (try mod.intern(.{ .err = .{
24424 .ty = error_set_type.toIntern(),24548 .ty = error_set_type.toIntern(),
24425 .name = name,24549 .name = field_name,
24426 } })).toValue());24550 } })).toValue());
24427 },24551 },
24428 .Union => {24552 .Union => {
...@@ -24499,7 +24623,7 @@ fn fieldPtr(...@@ -24499,7 +24623,7 @@ fn fieldPtr(
24499 block: *Block,24623 block: *Block,
24500 src: LazySrcLoc,24624 src: LazySrcLoc,
24501 object_ptr: Air.Inst.Ref,24625 object_ptr: Air.Inst.Ref,
24502 field_name: []const u8,24626 field_name: InternPool.NullTerminatedString,
24503 field_name_src: LazySrcLoc,24627 field_name_src: LazySrcLoc,
24504 initializing: bool,24628 initializing: bool,
24505) CompileError!Air.Inst.Ref {24629) CompileError!Air.Inst.Ref {
...@@ -24507,7 +24631,6 @@ fn fieldPtr(...@@ -24507,7 +24631,6 @@ fn fieldPtr(
24507 // in `fieldVal`. This function takes a pointer and returns a pointer.24631 // in `fieldVal`. This function takes a pointer and returns a pointer.
2450824632
24509 const mod = sema.mod;24633 const mod = sema.mod;
24510 const gpa = sema.gpa;
24511 const ip = &mod.intern_pool;24634 const ip = &mod.intern_pool;
24512 const object_ptr_src = src; // TODO better source location24635 const object_ptr_src = src; // TODO better source location
24513 const object_ptr_ty = sema.typeOf(object_ptr);24636 const object_ptr_ty = sema.typeOf(object_ptr);
...@@ -24528,7 +24651,7 @@ fn fieldPtr(...@@ -24528,7 +24651,7 @@ fn fieldPtr(
2452824651
24529 switch (inner_ty.zigTypeTag(mod)) {24652 switch (inner_ty.zigTypeTag(mod)) {
24530 .Array => {24653 .Array => {
24531 if (mem.eql(u8, field_name, "len")) {24654 if (ip.stringEqlSlice(field_name, "len")) {
24532 var anon_decl = try block.startAnonDecl();24655 var anon_decl = try block.startAnonDecl();
24533 defer anon_decl.deinit();24656 defer anon_decl.deinit();
24534 return sema.analyzeDeclRef(try anon_decl.finish(24657 return sema.analyzeDeclRef(try anon_decl.finish(
...@@ -24541,7 +24664,7 @@ fn fieldPtr(...@@ -24541,7 +24664,7 @@ fn fieldPtr(
24541 block,24664 block,
24542 field_name_src,24665 field_name_src,
24543 "no member named '{s}' in '{}'",24666 "no member named '{s}' in '{}'",
24544 .{ field_name, object_ty.fmt(mod) },24667 .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
24545 );24668 );
24546 }24669 }
24547 },24670 },
...@@ -24553,7 +24676,7 @@ fn fieldPtr(...@@ -24553,7 +24676,7 @@ fn fieldPtr(
2455324676
24554 const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty;24677 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")) {
24557 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);24680 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2455824681
24559 const result_ty = try Type.ptr(sema.arena, mod, .{24682 const result_ty = try Type.ptr(sema.arena, mod, .{
...@@ -24575,7 +24698,7 @@ fn fieldPtr(...@@ -24575,7 +24698,7 @@ fn fieldPtr(
24575 try sema.requireRuntimeBlock(block, src, null);24698 try sema.requireRuntimeBlock(block, src, null);
2457624699
24577 return block.addTyOp(.ptr_slice_ptr_ptr, result_ty, inner_ptr);24700 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")) {
24579 const result_ty = try Type.ptr(sema.arena, mod, .{24702 const result_ty = try Type.ptr(sema.arena, mod, .{
24580 .pointee_type = Type.usize,24703 .pointee_type = Type.usize,
24581 .mutable = attr_ptr_ty.ptrIsMutable(mod),24704 .mutable = attr_ptr_ty.ptrIsMutable(mod),
...@@ -24600,7 +24723,7 @@ fn fieldPtr(...@@ -24600,7 +24723,7 @@ fn fieldPtr(
24600 block,24723 block,
24601 field_name_src,24724 field_name_src,
24602 "no member named '{s}' in '{}'",24725 "no member named '{s}' in '{}'",
24603 .{ field_name, object_ty.fmt(mod) },24726 .{ ip.stringToSlice(field_name), object_ty.fmt(mod) },
24604 );24727 );
24605 }24728 }
24606 },24729 },
...@@ -24617,14 +24740,13 @@ fn fieldPtr(...@@ -24617,14 +24740,13 @@ fn fieldPtr(
2461724740
24618 switch (child_type.zigTypeTag(mod)) {24741 switch (child_type.zigTypeTag(mod)) {
24619 .ErrorSet => {24742 .ErrorSet => {
24620 const name = try ip.getOrPutString(gpa, field_name);
24621 switch (ip.indexToKey(child_type.toIntern())) {24743 switch (ip.indexToKey(child_type.toIntern())) {
24622 .error_set_type => |error_set_type| blk: {24744 .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) {
24624 break :blk;24746 break :blk;
24625 }24747 }
24626 return sema.fail(block, src, "no error named '{s}' in '{}'", .{24748 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),
24628 });24750 });
24629 },24751 },
24630 .inferred_error_set_type => {24752 .inferred_error_set_type => {
...@@ -24642,12 +24764,12 @@ fn fieldPtr(...@@ -24642,12 +24764,12 @@ fn fieldPtr(
24642 const error_set_type = if (!child_type.isAnyError(mod))24764 const error_set_type = if (!child_type.isAnyError(mod))
24643 child_type24765 child_type
24644 else24766 else
24645 try mod.singleErrorSetTypeNts(name);24767 try mod.singleErrorSetTypeNts(field_name);
24646 return sema.analyzeDeclRef(try anon_decl.finish(24768 return sema.analyzeDeclRef(try anon_decl.finish(
24647 error_set_type,24769 error_set_type,
24648 (try mod.intern(.{ .err = .{24770 (try mod.intern(.{ .err = .{
24649 .ty = error_set_type.toIntern(),24771 .ty = error_set_type.toIntern(),
24650 .name = name,24772 .name = field_name,
24651 } })).toValue(),24773 } })).toValue(),
24652 0, // default alignment24774 0, // default alignment
24653 ));24775 ));
...@@ -24736,13 +24858,14 @@ fn fieldCallBind(...@@ -24736,13 +24858,14 @@ fn fieldCallBind(
24736 block: *Block,24858 block: *Block,
24737 src: LazySrcLoc,24859 src: LazySrcLoc,
24738 raw_ptr: Air.Inst.Ref,24860 raw_ptr: Air.Inst.Ref,
24739 field_name: []const u8,24861 field_name: InternPool.NullTerminatedString,
24740 field_name_src: LazySrcLoc,24862 field_name_src: LazySrcLoc,
24741) CompileError!ResolvedFieldCallee {24863) CompileError!ResolvedFieldCallee {
24742 // When editing this function, note that there is corresponding logic to be edited24864 // When editing this function, note that there is corresponding logic to be edited
24743 // in `fieldVal`. This function takes a pointer and returns a pointer.24865 // in `fieldVal`. This function takes a pointer and returns a pointer.
2474424866
24745 const mod = sema.mod;24867 const mod = sema.mod;
24868 const ip = &mod.intern_pool;
24746 const raw_ptr_src = src; // TODO better source location24869 const raw_ptr_src = src; // TODO better source location
24747 const raw_ptr_ty = sema.typeOf(raw_ptr);24870 const raw_ptr_ty = sema.typeOf(raw_ptr);
24748 const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C))24871 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(...@@ -24771,18 +24894,18 @@ fn fieldCallBind(
2477124894
24772 return sema.finishFieldCallBind(block, src, ptr_ty, field.ty, field_index, object_ptr);24895 return sema.finishFieldCallBind(block, src, ptr_ty, field.ty, field_index, object_ptr);
24773 } else if (struct_ty.isTuple(mod)) {24896 } else if (struct_ty.isTuple(mod)) {
24774 if (mem.eql(u8, field_name, "len")) {24897 if (ip.stringEqlSlice(field_name, "len")) {
24775 return .{ .direct = try sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount(mod)) };24898 return .{ .direct = try sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount(mod)) };
24776 }24899 }
24777 if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| {24900 if (std.fmt.parseUnsigned(u32, ip.stringToSlice(field_name), 10)) |field_index| {
24778 if (field_index >= struct_ty.structFieldCount(mod)) break :find_field;24901 if (field_index >= struct_ty.structFieldCount(mod)) break :find_field;
24779 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(field_index, mod), field_index, object_ptr);24902 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(field_index, mod), field_index, object_ptr);
24780 } else |_| {}24903 } else |_| {}
24781 } else {24904 } else {
24782 const max = struct_ty.structFieldCount(mod);24905 const max = struct_ty.structFieldCount(mod);
24783 var i: u32 = 0;24906 for (0..max) |i_usize| {
24784 while (i < max) : (i += 1) {24907 const i = @intCast(u32, i_usize);
24785 if (mem.eql(u8, struct_ty.structFieldName(i, mod), field_name)) {24908 if (field_name == struct_ty.structFieldName(i, mod)) {
24786 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(i, mod), i, object_ptr);24909 return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(i, mod), i, object_ptr);
24787 }24910 }
24788 }24911 }
...@@ -24876,12 +24999,12 @@ fn fieldCallBind(...@@ -24876,12 +24999,12 @@ fn fieldCallBind(
24876 };24999 };
2487725000
24878 const msg = msg: {25001 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) });
24880 errdefer msg.destroy(sema.gpa);25003 errdefer msg.destroy(sema.gpa);
24881 try sema.addDeclaredHereNote(msg, concrete_ty);25004 try sema.addDeclaredHereNote(msg, concrete_ty);
24882 if (found_decl) |decl_idx| {25005 if (found_decl) |decl_idx| {
24883 const decl = mod.declPtr(decl_idx);25006 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)});
24885 }25008 }
24886 break :msg msg;25009 break :msg msg;
24887 };25010 };
...@@ -24933,7 +25056,7 @@ fn namespaceLookup(...@@ -24933,7 +25056,7 @@ fn namespaceLookup(
24933 block: *Block,25056 block: *Block,
24934 src: LazySrcLoc,25057 src: LazySrcLoc,
24935 namespace: Namespace.Index,25058 namespace: Namespace.Index,
24936 decl_name: []const u8,25059 decl_name: InternPool.NullTerminatedString,
24937) CompileError!?Decl.Index {25060) CompileError!?Decl.Index {
24938 const mod = sema.mod;25061 const mod = sema.mod;
24939 const gpa = sema.gpa;25062 const gpa = sema.gpa;
...@@ -24942,7 +25065,7 @@ fn namespaceLookup(...@@ -24942,7 +25065,7 @@ fn namespaceLookup(
24942 if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) {25065 if (!decl.is_pub and decl.getFileScope(mod) != block.getFileScope(mod)) {
24943 const msg = msg: {25066 const msg = msg: {
24944 const msg = try sema.errMsg(block, src, "'{s}' is not marked 'pub'", .{25067 const msg = try sema.errMsg(block, src, "'{s}' is not marked 'pub'", .{
24945 decl_name,25068 mod.intern_pool.stringToSlice(decl_name),
24946 });25069 });
24947 errdefer msg.destroy(gpa);25070 errdefer msg.destroy(gpa);
24948 try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "declared here", .{});25071 try mod.errNoteNonLazy(decl.srcLoc(mod), msg, "declared here", .{});
...@@ -24960,7 +25083,7 @@ fn namespaceLookupRef(...@@ -24960,7 +25083,7 @@ fn namespaceLookupRef(
24960 block: *Block,25083 block: *Block,
24961 src: LazySrcLoc,25084 src: LazySrcLoc,
24962 namespace: Namespace.Index,25085 namespace: Namespace.Index,
24963 decl_name: []const u8,25086 decl_name: InternPool.NullTerminatedString,
24964) CompileError!?Air.Inst.Ref {25087) CompileError!?Air.Inst.Ref {
24965 const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null;25088 const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null;
24966 try sema.addReferencedBy(block, src, decl);25089 try sema.addReferencedBy(block, src, decl);
...@@ -24972,7 +25095,7 @@ fn namespaceLookupVal(...@@ -24972,7 +25095,7 @@ fn namespaceLookupVal(
24972 block: *Block,25095 block: *Block,
24973 src: LazySrcLoc,25096 src: LazySrcLoc,
24974 namespace: Namespace.Index,25097 namespace: Namespace.Index,
24975 decl_name: []const u8,25098 decl_name: InternPool.NullTerminatedString,
24976) CompileError!?Air.Inst.Ref {25099) CompileError!?Air.Inst.Ref {
24977 const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null;25100 const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null;
24978 return try sema.analyzeDeclVal(block, src, decl);25101 return try sema.analyzeDeclVal(block, src, decl);
...@@ -24983,7 +25106,7 @@ fn structFieldPtr(...@@ -24983,7 +25106,7 @@ fn structFieldPtr(
24983 block: *Block,25106 block: *Block,
24984 src: LazySrcLoc,25107 src: LazySrcLoc,
24985 struct_ptr: Air.Inst.Ref,25108 struct_ptr: Air.Inst.Ref,
24986 field_name: []const u8,25109 field_name: InternPool.NullTerminatedString,
24987 field_name_src: LazySrcLoc,25110 field_name_src: LazySrcLoc,
24988 unresolved_struct_ty: Type,25111 unresolved_struct_ty: Type,
24989 initializing: bool,25112 initializing: bool,
...@@ -24995,7 +25118,7 @@ fn structFieldPtr(...@@ -24995,7 +25118,7 @@ fn structFieldPtr(
24995 try sema.resolveStructLayout(struct_ty);25118 try sema.resolveStructLayout(struct_ty);
2499625119
24997 if (struct_ty.isTuple(mod)) {25120 if (struct_ty.isTuple(mod)) {
24998 if (mem.eql(u8, field_name, "len")) {25121 if (mod.intern_pool.stringEqlSlice(field_name, "len")) {
24999 const len_inst = try sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount(mod));25122 const len_inst = try sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount(mod));
25000 return sema.analyzeRef(block, src, len_inst);25123 return sema.analyzeRef(block, src, len_inst);
25001 }25124 }
...@@ -25101,7 +25224,7 @@ fn structFieldPtrByIndex(...@@ -25101,7 +25224,7 @@ fn structFieldPtrByIndex(
25101 if (field.is_comptime) {25224 if (field.is_comptime) {
25102 const val = try mod.intern(.{ .ptr = .{25225 const val = try mod.intern(.{ .ptr = .{
25103 .ty = ptr_field_ty.toIntern(),25226 .ty = ptr_field_ty.toIntern(),
25104 .addr = .{ .comptime_field = try field.default_val.intern(field.ty, mod) },25227 .addr = .{ .comptime_field = field.default_val },
25105 } });25228 } });
25106 return sema.addConstant(ptr_field_ty, val.toValue());25229 return sema.addConstant(ptr_field_ty, val.toValue());
25107 }25230 }
...@@ -25126,7 +25249,7 @@ fn structFieldVal(...@@ -25126,7 +25249,7 @@ fn structFieldVal(
25126 block: *Block,25249 block: *Block,
25127 src: LazySrcLoc,25250 src: LazySrcLoc,
25128 struct_byval: Air.Inst.Ref,25251 struct_byval: Air.Inst.Ref,
25129 field_name: []const u8,25252 field_name: InternPool.NullTerminatedString,
25130 field_name_src: LazySrcLoc,25253 field_name_src: LazySrcLoc,
25131 unresolved_struct_ty: Type,25254 unresolved_struct_ty: Type,
25132) CompileError!Air.Inst.Ref {25255) CompileError!Air.Inst.Ref {
...@@ -25145,7 +25268,7 @@ fn structFieldVal(...@@ -25145,7 +25268,7 @@ fn structFieldVal(
25145 const field = struct_obj.fields.values()[field_index];25268 const field = struct_obj.fields.values()[field_index];
2514625269
25147 if (field.is_comptime) {25270 if (field.is_comptime) {
25148 return sema.addConstant(field.ty, field.default_val);25271 return sema.addConstant(field.ty, field.default_val.toValue());
25149 }25272 }
2515025273
25151 if (try sema.resolveMaybeUndefVal(struct_byval)) |struct_val| {25274 if (try sema.resolveMaybeUndefVal(struct_byval)) |struct_val| {
...@@ -25176,12 +25299,12 @@ fn tupleFieldVal(...@@ -25176,12 +25299,12 @@ fn tupleFieldVal(
25176 block: *Block,25299 block: *Block,
25177 src: LazySrcLoc,25300 src: LazySrcLoc,
25178 tuple_byval: Air.Inst.Ref,25301 tuple_byval: Air.Inst.Ref,
25179 field_name: []const u8,25302 field_name: InternPool.NullTerminatedString,
25180 field_name_src: LazySrcLoc,25303 field_name_src: LazySrcLoc,
25181 tuple_ty: Type,25304 tuple_ty: Type,
25182) CompileError!Air.Inst.Ref {25305) CompileError!Air.Inst.Ref {
25183 const mod = sema.mod;25306 const mod = sema.mod;
25184 if (mem.eql(u8, field_name, "len")) {25307 if (mod.intern_pool.stringEqlSlice(field_name, "len")) {
25185 return sema.addIntUnsigned(Type.usize, tuple_ty.structFieldCount(mod));25308 return sema.addIntUnsigned(Type.usize, tuple_ty.structFieldCount(mod));
25186 }25309 }
25187 const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src);25310 const field_index = try sema.tupleFieldIndex(block, tuple_ty, field_name, field_name_src);
...@@ -25193,11 +25316,12 @@ fn tupleFieldIndex(...@@ -25193,11 +25316,12 @@ fn tupleFieldIndex(
25193 sema: *Sema,25316 sema: *Sema,
25194 block: *Block,25317 block: *Block,
25195 tuple_ty: Type,25318 tuple_ty: Type,
25196 field_name: []const u8,25319 field_name_ip: InternPool.NullTerminatedString,
25197 field_name_src: LazySrcLoc,25320 field_name_src: LazySrcLoc,
25198) CompileError!u32 {25321) CompileError!u32 {
25199 const mod = sema.mod;25322 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"));
25201 if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| {25325 if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| {
25202 if (field_index < tuple_ty.structFieldCount(mod)) return field_index;25326 if (field_index < tuple_ty.structFieldCount(mod)) return field_index;
25203 return sema.fail(block, field_name_src, "index '{s}' out of bounds of tuple '{}'", .{25327 return sema.fail(block, field_name_src, "index '{s}' out of bounds of tuple '{}'", .{
...@@ -25253,13 +25377,14 @@ fn unionFieldPtr(...@@ -25253,13 +25377,14 @@ fn unionFieldPtr(
25253 block: *Block,25377 block: *Block,
25254 src: LazySrcLoc,25378 src: LazySrcLoc,
25255 union_ptr: Air.Inst.Ref,25379 union_ptr: Air.Inst.Ref,
25256 field_name: []const u8,25380 field_name: InternPool.NullTerminatedString,
25257 field_name_src: LazySrcLoc,25381 field_name_src: LazySrcLoc,
25258 unresolved_union_ty: Type,25382 unresolved_union_ty: Type,
25259 initializing: bool,25383 initializing: bool,
25260) CompileError!Air.Inst.Ref {25384) CompileError!Air.Inst.Ref {
25261 const arena = sema.arena;25385 const arena = sema.arena;
25262 const mod = sema.mod;25386 const mod = sema.mod;
25387 const ip = &mod.intern_pool;
2526325388
25264 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);25389 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
2526525390
...@@ -25281,7 +25406,9 @@ fn unionFieldPtr(...@@ -25281,7 +25406,9 @@ fn unionFieldPtr(
25281 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});25406 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
25282 errdefer msg.destroy(sema.gpa);25407 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 });
25285 try sema.addDeclaredHereNote(msg, union_ty);25412 try sema.addDeclaredHereNote(msg, union_ty);
25286 break :msg msg;25413 break :msg msg;
25287 };25414 };
...@@ -25296,14 +25423,17 @@ fn unionFieldPtr(...@@ -25296,14 +25423,17 @@ fn unionFieldPtr(
25296 if (union_val.isUndef(mod)) {25423 if (union_val.isUndef(mod)) {
25297 return sema.failWithUseOfUndef(block, src);25424 return sema.failWithUseOfUndef(block, src);
25298 }25425 }
25299 const un = mod.intern_pool.indexToKey(union_val.toIntern()).un;25426 const un = ip.indexToKey(union_val.toIntern()).un;
25300 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);25427 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
25301 const tag_matches = un.tag == field_tag.toIntern();25428 const tag_matches = un.tag == field_tag.toIntern();
25302 if (!tag_matches) {25429 if (!tag_matches) {
25303 const msg = msg: {25430 const msg = msg: {
25304 const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;25431 const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
25305 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);25432 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 });
25307 errdefer msg.destroy(sema.gpa);25437 errdefer msg.destroy(sema.gpa);
25308 try sema.addDeclaredHereNote(msg, union_ty);25438 try sema.addDeclaredHereNote(msg, union_ty);
25309 break :msg msg;25439 break :msg msg;
...@@ -25345,11 +25475,12 @@ fn unionFieldVal(...@@ -25345,11 +25475,12 @@ fn unionFieldVal(
25345 block: *Block,25475 block: *Block,
25346 src: LazySrcLoc,25476 src: LazySrcLoc,
25347 union_byval: Air.Inst.Ref,25477 union_byval: Air.Inst.Ref,
25348 field_name: []const u8,25478 field_name: InternPool.NullTerminatedString,
25349 field_name_src: LazySrcLoc,25479 field_name_src: LazySrcLoc,
25350 unresolved_union_ty: Type,25480 unresolved_union_ty: Type,
25351) CompileError!Air.Inst.Ref {25481) CompileError!Air.Inst.Ref {
25352 const mod = sema.mod;25482 const mod = sema.mod;
25483 const ip = &mod.intern_pool;
25353 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);25484 assert(unresolved_union_ty.zigTypeTag(mod) == .Union);
2535425485
25355 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);25486 const union_ty = try sema.resolveTypeFields(unresolved_union_ty);
...@@ -25361,7 +25492,7 @@ fn unionFieldVal(...@@ -25361,7 +25492,7 @@ fn unionFieldVal(
25361 if (try sema.resolveMaybeUndefVal(union_byval)) |union_val| {25492 if (try sema.resolveMaybeUndefVal(union_byval)) |union_val| {
25362 if (union_val.isUndef(mod)) return sema.addConstUndef(field.ty);25493 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;
25365 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);25496 const field_tag = try mod.enumValueFieldIndex(union_obj.tag_ty, enum_field_index);
25366 const tag_matches = un.tag == field_tag.toIntern();25497 const tag_matches = un.tag == field_tag.toIntern();
25367 switch (union_obj.layout) {25498 switch (union_obj.layout) {
...@@ -25372,7 +25503,9 @@ fn unionFieldVal(...@@ -25372,7 +25503,9 @@ fn unionFieldVal(
25372 const msg = msg: {25503 const msg = msg: {
25373 const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;25504 const active_index = union_obj.tag_ty.enumTagFieldIndex(un.tag.toValue(), mod).?;
25374 const active_field_name = union_obj.tag_ty.enumFieldName(active_index, mod);25505 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 });
25376 errdefer msg.destroy(sema.gpa);25509 errdefer msg.destroy(sema.gpa);
25377 try sema.addDeclaredHereNote(msg, union_ty);25510 try sema.addDeclaredHereNote(msg, union_ty);
25378 break :msg msg;25511 break :msg msg;
...@@ -26470,14 +26603,13 @@ fn coerceExtra(...@@ -26470,14 +26603,13 @@ fn coerceExtra(
26470 // enum literal to enum26603 // enum literal to enum
26471 const val = try sema.resolveConstValue(block, .unneeded, inst, "");26604 const val = try sema.resolveConstValue(block, .unneeded, inst, "");
26472 const string = mod.intern_pool.indexToKey(val.toIntern()).enum_literal;26605 const string = mod.intern_pool.indexToKey(val.toIntern()).enum_literal;
26473 const bytes = mod.intern_pool.stringToSlice(string);26606 const field_index = dest_ty.enumFieldIndex(string, mod) orelse {
26474 const field_index = dest_ty.enumFieldIndex(bytes, mod) orelse {
26475 const msg = msg: {26607 const msg = msg: {
26476 const msg = try sema.errMsg(26608 const msg = try sema.errMsg(
26477 block,26609 block,
26478 inst_src,26610 inst_src,
26479 "no field named '{s}' in enum '{}'",26611 "no field named '{s}' in enum '{}'",
26480 .{ bytes, dest_ty.fmt(mod) },26612 .{ mod.intern_pool.stringToSlice(string), dest_ty.fmt(mod) },
26481 );26613 );
26482 errdefer msg.destroy(sema.gpa);26614 errdefer msg.destroy(sema.gpa);
26483 try sema.addDeclaredHereNote(msg, dest_ty);26615 try sema.addDeclaredHereNote(msg, dest_ty);
...@@ -27876,10 +28008,7 @@ fn storePtrVal(...@@ -27876,10 +28008,7 @@ fn storePtrVal(
27876 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{mut_kit.ty.fmt(mod)}),28008 error.Unimplemented => return sema.fail(block, src, "TODO: implement writeToMemory for type '{}'", .{mut_kit.ty.fmt(mod)}),
27877 };28009 };
2787828010
27879 const arena = mut_kit.beginArena(mod);28011 reinterpret.val_ptr.* = (try (try Value.readFromMemory(mut_kit.ty, mod, buffer, sema.arena)).intern(mut_kit.ty, mod)).toValue();
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();
27883 },28012 },
27884 .bad_decl_ty, .bad_ptr_ty => {28013 .bad_decl_ty, .bad_ptr_ty => {
27885 // TODO show the decl declaration site in a note and explain whether the decl28014 // TODO show the decl declaration site in a note and explain whether the decl
...@@ -27913,18 +28042,6 @@ const ComptimePtrMutationKit = struct {...@@ -27913,18 +28042,6 @@ const ComptimePtrMutationKit = struct {
27913 bad_ptr_ty,28042 bad_ptr_ty,
27914 },28043 },
27915 ty: Type,28044 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 }
27928};28045};
2792928046
27930fn beginComptimePtrMutation(28047fn beginComptimePtrMutation(
...@@ -27966,10 +28083,8 @@ fn beginComptimePtrMutation(...@@ -27966,10 +28083,8 @@ fn beginComptimePtrMutation(
27966 // An error union has been initialized to undefined at comptime and now we28083 // An error union has been initialized to undefined at comptime and now we
27967 // are for the first time setting the payload. We must change the28084 // are for the first time setting the payload. We must change the
27968 // representation of the error union from `undef` to `opt_payload`.28085 // 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);
27973 payload.* = .{28088 payload.* = .{
27974 .base = .{ .tag = .eu_payload },28089 .base = .{ .tag = .eu_payload },
27975 .data = (try mod.intern(.{ .undef = payload_ty.toIntern() })).toValue(),28090 .data = (try mod.intern(.{ .undef = payload_ty.toIntern() })).toValue(),
...@@ -28019,10 +28134,8 @@ fn beginComptimePtrMutation(...@@ -28019,10 +28134,8 @@ fn beginComptimePtrMutation(
28019 // An optional has been initialized to undefined at comptime and now we28134 // An optional has been initialized to undefined at comptime and now we
28020 // are for the first time setting the payload. We must change the28135 // are for the first time setting the payload. We must change the
28021 // representation of the optional from `undef` to `opt_payload`.28136 // 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);
28026 payload.* = .{28139 payload.* = .{
28027 .base = .{ .tag = .opt_payload },28140 .base = .{ .tag = .opt_payload },
28028 .data = payload_val.toValue(),28141 .data = payload_val.toValue(),
...@@ -28088,8 +28201,7 @@ fn beginComptimePtrMutation(...@@ -28088,8 +28201,7 @@ fn beginComptimePtrMutation(
28088 // If we wanted to avoid this, there would need to be special detection28201 // If we wanted to avoid this, there would need to be special detection
28089 // elsewhere to identify when writing a value to an array element that is stored28202 // elsewhere to identify when writing a value to an array element that is stored
28090 // using the `bytes` tag, and handle it without making a call to this function.28203 // using the `bytes` tag, and handle it without making a call to this function.
28091 const arena = parent.beginArena(sema.mod);28204 const arena = sema.arena;
28092 defer parent.finishArena(sema.mod);
2809328205
28094 const bytes = val_ptr.castTag(.bytes).?.data;28206 const bytes = val_ptr.castTag(.bytes).?.data;
28095 const dest_len = parent.ty.arrayLenIncludingSentinel(mod);28207 const dest_len = parent.ty.arrayLenIncludingSentinel(mod);
...@@ -28121,8 +28233,7 @@ fn beginComptimePtrMutation(...@@ -28121,8 +28233,7 @@ fn beginComptimePtrMutation(
28121 // need to be special detection elsewhere to identify when writing a value to an28233 // need to be special detection elsewhere to identify when writing a value to an
28122 // array element that is stored using the `repeated` tag, and handle it28234 // array element that is stored using the `repeated` tag, and handle it
28123 // without making a call to this function.28235 // without making a call to this function.
28124 const arena = parent.beginArena(sema.mod);28236 const arena = sema.arena;
28125 defer parent.finishArena(sema.mod);
2812628237
28127 const repeated_val = try val_ptr.castTag(.repeated).?.data.copy(arena);28238 const repeated_val = try val_ptr.castTag(.repeated).?.data.copy(arena);
28128 const array_len_including_sentinel =28239 const array_len_including_sentinel =
...@@ -28163,8 +28274,7 @@ fn beginComptimePtrMutation(...@@ -28163,8 +28274,7 @@ fn beginComptimePtrMutation(
28163 // An array has been initialized to undefined at comptime and now we28274 // An array has been initialized to undefined at comptime and now we
28164 // are for the first time setting an element. We must change the representation28275 // are for the first time setting an element. We must change the representation
28165 // of the array from `undef` to `array`.28276 // of the array from `undef` to `array`.
28166 const arena = parent.beginArena(sema.mod);28277 const arena = sema.arena;
28167 defer parent.finishArena(sema.mod);
2816828278
28169 const array_len_including_sentinel =28279 const array_len_including_sentinel =
28170 try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod));28280 try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod));
...@@ -28261,8 +28371,7 @@ fn beginComptimePtrMutation(...@@ -28261,8 +28371,7 @@ fn beginComptimePtrMutation(
28261 parent.mut_decl,28371 parent.mut_decl,
28262 ),28372 ),
28263 .repeated => {28373 .repeated => {
28264 const arena = parent.beginArena(sema.mod);28374 const arena = sema.arena;
28265 defer parent.finishArena(sema.mod);
2826628375
28267 const elems = try arena.alloc(Value, parent.ty.structFieldCount(mod));28376 const elems = try arena.alloc(Value, parent.ty.structFieldCount(mod));
28268 @memset(elems, val_ptr.castTag(.repeated).?.data);28377 @memset(elems, val_ptr.castTag(.repeated).?.data);
...@@ -28325,8 +28434,7 @@ fn beginComptimePtrMutation(...@@ -28325,8 +28434,7 @@ fn beginComptimePtrMutation(
28325 // A struct or union has been initialized to undefined at comptime and now we28434 // A struct or union has been initialized to undefined at comptime and now we
28326 // are for the first time setting a field. We must change the representation28435 // are for the first time setting a field. We must change the representation
28327 // of the struct/union from `undef` to `struct`/`union`.28436 // of the struct/union from `undef` to `struct`/`union`.
28328 const arena = parent.beginArena(sema.mod);28437 const arena = sema.arena;
28329 defer parent.finishArena(sema.mod);
2833028438
28331 switch (parent.ty.zigTypeTag(mod)) {28439 switch (parent.ty.zigTypeTag(mod)) {
28332 .Struct => {28440 .Struct => {
...@@ -28436,11 +28544,7 @@ fn beginComptimePtrMutationInner(...@@ -28436,11 +28544,7 @@ fn beginComptimePtrMutationInner(
28436 const target = mod.getTarget();28544 const target = mod.getTarget();
28437 const coerce_ok = (try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_ty, true, target, src, src)) == .ok;28545 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);28547 decl_val.* = try decl_val.unintern(sema.arena, mod);
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);
2844428548
28445 if (coerce_ok) {28549 if (coerce_ok) {
28446 return ComptimePtrMutationKit{28550 return ComptimePtrMutationKit{
...@@ -28928,6 +29032,7 @@ fn coerceEnumToUnion(...@@ -28928,6 +29032,7 @@ fn coerceEnumToUnion(
28928 inst_src: LazySrcLoc,29032 inst_src: LazySrcLoc,
28929) !Air.Inst.Ref {29033) !Air.Inst.Ref {
28930 const mod = sema.mod;29034 const mod = sema.mod;
29035 const ip = &mod.intern_pool;
28931 const inst_ty = sema.typeOf(inst);29036 const inst_ty = sema.typeOf(inst);
2893229037
28933 const tag_ty = union_ty.unionTagType(mod) orelse {29038 const tag_ty = union_ty.unionTagType(mod) orelse {
...@@ -28966,7 +29071,9 @@ fn coerceEnumToUnion(...@@ -28966,7 +29071,9 @@ fn coerceEnumToUnion(
28966 errdefer msg.destroy(sema.gpa);29071 errdefer msg.destroy(sema.gpa);
2896729072
28968 const field_name = union_obj.fields.keys()[field_index];29073 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 });
28970 try sema.addDeclaredHereNote(msg, union_ty);29077 try sema.addDeclaredHereNote(msg, union_ty);
28971 break :msg msg;29078 break :msg msg;
28972 };29079 };
...@@ -28976,11 +29083,14 @@ fn coerceEnumToUnion(...@@ -28976,11 +29083,14 @@ fn coerceEnumToUnion(
28976 const msg = msg: {29083 const msg = msg: {
28977 const field_name = union_obj.fields.keys()[field_index];29084 const field_name = union_obj.fields.keys()[field_index];
28978 const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{s}'", .{29085 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),
28980 });29088 });
28981 errdefer msg.destroy(sema.gpa);29089 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 });
28984 try sema.addDeclaredHereNote(msg, union_ty);29094 try sema.addDeclaredHereNote(msg, union_ty);
28985 break :msg msg;29095 break :msg msg;
28986 };29096 };
...@@ -29049,7 +29159,10 @@ fn coerceEnumToUnion(...@@ -29049,7 +29159,10 @@ fn coerceEnumToUnion(
29049 const field_name = field.key_ptr.*;29159 const field_name = field.key_ptr.*;
29050 const field_ty = field.value_ptr.ty;29160 const field_ty = field.value_ptr.ty;
29051 if (!(try sema.typeHasRuntimeBits(field_ty))) continue;29161 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 });
29053 }29166 }
29054 try sema.addDeclaredHereNote(msg, union_ty);29167 try sema.addDeclaredHereNote(msg, union_ty);
29055 break :msg msg;29168 break :msg msg;
...@@ -29068,11 +29181,11 @@ fn coerceAnonStructToUnion(...@@ -29068,11 +29181,11 @@ fn coerceAnonStructToUnion(
29068 const mod = sema.mod;29181 const mod = sema.mod;
29069 const inst_ty = sema.typeOf(inst);29182 const inst_ty = sema.typeOf(inst);
29070 const field_info: union(enum) {29183 const field_info: union(enum) {
29071 name: []const u8,29184 name: InternPool.NullTerminatedString,
29072 count: usize,29185 count: usize,
29073 } = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {29186 } = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
29074 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 1)29187 .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] }
29076 else29189 else
29077 .{ .count = anon_struct_type.names.len },29190 .{ .count = anon_struct_type.names.len },
29078 .struct_type => |struct_type| name: {29191 .struct_type => |struct_type| name: {
...@@ -29335,6 +29448,7 @@ fn coerceTupleToStruct(...@@ -29335,6 +29448,7 @@ fn coerceTupleToStruct(
29335 inst_src: LazySrcLoc,29448 inst_src: LazySrcLoc,
29336) !Air.Inst.Ref {29449) !Air.Inst.Ref {
29337 const mod = sema.mod;29450 const mod = sema.mod;
29451 const ip = &mod.intern_pool;
29338 const struct_ty = try sema.resolveTypeFields(dest_ty);29452 const struct_ty = try sema.resolveTypeFields(dest_ty);
2933929453
29340 if (struct_ty.isTupleOrAnonStruct(mod)) {29454 if (struct_ty.isTupleOrAnonStruct(mod)) {
...@@ -29348,7 +29462,7 @@ fn coerceTupleToStruct(...@@ -29348,7 +29462,7 @@ fn coerceTupleToStruct(
2934829462
29349 const inst_ty = sema.typeOf(inst);29463 const inst_ty = sema.typeOf(inst);
29350 var runtime_src: ?LazySrcLoc = null;29464 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())) {
29352 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,29466 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
29353 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|29467 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|
29354 struct_obj.fields.count()29468 struct_obj.fields.count()
...@@ -29360,11 +29474,11 @@ fn coerceTupleToStruct(...@@ -29360,11 +29474,11 @@ fn coerceTupleToStruct(
29360 const field_i = @intCast(u32, field_index_usize);29474 const field_i = @intCast(u32, field_index_usize);
29361 const field_src = inst_src; // TODO better source location29475 const field_src = inst_src; // TODO better source location
29362 // https://github.com/ziglang/zig/issues/1570929476 // 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())) {
29364 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)29478 .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]
29366 else29480 else
29367 try std.fmt.allocPrint(sema.arena, "{d}", .{field_i}),29481 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
29368 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],29482 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
29369 else => unreachable,29483 else => unreachable,
29370 };29484 };
...@@ -29378,7 +29492,7 @@ fn coerceTupleToStruct(...@@ -29378,7 +29492,7 @@ fn coerceTupleToStruct(
29378 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known");29492 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known");
29379 };29493 };
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)) {
29382 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i);29496 return sema.failWithInvalidComptimeFieldStore(block, field_src, inst_ty, field_i);
29383 }29497 }
29384 }29498 }
...@@ -29401,9 +29515,9 @@ fn coerceTupleToStruct(...@@ -29401,9 +29515,9 @@ fn coerceTupleToStruct(
29401 const field_name = fields.keys()[i];29515 const field_name = fields.keys()[i];
29402 const field = fields.values()[i];29516 const field = fields.values()[i];
29403 const field_src = inst_src; // TODO better source location29517 const field_src = inst_src; // TODO better source location
29404 if (field.default_val.toIntern() == .unreachable_value) {29518 if (field.default_val == .none) {
29405 const template = "missing struct field: {s}";29519 const template = "missing struct field: {s}";
29406 const args = .{field_name};29520 const args = .{ip.stringToSlice(field_name)};
29407 if (root_msg) |msg| {29521 if (root_msg) |msg| {
29408 try sema.errNote(block, field_src, msg, template, args);29522 try sema.errNote(block, field_src, msg, template, args);
29409 } else {29523 } else {
...@@ -29412,9 +29526,9 @@ fn coerceTupleToStruct(...@@ -29412,9 +29526,9 @@ fn coerceTupleToStruct(
29412 continue;29526 continue;
29413 }29527 }
29414 if (runtime_src == null) {29528 if (runtime_src == null) {
29415 field_vals[i] = field.default_val.toIntern();29529 field_vals[i] = field.default_val;
29416 } else {29530 } else {
29417 field_ref.* = try sema.addConstant(field.ty, field.default_val);29531 field_ref.* = try sema.addConstant(field.ty, field.default_val.toValue());
29418 }29532 }
29419 }29533 }
2942029534
...@@ -29433,7 +29547,7 @@ fn coerceTupleToStruct(...@@ -29433,7 +29547,7 @@ fn coerceTupleToStruct(
29433 .ty = struct_ty.toIntern(),29547 .ty = struct_ty.toIntern(),
29434 .storage = .{ .elems = field_vals },29548 .storage = .{ .elems = field_vals },
29435 } });29549 } });
29436 errdefer mod.intern_pool.remove(struct_val);29550 errdefer ip.remove(struct_val);
2943729551
29438 return sema.addConstant(struct_ty, struct_val.toValue());29552 return sema.addConstant(struct_ty, struct_val.toValue());
29439}29553}
...@@ -29446,7 +29560,8 @@ fn coerceTupleToTuple(...@@ -29446,7 +29560,8 @@ fn coerceTupleToTuple(
29446 inst_src: LazySrcLoc,29560 inst_src: LazySrcLoc,
29447) !Air.Inst.Ref {29561) !Air.Inst.Ref {
29448 const mod = sema.mod;29562 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())) {
29450 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,29565 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
29451 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|29566 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|
29452 struct_obj.fields.count()29567 struct_obj.fields.count()
...@@ -29459,7 +29574,7 @@ fn coerceTupleToTuple(...@@ -29459,7 +29574,7 @@ fn coerceTupleToTuple(
29459 @memset(field_refs, .none);29574 @memset(field_refs, .none);
2946029575
29461 const inst_ty = sema.typeOf(inst);29576 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())) {
29463 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,29578 .anon_struct_type => |anon_struct_type| anon_struct_type.types.len,
29464 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|29579 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj|
29465 struct_obj.fields.count()29580 struct_obj.fields.count()
...@@ -29474,30 +29589,26 @@ fn coerceTupleToTuple(...@@ -29474,30 +29589,26 @@ fn coerceTupleToTuple(
29474 const field_i = @intCast(u32, field_index_usize);29589 const field_i = @intCast(u32, field_index_usize);
29475 const field_src = inst_src; // TODO better source location29590 const field_src = inst_src; // TODO better source location
29476 // https://github.com/ziglang/zig/issues/1570929591 // 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())) {
29478 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)29593 .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]
29480 else29595 else
29481 try std.fmt.allocPrint(sema.arena, "{d}", .{field_i}),29596 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
29482 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],29597 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
29483 else => unreachable,29598 else => unreachable,
29484 };29599 };
2948529600
29486 if (mem.eql(u8, field_name, "len")) {29601 if (ip.stringEqlSlice(field_name, "len"))
29487 return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{});29602 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())) {
29491 .anon_struct_type => |anon_struct_type| anon_struct_type.types[field_index_usize].toType(),29605 .anon_struct_type => |anon_struct_type| anon_struct_type.types[field_index_usize].toType(),
29492 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].ty,29606 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].ty,
29493 else => unreachable,29607 else => unreachable,
29494 };29608 };
29495 const default_val = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {29609 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
29496 .anon_struct_type => |anon_struct_type| anon_struct_type.values[field_index_usize],29610 .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()) {29611 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].default_val,
29498 .unreachable_value => .none,
29499 else => |default_val| default_val,
29500 },
29501 else => unreachable,29612 else => unreachable,
29502 };29613 };
2950329614
...@@ -29531,12 +29642,9 @@ fn coerceTupleToTuple(...@@ -29531,12 +29642,9 @@ fn coerceTupleToTuple(
29531 for (field_refs, 0..) |*field_ref, i| {29642 for (field_refs, 0..) |*field_ref, i| {
29532 if (field_ref.* != .none) continue;29643 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())) {
29535 .anon_struct_type => |anon_struct_type| anon_struct_type.values[i],29646 .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()) {29647 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].default_val,
29537 .unreachable_value => .none,
29538 else => |default_val| default_val,
29539 },
29540 else => unreachable,29648 else => unreachable,
29541 };29649 };
2954229650
...@@ -29552,7 +29660,7 @@ fn coerceTupleToTuple(...@@ -29552,7 +29660,7 @@ fn coerceTupleToTuple(
29552 continue;29660 continue;
29553 }29661 }
29554 const template = "missing struct field: {s}";29662 const template = "missing struct field: {s}";
29555 const args = .{tuple_ty.structFieldName(i, mod)};29663 const args = .{ip.stringToSlice(tuple_ty.structFieldName(i, mod))};
29556 if (root_msg) |msg| {29664 if (root_msg) |msg| {
29557 try sema.errNote(block, field_src, msg, template, args);29665 try sema.errNote(block, field_src, msg, template, args);
29558 } else {29666 } else {
...@@ -29563,7 +29671,7 @@ fn coerceTupleToTuple(...@@ -29563,7 +29671,7 @@ fn coerceTupleToTuple(
29563 if (runtime_src == null) {29671 if (runtime_src == null) {
29564 field_vals[i] = default_val;29672 field_vals[i] = default_val;
29565 } else {29673 } else {
29566 const field_ty = switch (mod.intern_pool.indexToKey(tuple_ty.toIntern())) {29674 const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {
29567 .anon_struct_type => |anon_struct_type| anon_struct_type.types[i].toType(),29675 .anon_struct_type => |anon_struct_type| anon_struct_type.types[i].toType(),
29568 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].ty,29676 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].ty,
29569 else => unreachable,29677 else => unreachable,
...@@ -31803,15 +31911,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -31803,15 +31911,7 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
31803 }31911 }
3180431912
31805 if (struct_obj.layout == .Auto and mod.backendSupportsFeature(.field_reordering)) {31913 if (struct_obj.layout == .Auto and mod.backendSupportsFeature(.field_reordering)) {
31806 const optimized_order = if (struct_obj.owner_decl == sema.owner_decl_index)31914 const optimized_order = try mod.tmp_hack_arena.allocator().alloc(u32, struct_obj.fields.count());
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 };
3181531915
31816 for (struct_obj.fields.values(), 0..) |field, i| {31916 for (struct_obj.fields.values(), 0..) |field, i| {
31817 optimized_order[i] = if (try sema.typeHasRuntimeBits(field.ty))31917 optimized_order[i] = if (try sema.typeHasRuntimeBits(field.ty))
...@@ -31852,9 +31952,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi...@@ -31852,9 +31952,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
3185231952
31853 const decl_index = struct_obj.owner_decl;31953 const decl_index = struct_obj.owner_decl;
31854 const decl = mod.declPtr(decl_index);31954 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
31859 const zir = mod.namespacePtr(struct_obj.namespace).file_scope.zir;31956 const zir = mod.namespacePtr(struct_obj.namespace).file_scope.zir;
31860 const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;31957 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...@@ -31880,7 +31977,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
31880 .mod = mod,31977 .mod = mod,
31881 .gpa = gpa,31978 .gpa = gpa,
31882 .arena = analysis_arena.allocator(),31979 .arena = analysis_arena.allocator(),
31883 .perm_arena = decl_arena_allocator,
31884 .code = zir,31980 .code = zir,
31885 .owner_decl = decl,31981 .owner_decl = decl,
31886 .owner_decl_index = decl_index,31982 .owner_decl_index = decl_index,
...@@ -31936,7 +32032,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi...@@ -31936,7 +32032,6 @@ fn semaBackingIntType(mod: *Module, struct_obj: *Module.Struct) CompileError!voi
31936 .mod = mod,32032 .mod = mod,
31937 .gpa = gpa,32033 .gpa = gpa,
31938 .arena = undefined,32034 .arena = undefined,
31939 .perm_arena = decl_arena_allocator,
31940 .code = zir,32035 .code = zir,
31941 .owner_decl = decl,32036 .owner_decl = decl,
31942 .owner_decl_index = decl_index,32037 .owner_decl_index = decl_index,
...@@ -32581,6 +32676,7 @@ fn resolveInferredErrorSetTy(...@@ -32581,6 +32676,7 @@ fn resolveInferredErrorSetTy(
3258132676
32582fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void {32677fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void {
32583 const gpa = mod.gpa;32678 const gpa = mod.gpa;
32679 const ip = &mod.intern_pool;
32584 const decl_index = struct_obj.owner_decl;32680 const decl_index = struct_obj.owner_decl;
32585 const zir = mod.namespacePtr(struct_obj.namespace).file_scope.zir;32681 const zir = mod.namespacePtr(struct_obj.namespace).file_scope.zir;
32586 const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;32682 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...@@ -32628,9 +32724,6 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32628 }32724 }
3262932725
32630 const decl = mod.declPtr(decl_index);32726 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
32635 var analysis_arena = std.heap.ArenaAllocator.init(gpa);32728 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
32636 defer analysis_arena.deinit();32729 defer analysis_arena.deinit();
...@@ -32642,7 +32735,6 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32642,7 +32735,6 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32642 .mod = mod,32735 .mod = mod,
32643 .gpa = gpa,32736 .gpa = gpa,
32644 .arena = analysis_arena.allocator(),32737 .arena = analysis_arena.allocator(),
32645 .perm_arena = decl_arena_allocator,
32646 .code = zir,32738 .code = zir,
32647 .owner_decl = decl,32739 .owner_decl = decl,
32648 .owner_decl_index = decl_index,32740 .owner_decl_index = decl_index,
...@@ -32674,7 +32766,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32674,7 +32766,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32674 }32766 }
3267532767
32676 struct_obj.fields = .{};32768 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
32679 const Field = struct {32771 const Field = struct {
32680 type_body_len: u32 = 0,32772 type_body_len: u32 = 0,
...@@ -32725,16 +32817,15 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32725,16 +32817,15 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32725 extra_index += 1;32817 extra_index += 1;
3272632818
32727 // This string needs to outlive the ZIR code.32819 // This string needs to outlive the ZIR code.
32728 const field_name = if (field_name_zir) |some|32820 const field_name = try ip.getOrPutString(gpa, if (field_name_zir) |s| s else try std.fmt.allocPrint(sema.arena, "{d}", .{
32729 try decl_arena_allocator.dupe(u8, some)32821 field_i,
32730 else32822 }));
32731 try std.fmt.allocPrint(decl_arena_allocator, "{d}", .{field_i});
3273232823
32733 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);32824 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
32734 if (gop.found_existing) {32825 if (gop.found_existing) {
32735 const msg = msg: {32826 const msg = msg: {
32736 const field_src = mod.fieldSrcLoc(struct_obj.owner_decl, .{ .index = field_i }).lazy;32827 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)});
32738 errdefer msg.destroy(gpa);32829 errdefer msg.destroy(gpa);
3273932830
32740 const prev_field_index = struct_obj.fields.getIndex(field_name).?;32831 const prev_field_index = struct_obj.fields.getIndex(field_name).?;
...@@ -32748,7 +32839,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32748,7 +32839,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32748 gop.value_ptr.* = .{32839 gop.value_ptr.* = .{
32749 .ty = Type.noreturn,32840 .ty = Type.noreturn,
32750 .abi_align = 0,32841 .abi_align = 0,
32751 .default_val = Value.@"unreachable",32842 .default_val = .none,
32752 .is_comptime = is_comptime,32843 .is_comptime = is_comptime,
32753 .offset = undefined,32844 .offset = undefined,
32754 };32845 };
...@@ -32917,7 +33008,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void...@@ -32917,7 +33008,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
32917 }).lazy;33008 }).lazy;
32918 return sema.failWithNeededComptime(&block_scope, init_src, "struct field default value must be comptime-known");33009 return sema.failWithNeededComptime(&block_scope, init_src, "struct field default value must be comptime-known");
32919 };33010 };
32920 field.default_val = try default_val.copy(decl_arena_allocator);33011 field.default_val = try default_val.intern(field.ty, mod);
32921 }33012 }
32922 }33013 }
32923 }33014 }
...@@ -32935,6 +33026,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32935,6 +33026,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32935 defer tracy.end();33026 defer tracy.end();
3293633027
32937 const gpa = mod.gpa;33028 const gpa = mod.gpa;
33029 const ip = &mod.intern_pool;
32938 const decl_index = union_obj.owner_decl;33030 const decl_index = union_obj.owner_decl;
32939 const zir = mod.namespacePtr(union_obj.namespace).file_scope.zir;33031 const zir = mod.namespacePtr(union_obj.namespace).file_scope.zir;
32940 const extended = zir.instructions.items(.data)[union_obj.zir_index].extended;33032 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 {...@@ -32978,9 +33070,6 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32978 extra_index += body.len;33070 extra_index += body.len;
3297933071
32980 const decl = mod.declPtr(decl_index);33072 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
32985 var analysis_arena = std.heap.ArenaAllocator.init(gpa);33074 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
32986 defer analysis_arena.deinit();33075 defer analysis_arena.deinit();
...@@ -32992,7 +33081,6 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -32992,7 +33081,6 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
32992 .mod = mod,33081 .mod = mod,
32993 .gpa = gpa,33082 .gpa = gpa,
32994 .arena = analysis_arena.allocator(),33083 .arena = analysis_arena.allocator(),
32995 .perm_arena = decl_arena_allocator,
32996 .code = zir,33084 .code = zir,
32997 .owner_decl = decl,33085 .owner_decl = decl,
32998 .owner_decl_index = decl_index,33086 .owner_decl_index = decl_index,
...@@ -33033,7 +33121,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -33033,7 +33121,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
33033 try ct_decl.intern(mod);33121 try ct_decl.intern(mod);
33034 }33122 }
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
33038 var int_tag_ty: Type = undefined;33126 var int_tag_ty: Type = undefined;
33039 var enum_field_names: []InternPool.NullTerminatedString = &.{};33127 var enum_field_names: []InternPool.NullTerminatedString = &.{};
...@@ -33070,7 +33158,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -33070,7 +33158,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
33070 } else {33158 } else {
33071 // The provided type is the enum tag type.33159 // The provided type is the enum tag type.
33072 union_obj.tag_ty = provided_ty;33160 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())) {
33074 .enum_type => |x| x,33162 .enum_type => |x| x,
33075 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(mod)}),33163 else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(mod)}),
33076 };33164 };
...@@ -33174,10 +33262,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -33174,10 +33262,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
33174 }33262 }
3317533263
33176 // This string needs to outlive the ZIR code.33264 // This string needs to outlive the ZIR code.
33177 const field_name = try decl_arena_allocator.dupe(u8, field_name_zir);33265 const field_name = try ip.getOrPutString(gpa, field_name_zir);
33178 const field_name_ip = try mod.intern_pool.getOrPutString(gpa, field_name);
33179 if (enum_field_names.len != 0) {33266 if (enum_field_names.len != 0) {
33180 enum_field_names[field_i] = field_name_ip;33267 enum_field_names[field_i] = field_name;
33181 }33268 }
3318233269
33183 const field_ty: Type = if (!has_type)33270 const field_ty: Type = if (!has_type)
...@@ -33205,7 +33292,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -33205,7 +33292,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
33205 if (gop.found_existing) {33292 if (gop.found_existing) {
33206 const msg = msg: {33293 const msg = msg: {
33207 const field_src = mod.fieldSrcLoc(union_obj.owner_decl, .{ .index = field_i }).lazy;33294 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 });
33209 errdefer msg.destroy(gpa);33298 errdefer msg.destroy(gpa);
3321033299
33211 const prev_field_index = union_obj.fields.getIndex(field_name).?;33300 const prev_field_index = union_obj.fields.getIndex(field_name).?;
...@@ -33218,14 +33307,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -33218,14 +33307,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
33218 }33307 }
3321933308
33220 if (explicit_enum_info) |tag_info| {33309 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 {
33222 const msg = msg: {33311 const msg = msg: {
33223 const ty_src = mod.fieldSrcLoc(union_obj.owner_decl, .{33312 const ty_src = mod.fieldSrcLoc(union_obj.owner_decl, .{
33224 .index = field_i,33313 .index = field_i,
33225 .range = .type,33314 .range = .type,
33226 }).lazy;33315 }).lazy;
33227 const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{s}' in enum '{}'", .{33316 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),
33229 });33318 });
33230 errdefer msg.destroy(sema.gpa);33319 errdefer msg.destroy(sema.gpa);
33231 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);33320 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
...@@ -33317,7 +33406,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -33317,7 +33406,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
33317 for (tag_info.names, 0..) |field_name, field_index| {33406 for (tag_info.names, 0..) |field_name, field_index| {
33318 if (explicit_tags_seen[field_index]) continue;33407 if (explicit_tags_seen[field_index]) continue;
33319 try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{33408 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),
33321 });33410 });
33322 }33411 }
33323 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);33412 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
...@@ -33345,14 +33434,22 @@ fn generateUnionTagTypeNumbered(...@@ -33345,14 +33434,22 @@ fn generateUnionTagTypeNumbered(
33345 union_obj: *Module.Union,33434 union_obj: *Module.Union,
33346) !Type {33435) !Type {
33347 const mod = sema.mod;33436 const mod = sema.mod;
33437 const gpa = sema.gpa;
33438 const ip = &mod.intern_pool;
3334833439
33349 const src_decl = mod.declPtr(block.src_decl);33440 const src_decl = mod.declPtr(block.src_decl);
33350 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);33441 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
33351 errdefer mod.destroyDecl(new_decl_index);33442 errdefer mod.destroyDecl(new_decl_index);
33352 const name = name: {33443 const name = name: {
33353 const fqn = try union_obj.getFullyQualifiedName(mod);33444 const prefix = "@typeInfo(";
33354 defer sema.gpa.free(fqn);33445 const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod));
33355 break :name try std.fmt.allocPrintZ(sema.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn});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);
33356 };33453 };
33357 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{33454 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{
33358 .ty = Type.type,33455 .ty = Type.type,
...@@ -33390,6 +33487,8 @@ fn generateUnionTagTypeSimple(...@@ -33390,6 +33487,8 @@ fn generateUnionTagTypeSimple(
33390 maybe_union_obj: ?*Module.Union,33487 maybe_union_obj: ?*Module.Union,
33391) !Type {33488) !Type {
33392 const mod = sema.mod;33489 const mod = sema.mod;
33490 const gpa = sema.gpa;
33491 const ip = &mod.intern_pool;
3339333492
33394 const new_decl_index = new_decl_index: {33493 const new_decl_index = new_decl_index: {
33395 const union_obj = maybe_union_obj orelse {33494 const union_obj = maybe_union_obj orelse {
...@@ -33402,9 +33501,15 @@ fn generateUnionTagTypeSimple(...@@ -33402,9 +33501,15 @@ fn generateUnionTagTypeSimple(
33402 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);33501 const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
33403 errdefer mod.destroyDecl(new_decl_index);33502 errdefer mod.destroyDecl(new_decl_index);
33404 const name = name: {33503 const name = name: {
33405 const fqn = try union_obj.getFullyQualifiedName(mod);33504 const prefix = "@typeInfo(";
33406 defer sema.gpa.free(fqn);33505 const fqn = ip.stringToSlice(try union_obj.getFullyQualifiedName(mod));
33407 break :name try std.fmt.allocPrintZ(sema.gpa, "@typeInfo({s}).Union.tag_type.?", .{fqn});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);
33408 };33513 };
33409 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{33514 try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, block.namespace, .{
33410 .ty = Type.type,33515 .ty = Type.type,
...@@ -33436,7 +33541,9 @@ fn generateUnionTagTypeSimple(...@@ -33436,7 +33541,9 @@ fn generateUnionTagTypeSimple(
33436}33541}
3343733542
33438fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {33543fn 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);
33440 defer wip_captures.deinit();33547 defer wip_captures.deinit();
3344133548
33442 var block: Block = .{33549 var block: Block = .{
...@@ -33450,19 +33557,20 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {...@@ -33450,19 +33557,20 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
33450 .is_comptime = true,33557 .is_comptime = true,
33451 };33558 };
33452 defer {33559 defer {
33453 block.instructions.deinit(sema.gpa);33560 block.instructions.deinit(gpa);
33454 block.params.deinit(sema.gpa);33561 block.params.deinit(gpa);
33455 }33562 }
33456 const src = LazySrcLoc.nodeOffset(0);33563 const src = LazySrcLoc.nodeOffset(0);
3345733564
33458 const mod = sema.mod;33565 const mod = sema.mod;
33566 const ip = &mod.intern_pool;
33459 const std_pkg = mod.main_pkg.table.get("std").?;33567 const std_pkg = mod.main_pkg.table.get("std").?;
33460 const std_file = (mod.importPkg(std_pkg) catch unreachable).file;33568 const std_file = (mod.importPkg(std_pkg) catch unreachable).file;
33461 const opt_builtin_inst = (try sema.namespaceLookupRef(33569 const opt_builtin_inst = (try sema.namespaceLookupRef(
33462 &block,33570 &block,
33463 src,33571 src,
33464 mod.declPtr(std_file.root_decl.unwrap().?).src_namespace,33572 mod.declPtr(std_file.root_decl.unwrap().?).src_namespace,
33465 "builtin",33573 try ip.getOrPutString(gpa, "builtin"),
33466 )) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");33574 )) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
33467 const builtin_inst = try sema.analyzeLoad(&block, src, opt_builtin_inst, src);33575 const builtin_inst = try sema.analyzeLoad(&block, src, opt_builtin_inst, src);
33468 const builtin_ty = sema.analyzeAsType(&block, src, builtin_inst) catch |err| switch (err) {33576 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 {...@@ -33473,7 +33581,7 @@ fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
33473 &block,33581 &block,
33474 src,33582 src,
33475 builtin_ty.getNamespaceIndex(mod).unwrap().?,33583 builtin_ty.getNamespaceIndex(mod).unwrap().?,
33476 name,33584 try ip.getOrPutString(gpa, name),
33477 )) orelse std.debug.panic("lib/std/builtin.zig is corrupt and missing '{s}'", .{name});33585 )) orelse std.debug.panic("lib/std/builtin.zig is corrupt and missing '{s}'", .{name});
33478 return sema.analyzeDeclVal(&block, src, opt_ty_decl);33586 return sema.analyzeDeclVal(&block, src, opt_ty_decl);
33479}33587}
...@@ -33608,7 +33716,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -33608,7 +33716,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
33608 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());33716 const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count());
33609 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {33717 for (field_vals, s.fields.values(), 0..) |*field_val, field, i| {
33610 if (field.is_comptime) {33718 if (field.is_comptime) {
33611 field_val.* = try field.default_val.intern(field.ty, mod);33719 field_val.* = field.default_val;
33612 continue;33720 continue;
33613 }33721 }
33614 if (field.ty.eql(resolved_ty, sema.mod)) {33722 if (field.ty.eql(resolved_ty, sema.mod)) {
...@@ -34287,7 +34395,7 @@ fn unionFieldIndex(...@@ -34287,7 +34395,7 @@ fn unionFieldIndex(
34287 sema: *Sema,34395 sema: *Sema,
34288 block: *Block,34396 block: *Block,
34289 unresolved_union_ty: Type,34397 unresolved_union_ty: Type,
34290 field_name: []const u8,34398 field_name: InternPool.NullTerminatedString,
34291 field_src: LazySrcLoc,34399 field_src: LazySrcLoc,
34292) !u32 {34400) !u32 {
34293 const mod = sema.mod;34401 const mod = sema.mod;
...@@ -34302,7 +34410,7 @@ fn structFieldIndex(...@@ -34302,7 +34410,7 @@ fn structFieldIndex(
34302 sema: *Sema,34410 sema: *Sema,
34303 block: *Block,34411 block: *Block,
34304 unresolved_struct_ty: Type,34412 unresolved_struct_ty: Type,
34305 field_name: []const u8,34413 field_name: InternPool.NullTerminatedString,
34306 field_src: LazySrcLoc,34414 field_src: LazySrcLoc,
34307) !u32 {34415) !u32 {
34308 const mod = sema.mod;34416 const mod = sema.mod;
...@@ -34321,19 +34429,17 @@ fn anonStructFieldIndex(...@@ -34321,19 +34429,17 @@ fn anonStructFieldIndex(
34321 sema: *Sema,34429 sema: *Sema,
34322 block: *Block,34430 block: *Block,
34323 struct_ty: Type,34431 struct_ty: Type,
34324 field_name: []const u8,34432 field_name: InternPool.NullTerminatedString,
34325 field_src: LazySrcLoc,34433 field_src: LazySrcLoc,
34326) !u32 {34434) !u32 {
34327 const mod = sema.mod;34435 const mod = sema.mod;
34328 switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {34436 switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
34329 .anon_struct_type => |anon_struct_type| for (anon_struct_type.names, 0..) |name, i| {34437 .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)) {34438 if (name == field_name) return @intCast(u32, i);
34331 return @intCast(u32, i);
34332 }
34333 },34439 },
34334 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {34440 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {
34335 for (struct_obj.fields.keys(), 0..) |name, i| {34441 for (struct_obj.fields.keys(), 0..) |name, i| {
34336 if (mem.eql(u8, name, field_name)) {34442 if (name == field_name) {
34337 return @intCast(u32, i);34443 return @intCast(u32, i);
34338 }34444 }
34339 }34445 }
...@@ -34341,7 +34447,7 @@ fn anonStructFieldIndex(...@@ -34341,7 +34447,7 @@ fn anonStructFieldIndex(
34341 else => unreachable,34447 else => unreachable,
34342 }34448 }
34343 return sema.fail(block, field_src, "no field named '{s}' in anonymous struct '{}'", .{34449 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),
34345 });34451 });
34346}34452}
3434734453
src/TypedValue.zig+14-13
...@@ -201,10 +201,10 @@ pub fn print(...@@ -201,10 +201,10 @@ pub fn print(
201 },201 },
202 .variable => return writer.writeAll("(variable)"),202 .variable => return writer.writeAll("(variable)"),
203 .extern_func => |extern_func| return writer.print("(extern function '{s}')", .{203 .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),
205 }),205 }),
206 .func => |func| return writer.print("(function '{s}')", .{206 .func => |func| return writer.print("(function '{d}')", .{
207 mod.declPtr(mod.funcPtr(func.index).owner_decl).name,207 mod.intern_pool.stringToSlice(mod.declPtr(mod.funcPtr(func.index).owner_decl).name),
208 }),208 }),
209 .int => |int| switch (int.storage) {209 .int => |int| switch (int.storage) {
210 inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),210 inline .u64, .i64, .big_int => |x| return writer.print("{}", .{x}),
...@@ -296,19 +296,20 @@ fn printAggregate(...@@ -296,19 +296,20 @@ fn printAggregate(
296 }296 }
297 if (ty.zigTypeTag(mod) == .Struct) {297 if (ty.zigTypeTag(mod) == .Struct) {
298 try writer.writeAll(".{");298 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;301 for (0..max_len) |i| {
302 while (i < max_len) : (i += 1) {
303 if (i != 0) try writer.writeAll(", ");302 if (i != 0) try writer.writeAll(", ");
304 if (switch (mod.intern_pool.indexToKey(ty.toIntern())) {303
305 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[i],304 const field_name = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
306 .anon_struct_type => |anon_struct_type| if (anon_struct_type.isTuple())305 .struct_type => |x| mod.structPtrUnwrap(x.index).?.fields.keys()[i].toOptional(),
307 null306 .anon_struct_type => |x| if (x.isTuple()) .none else x.names[i].toOptional(),
308 else
309 mod.intern_pool.stringToSlice(anon_struct_type.names[i]),
310 else => unreachable,307 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 });
312 try print(.{313 try print(.{
313 .ty = ty.structFieldType(i, mod),314 .ty = ty.structFieldType(i, mod),
314 .val = try val.fieldValue(mod, i),315 .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...@@ -4350,7 +4350,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4350 .data = .{ .reg = .x30 },4350 .data = .{ .reg = .x30 },
4351 });4351 });
4352 } else if (func_value.getExternFunc(mod)) |extern_func| {4352 } 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);
4354 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);4354 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
4355 if (self.bin_file.cast(link.File.MachO)) |macho_file| {4355 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
4356 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);4356 const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
src/arch/sparc64/CodeGen.zig-2
...@@ -276,8 +276,6 @@ pub fn generate(...@@ -276,8 +276,6 @@ pub fn generate(
276 assert(fn_owner_decl.has_tv);276 assert(fn_owner_decl.has_tv);
277 const fn_type = fn_owner_decl.ty;277 const fn_type = fn_owner_decl.ty;
278278
279 log.debug("fn {s}", .{fn_owner_decl.name});
280
281 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);279 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
282 defer {280 defer {
283 assert(branch_stack.items.len == 1);281 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...@@ -2208,7 +2208,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
2208 const atom = func.bin_file.getAtomPtr(atom_index);2208 const atom = func.bin_file.getAtomPtr(atom_index);
2209 const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);2209 const type_index = try func.bin_file.storeDeclType(extern_func.decl, func_type);
2210 try func.bin_file.addOrUpdateImport(2210 try func.bin_file.addOrUpdateImport(
2211 mem.sliceTo(ext_decl.name, 0),2211 mod.intern_pool.stringToSlice(ext_decl.name),
2212 atom.getSymbolIndex().?,2212 atom.getSymbolIndex().?,
2213 mod.intern_pool.stringToSliceUnwrap(ext_decl.getOwnedExternFunc(mod).?.lib_name),2213 mod.intern_pool.stringToSliceUnwrap(ext_decl.getOwnedExternFunc(mod).?.lib_name),
2214 type_index,2214 type_index,
...@@ -3180,9 +3180,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3180,9 +3180,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3180 }3180 }
3181 },3181 },
3182 .err => |err| {3182 .err => |err| {
3183 const name = mod.intern_pool.stringToSlice(err.name);3183 const int = try mod.getErrorValue(err.name);
3184 const kv = try mod.getErrorValue(name);3184 return WValue{ .imm32 = int };
3185 return WValue{ .imm32 = kv.value };
3186 },3185 },
3187 .error_union => |error_union| {3186 .error_union => |error_union| {
3188 const err_tv: TypedValue = switch (error_union.val) {3187 const err_tv: TypedValue = switch (error_union.val) {
...@@ -3320,18 +3319,15 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {...@@ -3320,18 +3319,15 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3320 .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, mod),3319 .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, mod),
3321 .int => |int| intStorageAsI32(int.storage, mod),3320 .int => |int| intStorageAsI32(int.storage, mod),
3322 .ptr => |ptr| intIndexAsI32(&mod.intern_pool, ptr.addr.int, mod),3321 .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).?)),
3324 else => unreachable,3323 else => unreachable,
3325 },3324 },
3326 }3325 }
33273326
3328 switch (ty.zigTypeTag(mod)) {3327 return switch (ty.zigTypeTag(mod)) {
3329 .ErrorSet => {3328 .ErrorSet => @bitCast(i32, val.getErrorInt(mod)),
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 },
3333 else => unreachable, // Programmer called this function for an illegal type3329 else => unreachable, // Programmer called this function for an illegal type
3334 }3330 };
3335}3331}
33363332
3337fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, mod: *Module) i32 {3333fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, mod: *Module) i32 {
...@@ -6874,8 +6870,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -6874,8 +6870,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
6874 defer arena_allocator.deinit();6870 defer arena_allocator.deinit();
6875 const arena = arena_allocator.allocator();6871 const arena = arena_allocator.allocator();
68766872
6877 const fqn = try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod);6873 const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod));
6878 defer mod.gpa.free(fqn);
6879 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});6874 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
68806875
6881 // check if we already generated code for this.6876 // check if we already generated code for this.
...@@ -7037,9 +7032,8 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7037,9 +7032,8 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
70377032
7038 var lowest: ?u32 = null;7033 var lowest: ?u32 = null;
7039 var highest: ?u32 = null;7034 var highest: ?u32 = null;
7040 for (names) |name_ip| {7035 for (names) |name| {
7041 const name = mod.intern_pool.stringToSlice(name_ip);7036 const err_int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);
7042 const err_int = mod.global_error_set.get(name).?;
7043 if (lowest) |*l| {7037 if (lowest) |*l| {
7044 if (err_int < l.*) {7038 if (err_int < l.*) {
7045 l.* = err_int;7039 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...@@ -8132,7 +8132,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8132 }));8132 }));
8133 } else unreachable;8133 } else unreachable;
8134 } else if (func_value.getExternFunc(mod)) |extern_func| {8134 } 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);
8136 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);8136 const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
8137 if (self.bin_file.cast(link.File.Coff)) |coff_file| {8137 if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8138 const atom_index = try self.owner.getSymbolIndex(self);8138 const atom_index = try self.owner.getSymbolIndex(self);
src/codegen.zig+8-12
...@@ -142,11 +142,12 @@ pub fn generateLazySymbol(...@@ -142,11 +142,12 @@ pub fn generateLazySymbol(
142142
143 if (lazy_sym.ty.isAnyError(mod)) {143 if (lazy_sym.ty.isAnyError(mod)) {
144 alignment.* = 4;144 alignment.* = 4;
145 const err_names = mod.error_name_list.items;145 const err_names = mod.global_error_set.keys();
146 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);146 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(u32, err_names.len), endian);
147 var offset = code.items.len;147 var offset = code.items.len;
148 try code.resize((1 + err_names.len + 1) * 4);148 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);
150 mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);151 mem.writeInt(u32, code.items[offset..][0..4], @intCast(u32, code.items.len), endian);
151 offset += 4;152 offset += 4;
152 try code.ensureUnusedCapacity(err_name.len + 1);153 try code.ensureUnusedCapacity(err_name.len + 1);
...@@ -251,15 +252,13 @@ pub fn generateSymbol(...@@ -251,15 +252,13 @@ pub fn generateSymbol(
251 val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);252 val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
252 },253 },
253 .err => |err| {254 .err => |err| {
254 const name = mod.intern_pool.stringToSlice(err.name);255 const int = try mod.getErrorValue(err.name);
255 const kv = try mod.getErrorValue(name);256 try code.writer().writeInt(u16, @intCast(u16, int), endian);
256 try code.writer().writeInt(u16, @intCast(u16, kv.value), endian);
257 },257 },
258 .error_union => |error_union| {258 .error_union => |error_union| {
259 const payload_ty = typed_value.ty.errorUnionPayload(mod);259 const payload_ty = typed_value.ty.errorUnionPayload(mod);
260
261 const err_val = switch (error_union.val) {260 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)),
263 .payload => @as(u16, 0),262 .payload => @as(u16, 0),
264 };263 };
265264
...@@ -974,11 +973,8 @@ pub fn genTypedValue(...@@ -974,11 +973,8 @@ pub fn genTypedValue(
974 }, owner_decl_index);973 }, owner_decl_index);
975 },974 },
976 .ErrorSet => {975 .ErrorSet => {
977 const err_name = mod.intern_pool.stringToSlice(976 const err_name = mod.intern_pool.indexToKey(typed_value.val.toIntern()).err.name;
978 mod.intern_pool.indexToKey(typed_value.val.toIntern()).err.name,977 const error_index = mod.global_error_set.getIndex(err_name).?;
979 );
980 const global_error_set = mod.global_error_set;
981 const error_index = global_error_set.get(err_name).?;
982 return GenResult.mcv(.{ .immediate = error_index });978 return GenResult.mcv(.{ .immediate = error_index });
983 },979 },
984 .ErrorUnion => {980 .ErrorUnion => {
src/codegen/c.zig+43-29
...@@ -452,6 +452,7 @@ pub const Function = struct {...@@ -452,6 +452,7 @@ pub const Function = struct {
452 var promoted = f.object.dg.ctypes.promote(gpa);452 var promoted = f.object.dg.ctypes.promote(gpa);
453 defer f.object.dg.ctypes.demote(promoted);453 defer f.object.dg.ctypes.demote(promoted);
454 const arena = promoted.arena.allocator();454 const arena = promoted.arena.allocator();
455 const mod = f.object.dg.module;
455456
456 gop.value_ptr.* = .{457 gop.value_ptr.* = .{
457 .fn_name = switch (key) {458 .fn_name = switch (key) {
...@@ -460,7 +461,7 @@ pub const Function = struct {...@@ -460,7 +461,7 @@ pub const Function = struct {
460 .never_inline,461 .never_inline,
461 => |owner_decl| try std.fmt.allocPrint(arena, "zig_{s}_{}__{d}", .{462 => |owner_decl| try std.fmt.allocPrint(arena, "zig_{s}_{}__{d}", .{
462 @tagName(key),463 @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)),
464 @enumToInt(owner_decl),465 @enumToInt(owner_decl),
465 }),466 }),
466 },467 },
...@@ -1465,7 +1466,7 @@ pub const DeclGen = struct {...@@ -1465,7 +1466,7 @@ pub const DeclGen = struct {
1465 try writer.writeAll(" .payload = {");1466 try writer.writeAll(" .payload = {");
1466 }1467 }
1467 if (field_ty.hasRuntimeBits(mod)) {1468 if (field_ty.hasRuntimeBits(mod)) {
1468 try writer.print(" .{ } = ", .{fmtIdent(field_name)});1469 try writer.print(" .{ } = ", .{fmtIdent(mod.intern_pool.stringToSlice(field_name))});
1469 try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type);1470 try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type);
1470 try writer.writeByte(' ');1471 try writer.writeByte(' ');
1471 } else for (ty.unionFields(mod).values()) |field| {1472 } else for (ty.unionFields(mod).values()) |field| {
...@@ -1849,9 +1850,9 @@ pub const DeclGen = struct {...@@ -1849,9 +1850,9 @@ pub const DeclGen = struct {
1849 try mod.markDeclAlive(decl);1850 try mod.markDeclAlive(decl);
18501851
1851 if (mod.decl_exports.get(decl_index)) |exports| {1852 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));
1853 } else if (decl.isExtern(mod)) {1854 } else if (decl.isExtern(mod)) {
1854 try writer.writeAll(mem.span(decl.name));1855 try writer.writeAll(mod.intern_pool.stringToSlice(decl.name));
1855 } else {1856 } else {
1856 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),1857 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
1857 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.1858 // 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(...@@ -1987,7 +1988,7 @@ fn renderTypeName(
1987 try w.print("{s} {s}{}__{d}", .{1988 try w.print("{s} {s}{}__{d}", .{
1988 @tagName(tag)["fwd_".len..],1989 @tagName(tag)["fwd_".len..],
1989 attributes,1990 attributes,
1990 fmtIdent(mem.span(mod.declPtr(owner_decl).name)),1991 fmtIdent(mod.intern_pool.stringToSlice(mod.declPtr(owner_decl).name)),
1991 @enumToInt(owner_decl),1992 @enumToInt(owner_decl),
1992 });1993 });
1993 },1994 },
...@@ -2406,11 +2407,12 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2406,11 +2407,12 @@ pub fn genErrDecls(o: *Object) !void {
2406 try writer.writeAll("enum {\n");2407 try writer.writeAll("enum {\n");
2407 o.indent_writer.pushIndent();2408 o.indent_writer.pushIndent();
2408 var max_name_len: usize = 0;2409 var max_name_len: usize = 0;
2409 for (mod.error_name_list.items[1..], 1..) |name, value| {2410 for (mod.global_error_set.keys()[1..], 1..) |name_nts, value| {
2410 max_name_len = std.math.max(name.len, max_name_len);2411 const name = mod.intern_pool.stringToSlice(name_nts);
2412 max_name_len = @max(name.len, max_name_len);
2411 const err_val = try mod.intern(.{ .err = .{2413 const err_val = try mod.intern(.{ .err = .{
2412 .ty = .anyerror_type,2414 .ty = .anyerror_type,
2413 .name = mod.intern_pool.getString(name).unwrap().?,2415 .name = name_nts,
2414 } });2416 } });
2415 try o.dg.renderValue(writer, Type.anyerror, err_val.toValue(), .Other);2417 try o.dg.renderValue(writer, Type.anyerror, err_val.toValue(), .Other);
2416 try writer.print(" = {d}u,\n", .{value});2418 try writer.print(" = {d}u,\n", .{value});
...@@ -2424,7 +2426,8 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2424,7 +2426,8 @@ pub fn genErrDecls(o: *Object) !void {
2424 defer o.dg.gpa.free(name_buf);2426 defer o.dg.gpa.free(name_buf);
24252427
2426 @memcpy(name_buf[0..name_prefix.len], name_prefix);2428 @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);
2428 @memcpy(name_buf[name_prefix.len..][0..name.len], name);2431 @memcpy(name_buf[name_prefix.len..][0..name.len], name);
2429 const identifier = name_buf[0 .. name_prefix.len + name.len];2432 const identifier = name_buf[0 .. name_prefix.len + name.len];
24302433
...@@ -2446,14 +2449,15 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2446,14 +2449,15 @@ pub fn genErrDecls(o: *Object) !void {
2446 }2449 }
24472450
2448 const name_array_ty = try mod.arrayType(.{2451 const name_array_ty = try mod.arrayType(.{
2449 .len = mod.error_name_list.items.len,2452 .len = mod.global_error_set.count(),
2450 .child = .slice_const_u8_sentinel_0_type,2453 .child = .slice_const_u8_sentinel_0_type,
2451 });2454 });
24522455
2453 try writer.writeAll("static ");2456 try writer.writeAll("static ");
2454 try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, 0, .complete);2457 try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, 0, .complete);
2455 try writer.writeAll(" = {");2458 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);
2457 if (value != 0) try writer.writeByte(',');2461 if (value != 0) try writer.writeByte(',');
24582462
2459 const len_val = try mod.intValue(Type.usize, name.len);2463 const len_val = try mod.intValue(Type.usize, name.len);
...@@ -2469,14 +2473,16 @@ fn genExports(o: *Object) !void {...@@ -2469,14 +2473,16 @@ fn genExports(o: *Object) !void {
2469 const tracy = trace(@src());2473 const tracy = trace(@src());
2470 defer tracy.end();2474 defer tracy.end();
24712475
2476 const mod = o.dg.module;
2477 const ip = &mod.intern_pool;
2472 const fwd_decl_writer = o.dg.fwd_decl.writer();2478 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| {
2474 for (exports.items[1..], 1..) |@"export", i| {2480 for (exports.items[1..], 1..) |@"export", i| {
2475 try fwd_decl_writer.writeAll("zig_export(");2481 try fwd_decl_writer.writeAll("zig_export(");
2476 try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @intCast(u32, i) });2482 try o.dg.renderFunctionSignature(fwd_decl_writer, o.dg.decl_index.unwrap().?, .forward, .{ .export_index = @intCast(u32, i) });
2477 try fwd_decl_writer.print(", {s}, {s});\n", .{2483 try fwd_decl_writer.print(", {s}, {s});\n", .{
2478 fmtStringLiteral(exports.items[0].options.name, null),2484 fmtStringLiteral(ip.stringToSlice(exports.items[0].name), null),
2479 fmtStringLiteral(@"export".options.name, null),2485 fmtStringLiteral(ip.stringToSlice(@"export".name), null),
2480 });2486 });
2481 }2487 }
2482 }2488 }
...@@ -2680,9 +2686,10 @@ pub fn genDecl(o: *Object) !void {...@@ -2680,9 +2686,10 @@ pub fn genDecl(o: *Object) !void {
2680 if (!is_global) try w.writeAll("static ");2686 if (!is_global) try w.writeAll("static ");
2681 if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");2687 if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
2682 if (variable.is_weak_linkage) try w.writeAll("zig_weak_linkage ");2688 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});
2684 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, .{}, decl.@"align", .complete);2691 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)");
2686 try w.writeAll(" = ");2693 try w.writeAll(" = ");
2687 try o.dg.renderValue(w, tv.ty, variable.init.toValue(), .StaticInitializer);2694 try o.dg.renderValue(w, tv.ty, variable.init.toValue(), .StaticInitializer);
2688 try w.writeByte(';');2695 try w.writeByte(';');
...@@ -2697,9 +2704,10 @@ pub fn genDecl(o: *Object) !void {...@@ -2697,9 +2704,10 @@ pub fn genDecl(o: *Object) !void {
26972704
2698 const w = o.writer();2705 const w = o.writer();
2699 if (!is_global) try w.writeAll("static ");2706 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});
2701 try o.dg.renderTypeAndName(w, tv.ty, decl_c_value, Const, decl.@"align", .complete);2709 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)");
2703 try w.writeAll(" = ");2711 try w.writeAll(" = ");
2704 try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);2712 try o.dg.renderValue(w, tv.ty, tv.val, .StaticInitializer);
2705 try w.writeAll(";\n");2713 try w.writeAll(";\n");
...@@ -4229,7 +4237,9 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4229,7 +4237,9 @@ fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue {
4229 const mod = f.object.dg.module;4237 const mod = f.object.dg.module;
4230 const writer = f.object.writer();4238 const writer = f.object.writer();
4231 const function = mod.funcPtr(ty_fn.func);4239 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 });
4233 return .none;4243 return .none;
4234}4244}
42354245
...@@ -5176,6 +5186,7 @@ fn fieldLocation(...@@ -5176,6 +5186,7 @@ fn fieldLocation(
5176 byte_offset: u32,5186 byte_offset: u32,
5177 end: void,5187 end: void,
5178} {5188} {
5189 const ip = &mod.intern_pool;
5179 return switch (container_ty.zigTypeTag(mod)) {5190 return switch (container_ty.zigTypeTag(mod)) {
5180 .Struct => switch (container_ty.containerLayout(mod)) {5191 .Struct => switch (container_ty.containerLayout(mod)) {
5181 .Auto, .Extern => for (field_index..container_ty.structFieldCount(mod)) |next_field_index| {5192 .Auto, .Extern => for (field_index..container_ty.structFieldCount(mod)) |next_field_index| {
...@@ -5186,7 +5197,7 @@ fn fieldLocation(...@@ -5186,7 +5197,7 @@ fn fieldLocation(
5186 break .{ .field = if (container_ty.isSimpleTuple(mod))5197 break .{ .field = if (container_ty.isSimpleTuple(mod))
5187 .{ .field = next_field_index }5198 .{ .field = next_field_index }
5188 else5199 else
5189 .{ .identifier = container_ty.structFieldName(next_field_index, mod) } };5200 .{ .identifier = ip.stringToSlice(container_ty.structFieldName(next_field_index, mod)) } };
5190 } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin,5201 } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin,
5191 .Packed => if (field_ptr_ty.ptrInfo(mod).host_size == 0)5202 .Packed => if (field_ptr_ty.ptrInfo(mod).host_size == 0)
5192 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }5203 .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) }
...@@ -5204,9 +5215,9 @@ fn fieldLocation(...@@ -5204,9 +5215,9 @@ fn fieldLocation(
5204 .begin;5215 .begin;
5205 const field_name = container_ty.unionFields(mod).keys()[field_index];5216 const field_name = container_ty.unionFields(mod).keys()[field_index];
5206 return .{ .field = if (container_ty.unionTagTypeSafety(mod)) |_|5217 return .{ .field = if (container_ty.unionTagTypeSafety(mod)) |_|
5207 .{ .payload_identifier = field_name }5218 .{ .payload_identifier = ip.stringToSlice(field_name) }
5208 else5219 else
5209 .{ .identifier = field_name } };5220 .{ .identifier = ip.stringToSlice(field_name) } };
5210 },5221 },
5211 .Packed => .begin,5222 .Packed => .begin,
5212 },5223 },
...@@ -5347,6 +5358,7 @@ fn fieldPtr(...@@ -5347,6 +5358,7 @@ fn fieldPtr(
53475358
5348fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {5359fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5349 const mod = f.object.dg.module;5360 const mod = f.object.dg.module;
5361 const ip = &mod.intern_pool;
5350 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;5362 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
5351 const extra = f.air.extraData(Air.StructField, ty_pl.payload).data;5363 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 {...@@ -5369,7 +5381,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5369 .Auto, .Extern => if (struct_ty.isSimpleTuple(mod))5381 .Auto, .Extern => if (struct_ty.isSimpleTuple(mod))
5370 .{ .field = extra.field_index }5382 .{ .field = extra.field_index }
5371 else5383 else
5372 .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },5384 .{ .identifier = ip.stringToSlice(struct_ty.structFieldName(extra.field_index, mod)) },
5373 .Packed => {5385 .Packed => {
5374 const struct_obj = mod.typeToStruct(struct_ty).?;5386 const struct_obj = mod.typeToStruct(struct_ty).?;
5375 const int_info = struct_ty.intInfo(mod);5387 const int_info = struct_ty.intInfo(mod);
...@@ -5431,7 +5443,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5431,7 +5443,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5431 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 0)5443 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 0)
5432 .{ .field = extra.field_index }5444 .{ .field = extra.field_index }
5433 else5445 else
5434 .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },5446 .{ .identifier = ip.stringToSlice(struct_ty.structFieldName(extra.field_index, mod)) },
54355447
5436 .union_type => |union_type| field_name: {5448 .union_type => |union_type| field_name: {
5437 const union_obj = mod.unionPtr(union_type.index);5449 const union_obj = mod.unionPtr(union_type.index);
...@@ -5462,9 +5474,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5462,9 +5474,9 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
5462 } else {5474 } else {
5463 const name = union_obj.fields.keys()[extra.field_index];5475 const name = union_obj.fields.keys()[extra.field_index];
5464 break :field_name if (union_type.hasTag()) .{5476 break :field_name if (union_type.hasTag()) .{
5465 .payload_identifier = name,5477 .payload_identifier = ip.stringToSlice(name),
5466 } else .{5478 } else .{
5467 .identifier = name,5479 .identifier = ip.stringToSlice(name),
5468 };5480 };
5469 }5481 }
5470 },5482 },
...@@ -6723,6 +6735,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6723,6 +6735,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
67236735
6724fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {6736fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6725 const mod = f.object.dg.module;6737 const mod = f.object.dg.module;
6738 const ip = &mod.intern_pool;
6726 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;6739 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6727 const inst_ty = f.typeOfIndex(inst);6740 const inst_ty = f.typeOfIndex(inst);
6728 const len = @intCast(usize, inst_ty.arrayLen(mod));6741 const len = @intCast(usize, inst_ty.arrayLen(mod));
...@@ -6773,7 +6786,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6773,7 +6786,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
6773 try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple(mod))6786 try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple(mod))
6774 .{ .field = field_i }6787 .{ .field = field_i }
6775 else6788 else
6776 .{ .identifier = inst_ty.structFieldName(field_i, mod) });6789 .{ .identifier = ip.stringToSlice(inst_ty.structFieldName(field_i, mod)) });
6777 try a.assign(f, writer);6790 try a.assign(f, writer);
6778 try f.writeCValue(writer, element, .Other);6791 try f.writeCValue(writer, element, .Other);
6779 try a.end(f, writer);6792 try a.end(f, writer);
...@@ -6851,6 +6864,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6851,6 +6864,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
68516864
6852fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {6865fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6853 const mod = f.object.dg.module;6866 const mod = f.object.dg.module;
6867 const ip = &mod.intern_pool;
6854 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;6868 const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
6855 const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;6869 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 {...@@ -6886,8 +6900,8 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
6886 try writer.print("{}", .{try f.fmtIntLiteral(tag_ty, int_val)});6900 try writer.print("{}", .{try f.fmtIntLiteral(tag_ty, int_val)});
6887 try a.end(f, writer);6901 try a.end(f, writer);
6888 }6902 }
6889 break :field .{ .payload_identifier = field_name };6903 break :field .{ .payload_identifier = ip.stringToSlice(field_name) };
6890 } else .{ .identifier = field_name };6904 } else .{ .identifier = ip.stringToSlice(field_name) };
68916905
6892 const a = try Assignment.start(f, writer, payload_ty);6906 const a = try Assignment.start(f, writer, payload_ty);
6893 try f.writeCValueMember(writer, local, field);6907 try f.writeCValueMember(writer, local, field);
src/codegen/c/type.zig+15-13
...@@ -1953,11 +1953,11 @@ pub const CType = extern union {...@@ -1953,11 +1953,11 @@ pub const CType = extern union {
1953 .name = try if (ty.isSimpleTuple(mod))1953 .name = try if (ty.isSimpleTuple(mod))
1954 std.fmt.allocPrintZ(arena, "f{}", .{field_i})1954 std.fmt.allocPrintZ(arena, "f{}", .{field_i})
1955 else1955 else
1956 arena.dupeZ(u8, switch (zig_ty_tag) {1956 arena.dupeZ(u8, mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
1957 .Struct => ty.structFieldName(field_i, mod),1957 .Struct => ty.structFieldName(field_i, mod),
1958 .Union => ty.unionFields(mod).keys()[field_i],1958 .Union => ty.unionFields(mod).keys()[field_i],
1959 else => unreachable,1959 else => unreachable,
1960 }),1960 })),
1961 .type = store.set.typeToIndex(field_ty, mod, switch (kind) {1961 .type = store.set.typeToIndex(field_ty, mod, switch (kind) {
1962 .forward, .forward_parameter => .forward,1962 .forward, .forward_parameter => .forward,
1963 .complete, .parameter, .payload => .complete,1963 .complete, .parameter, .payload => .complete,
...@@ -2102,12 +2102,13 @@ pub const CType = extern union {...@@ -2102,12 +2102,13 @@ pub const CType = extern union {
2102 }) or !mem.eql(2102 }) or !mem.eql(
2103 u8,2103 u8,
2104 if (ty.isSimpleTuple(mod))2104 if (ty.isSimpleTuple(mod))
2105 std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable2105 std.fmt.bufPrintZ(&name_buf, "f{}", .{field_i}) catch unreachable
2106 else switch (zig_ty_tag) {2106 else
2107 .Struct => ty.structFieldName(field_i, mod),2107 mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
2108 .Union => ty.unionFields(mod).keys()[field_i],2108 .Struct => ty.structFieldName(field_i, mod),
2109 else => unreachable,2109 .Union => ty.unionFields(mod).keys()[field_i],
2110 },2110 else => unreachable,
2111 }),
2111 mem.span(c_field.name),2112 mem.span(c_field.name),
2112 ) or AlignAs.fieldAlign(ty, field_i, mod).@"align" !=2113 ) or AlignAs.fieldAlign(ty, field_i, mod).@"align" !=
2113 c_field.alignas.@"align") return false;2114 c_field.alignas.@"align") return false;
...@@ -2225,11 +2226,12 @@ pub const CType = extern union {...@@ -2225,11 +2226,12 @@ pub const CType = extern union {
2225 });2226 });
2226 hasher.update(if (ty.isSimpleTuple(mod))2227 hasher.update(if (ty.isSimpleTuple(mod))
2227 std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable2228 std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable
2228 else switch (zig_ty_tag) {2229 else
2229 .Struct => ty.structFieldName(field_i, mod),2230 mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
2230 .Union => ty.unionFields(mod).keys()[field_i],2231 .Struct => ty.structFieldName(field_i, mod),
2231 else => unreachable,2232 .Union => ty.unionFields(mod).keys()[field_i],
2232 });2233 else => unreachable,
2234 }));
2233 autoHash(hasher, AlignAs.fieldAlign(ty, field_i, mod).@"align");2235 autoHash(hasher, AlignAs.fieldAlign(ty, field_i, mod).@"align");
2234 }2236 }
2235 },2237 },
src/codegen/llvm.zig+52-70
...@@ -585,13 +585,13 @@ pub const Object = struct {...@@ -585,13 +585,13 @@ pub const Object = struct {
585 const slice_ty = Type.slice_const_u8_sentinel_0;585 const slice_ty = Type.slice_const_u8_sentinel_0;
586 const slice_alignment = slice_ty.abiAlignment(mod);586 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();
589 const llvm_errors = try mod.gpa.alloc(*llvm.Value, error_name_list.len);589 const llvm_errors = try mod.gpa.alloc(*llvm.Value, error_name_list.len);
590 defer mod.gpa.free(llvm_errors);590 defer mod.gpa.free(llvm_errors);
591591
592 llvm_errors[0] = llvm_slice_ty.getUndef();592 llvm_errors[0] = llvm_slice_ty.getUndef();
593 for (llvm_errors[1..], 0..) |*llvm_error, i| {593 for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name_nts| {
594 const name = error_name_list[1..][i];594 const name = mod.intern_pool.stringToSlice(name_nts);
595 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);595 const str_init = self.context.constString(name.ptr, @intCast(c_uint, name.len), .False);
596 const str_global = self.llvm_module.addGlobal(str_init.typeOf(), "");596 const str_global = self.llvm_module.addGlobal(str_init.typeOf(), "");
597 str_global.setInitializer(str_init);597 str_global.setInitializer(str_init);
...@@ -671,7 +671,7 @@ pub const Object = struct {...@@ -671,7 +671,7 @@ pub const Object = struct {
671 const llvm_global = entry.value_ptr.*;671 const llvm_global = entry.value_ptr.*;
672 // Same logic as below but for externs instead of exports.672 // Same logic as below but for externs instead of exports.
673 const decl = mod.declPtr(decl_index);673 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;
675 if (other_global == llvm_global) continue;675 if (other_global == llvm_global) continue;
676676
677 llvm_global.replaceAllUsesWith(other_global);677 llvm_global.replaceAllUsesWith(other_global);
...@@ -689,8 +689,7 @@ pub const Object = struct {...@@ -689,8 +689,7 @@ pub const Object = struct {
689 // case, we need to replace all uses of it with this exported global.689 // case, we need to replace all uses of it with this exported global.
690 // TODO update std.builtin.ExportOptions to have the name be a690 // TODO update std.builtin.ExportOptions to have the name be a
691 // null-terminated slice.691 // null-terminated slice.
692 const exp_name_z = try mod.gpa.dupeZ(u8, exp.options.name);692 const exp_name_z = mod.intern_pool.stringToSlice(exp.name);
693 defer mod.gpa.free(exp_name_z);
694693
695 const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue;694 const other_global = object.getLlvmGlobal(exp_name_z.ptr) orelse continue;
696 if (other_global == llvm_global) continue;695 if (other_global == llvm_global) continue;
...@@ -923,9 +922,8 @@ pub const Object = struct {...@@ -923,9 +922,8 @@ pub const Object = struct {
923 dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");922 dg.addFnAttrString(llvm_func, "no-stack-arg-probe", "");
924 }923 }
925924
926 if (decl.@"linksection") |section| {925 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |section|
927 llvm_func.setSection(section);926 llvm_func.setSection(section);
928 }
929927
930 // Remove all the basic blocks of a function in order to start over, generating928 // Remove all the basic blocks of a function in order to start over, generating
931 // LLVM IR from an empty function body.929 // LLVM IR from an empty function body.
...@@ -1173,7 +1171,7 @@ pub const Object = struct {...@@ -1173,7 +1171,7 @@ pub const Object = struct {
1173 0;1171 0;
1174 const subprogram = dib.createFunction(1172 const subprogram = dib.createFunction(
1175 di_file.?.toScope(),1173 di_file.?.toScope(),
1176 decl.name,1174 mod.intern_pool.stringToSlice(decl.name),
1177 llvm_func.getValueName(),1175 llvm_func.getValueName(),
1178 di_file.?,1176 di_file.?,
1179 line_number,1177 line_number,
...@@ -1273,22 +1271,26 @@ pub const Object = struct {...@@ -1273,22 +1271,26 @@ pub const Object = struct {
1273 if (decl.isExtern(mod)) {1271 if (decl.isExtern(mod)) {
1274 var free_decl_name = false;1272 var free_decl_name = false;
1275 const decl_name = decl_name: {1273 const decl_name = decl_name: {
1274 const decl_name = mod.intern_pool.stringToSlice(decl.name);
1275
1276 if (mod.getTarget().isWasm() and try decl.isFunction(mod)) {1276 if (mod.getTarget().isWasm() and try decl.isFunction(mod)) {
1277 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {1277 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
1278 if (!std.mem.eql(u8, lib_name, "c")) {1278 if (!std.mem.eql(u8, lib_name, "c")) {
1279 free_decl_name = true;1279 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 });
1281 }1283 }
1282 }1284 }
1283 }1285 }
1284 break :decl_name std.mem.span(decl.name);1286
1287 break :decl_name decl_name;
1285 };1288 };
1286 defer if (free_decl_name) gpa.free(decl_name);1289 defer if (free_decl_name) gpa.free(decl_name);
12871290
1288 llvm_global.setValueName(decl_name);1291 llvm_global.setValueName(decl_name);
1289 if (self.getLlvmGlobal(decl_name)) |other_global| {1292 if (self.getLlvmGlobal(decl_name)) |other_global| {
1290 if (other_global != llvm_global) {1293 if (other_global != llvm_global) {
1291 log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name});
1292 try self.extern_collisions.put(gpa, decl_index, {});1294 try self.extern_collisions.put(gpa, decl_index, {});
1293 }1295 }
1294 }1296 }
...@@ -1298,11 +1300,11 @@ pub const Object = struct {...@@ -1298,11 +1300,11 @@ pub const Object = struct {
1298 if (self.di_map.get(decl)) |di_node| {1300 if (self.di_map.get(decl)) |di_node| {
1299 if (try decl.isFunction(mod)) {1301 if (try decl.isFunction(mod)) {
1300 const di_func = @ptrCast(*llvm.DISubprogram, di_node);1302 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);
1302 di_func.replaceLinkageName(linkage_name);1304 di_func.replaceLinkageName(linkage_name);
1303 } else {1305 } else {
1304 const di_global = @ptrCast(*llvm.DIGlobalVariable, di_node);1306 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);
1306 di_global.replaceLinkageName(linkage_name);1308 di_global.replaceLinkageName(linkage_name);
1307 }1309 }
1308 }1310 }
...@@ -1317,7 +1319,7 @@ pub const Object = struct {...@@ -1317,7 +1319,7 @@ pub const Object = struct {
1317 }1319 }
1318 }1320 }
1319 } else if (exports.len != 0) {1321 } else if (exports.len != 0) {
1320 const exp_name = exports[0].options.name;1322 const exp_name = mod.intern_pool.stringToSlice(exports[0].name);
1321 llvm_global.setValueName2(exp_name.ptr, exp_name.len);1323 llvm_global.setValueName2(exp_name.ptr, exp_name.len);
1322 llvm_global.setUnnamedAddr(.False);1324 llvm_global.setUnnamedAddr(.False);
1323 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);1325 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);
...@@ -1332,21 +1334,19 @@ pub const Object = struct {...@@ -1332,21 +1334,19 @@ pub const Object = struct {
1332 di_global.replaceLinkageName(linkage_name);1334 di_global.replaceLinkageName(linkage_name);
1333 }1335 }
1334 }1336 }
1335 switch (exports[0].options.linkage) {1337 switch (exports[0].linkage) {
1336 .Internal => unreachable,1338 .Internal => unreachable,
1337 .Strong => llvm_global.setLinkage(.External),1339 .Strong => llvm_global.setLinkage(.External),
1338 .Weak => llvm_global.setLinkage(.WeakODR),1340 .Weak => llvm_global.setLinkage(.WeakODR),
1339 .LinkOnce => llvm_global.setLinkage(.LinkOnceODR),1341 .LinkOnce => llvm_global.setLinkage(.LinkOnceODR),
1340 }1342 }
1341 switch (exports[0].options.visibility) {1343 switch (exports[0].visibility) {
1342 .default => llvm_global.setVisibility(.Default),1344 .default => llvm_global.setVisibility(.Default),
1343 .hidden => llvm_global.setVisibility(.Hidden),1345 .hidden => llvm_global.setVisibility(.Hidden),
1344 .protected => llvm_global.setVisibility(.Protected),1346 .protected => llvm_global.setVisibility(.Protected),
1345 }1347 }
1346 if (exports[0].options.section) |section| {1348 if (mod.intern_pool.stringToSliceUnwrap(exports[0].section)) |section| {
1347 const section_z = try gpa.dupeZ(u8, section);1349 llvm_global.setSection(section);
1348 defer gpa.free(section_z);
1349 llvm_global.setSection(section_z);
1350 }1350 }
1351 if (decl.val.getVariable(mod)) |variable| {1351 if (decl.val.getVariable(mod)) |variable| {
1352 if (variable.is_threadlocal) {1352 if (variable.is_threadlocal) {
...@@ -1356,13 +1356,12 @@ pub const Object = struct {...@@ -1356,13 +1356,12 @@ pub const Object = struct {
13561356
1357 // If a Decl is exported more than one time (which is rare),1357 // If a Decl is exported more than one time (which is rare),
1358 // we add aliases for all but the first export.1358 // we add aliases for all but the first export.
1359 // TODO LLVM C API does not support deleting aliases. We need to1359 // TODO LLVM C API does not support deleting aliases.
1360 // patch it to support this or figure out how to wrap the C++ API ourselves.1360 // The planned solution to this is https://github.com/ziglang/zig/issues/13265
1361 // Until then we iterate over existing aliases and make them point1361 // Until then we iterate over existing aliases and make them point
1362 // to the correct decl, or otherwise add a new alias. Old aliases are leaked.1362 // to the correct decl, or otherwise add a new alias. Old aliases are leaked.
1363 for (exports[1..]) |exp| {1363 for (exports[1..]) |exp| {
1364 const exp_name_z = try gpa.dupeZ(u8, exp.options.name);1364 const exp_name_z = mod.intern_pool.stringToSlice(exp.name);
1365 defer gpa.free(exp_name_z);
13661365
1367 if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| {1366 if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| {
1368 alias.setAliasee(llvm_global);1367 alias.setAliasee(llvm_global);
...@@ -1376,8 +1375,7 @@ pub const Object = struct {...@@ -1376,8 +1375,7 @@ pub const Object = struct {
1376 }1375 }
1377 }1376 }
1378 } else {1377 } else {
1379 const fqn = try decl.getFullyQualifiedName(mod);1378 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1380 defer gpa.free(fqn);
1381 llvm_global.setValueName2(fqn.ptr, fqn.len);1379 llvm_global.setValueName2(fqn.ptr, fqn.len);
1382 llvm_global.setLinkage(.Internal);1380 llvm_global.setLinkage(.Internal);
1383 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);1381 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
...@@ -2092,8 +2090,7 @@ pub const Object = struct {...@@ -2092,8 +2090,7 @@ pub const Object = struct {
2092 const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);2090 const field_offset = std.mem.alignForwardGeneric(u64, offset, field_align);
2093 offset = field_offset + field_size;2091 offset = field_offset + field_size;
20942092
2095 const field_name = try gpa.dupeZ(u8, fields.keys()[field_and_index.index]);2093 const field_name = mod.intern_pool.stringToSlice(fields.keys()[field_and_index.index]);
2096 defer gpa.free(field_name);
20972094
2098 try di_fields.append(gpa, dib.createMemberType(2095 try di_fields.append(gpa, dib.createMemberType(
2099 fwd_decl.toScope(),2096 fwd_decl.toScope(),
...@@ -2200,12 +2197,9 @@ pub const Object = struct {...@@ -2200,12 +2197,9 @@ pub const Object = struct {
2200 const field_size = field.ty.abiSize(mod);2197 const field_size = field.ty.abiSize(mod);
2201 const field_align = field.normalAlignment(mod);2198 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
2206 di_fields.appendAssumeCapacity(dib.createMemberType(2200 di_fields.appendAssumeCapacity(dib.createMemberType(
2207 fwd_decl.toScope(),2201 fwd_decl.toScope(),
2208 field_name_copy,2202 mod.intern_pool.stringToSlice(field_name),
2209 null, // file2203 null, // file
2210 0, // line2204 0, // line
2211 field_size * 8, // size in bits2205 field_size * 8, // size in bits
...@@ -2327,7 +2321,7 @@ pub const Object = struct {...@@ -2327,7 +2321,7 @@ pub const Object = struct {
2327 if (fn_info.return_type.toType().isError(mod) and2321 if (fn_info.return_type.toType().isError(mod) and
2328 o.module.comp.bin_file.options.error_return_tracing)2322 o.module.comp.bin_file.options.error_return_tracing)
2329 {2323 {
2330 const ptr_ty = try mod.singleMutPtrType(o.getStackTraceType());2324 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
2331 try param_di_types.append(try o.lowerDebugType(ptr_ty, .full));2325 try param_di_types.append(try o.lowerDebugType(ptr_ty, .full));
2332 }2326 }
23332327
...@@ -2384,7 +2378,7 @@ pub const Object = struct {...@@ -2384,7 +2378,7 @@ pub const Object = struct {
2384 const fields: [0]*llvm.DIType = .{};2378 const fields: [0]*llvm.DIType = .{};
2385 return o.di_builder.?.createStructType(2379 return o.di_builder.?.createStructType(
2386 try o.namespaceToDebugScope(decl.src_namespace),2380 try o.namespaceToDebugScope(decl.src_namespace),
2387 decl.name, // TODO use fully qualified name2381 mod.intern_pool.stringToSlice(decl.name), // TODO use fully qualified name
2388 try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope),2382 try o.getDIFile(o.gpa, mod.namespacePtr(decl.src_namespace).file_scope),
2389 decl.src_line + 1,2383 decl.src_line + 1,
2390 0, // size in bits2384 0, // size in bits
...@@ -2399,18 +2393,18 @@ pub const Object = struct {...@@ -2399,18 +2393,18 @@ pub const Object = struct {
2399 );2393 );
2400 }2394 }
24012395
2402 fn getStackTraceType(o: *Object) Type {2396 fn getStackTraceType(o: *Object) Allocator.Error!Type {
2403 const mod = o.module;2397 const mod = o.module;
24042398
2405 const std_pkg = mod.main_pkg.table.get("std").?;2399 const std_pkg = mod.main_pkg.table.get("std").?;
2406 const std_file = (mod.importPkg(std_pkg) catch unreachable).file;2400 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");
2409 const std_namespace = mod.namespacePtr(mod.declPtr(std_file.root_decl.unwrap().?).src_namespace);2403 const std_namespace = mod.namespacePtr(mod.declPtr(std_file.root_decl.unwrap().?).src_namespace);
2410 const builtin_decl = std_namespace.decls2404 const builtin_decl = std_namespace.decls
2411 .getKeyAdapted(builtin_str, Module.DeclAdapter{ .mod = mod }).?;2405 .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");
2414 // buffer is only used for int_type, `builtin` is a struct.2408 // buffer is only used for int_type, `builtin` is a struct.
2415 const builtin_ty = mod.declPtr(builtin_decl).val.toType();2409 const builtin_ty = mod.declPtr(builtin_decl).val.toType();
2416 const builtin_namespace = builtin_ty.getNamespace(mod).?;2410 const builtin_namespace = builtin_ty.getNamespace(mod).?;
...@@ -2452,16 +2446,13 @@ pub const DeclGen = struct {...@@ -2452,16 +2446,13 @@ pub const DeclGen = struct {
2452 const decl_index = dg.decl_index;2446 const decl_index = dg.decl_index;
2453 assert(decl.has_tv);2447 assert(decl.has_tv);
24542448
2455 log.debug("gen: {s} type: {}, value: {}", .{
2456 decl.name, decl.ty.fmtDebug(), decl.val.fmtDebug(),
2457 });
2458 if (decl.val.getExternFunc(mod)) |extern_func| {2449 if (decl.val.getExternFunc(mod)) |extern_func| {
2459 _ = try dg.resolveLlvmFunction(extern_func.decl);2450 _ = try dg.resolveLlvmFunction(extern_func.decl);
2460 } else {2451 } else {
2461 const target = mod.getTarget();2452 const target = mod.getTarget();
2462 var global = try dg.resolveGlobalDecl(decl_index);2453 var global = try dg.resolveGlobalDecl(decl_index);
2463 global.setAlignment(decl.getAlignment(mod));2454 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);
2465 assert(decl.has_tv);2456 assert(decl.has_tv);
2466 const init_val = if (decl.val.getVariable(mod)) |variable| init_val: {2457 const init_val = if (decl.val.getVariable(mod)) |variable| init_val: {
2467 break :init_val variable.init;2458 break :init_val variable.init;
...@@ -2495,7 +2486,8 @@ pub const DeclGen = struct {...@@ -2495,7 +2486,8 @@ pub const DeclGen = struct {
2495 new_global.setLinkage(global.getLinkage());2486 new_global.setLinkage(global.getLinkage());
2496 new_global.setUnnamedAddr(global.getUnnamedAddress());2487 new_global.setUnnamedAddr(global.getUnnamedAddress());
2497 new_global.setAlignment(global.getAlignment());2488 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);
2499 new_global.setInitializer(llvm_init);2491 new_global.setInitializer(llvm_init);
2500 // TODO: How should this work then the address space of a global changed?2492 // TODO: How should this work then the address space of a global changed?
2501 global.replaceAllUsesWith(new_global);2493 global.replaceAllUsesWith(new_global);
...@@ -2513,7 +2505,7 @@ pub const DeclGen = struct {...@@ -2513,7 +2505,7 @@ pub const DeclGen = struct {
2513 const is_internal_linkage = !dg.module.decl_exports.contains(decl_index);2505 const is_internal_linkage = !dg.module.decl_exports.contains(decl_index);
2514 const di_global = dib.createGlobalVariableExpression(2506 const di_global = dib.createGlobalVariableExpression(
2515 di_file.toScope(),2507 di_file.toScope(),
2516 decl.name,2508 mod.intern_pool.stringToSlice(decl.name),
2517 global.getValueName(),2509 global.getValueName(),
2518 di_file,2510 di_file,
2519 line_number,2511 line_number,
...@@ -2544,8 +2536,7 @@ pub const DeclGen = struct {...@@ -2544,8 +2536,7 @@ pub const DeclGen = struct {
25442536
2545 const fn_type = try dg.lowerType(zig_fn_type);2537 const fn_type = try dg.lowerType(zig_fn_type);
25462538
2547 const fqn = try decl.getFullyQualifiedName(mod);2539 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
2548 defer dg.gpa.free(fqn);
25492540
2550 const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);2541 const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
2551 const llvm_fn = dg.llvmModule().addFunctionInAddressSpace(fqn, fn_type, llvm_addrspace);2542 const llvm_fn = dg.llvmModule().addFunctionInAddressSpace(fqn, fn_type, llvm_addrspace);
...@@ -2557,7 +2548,7 @@ pub const DeclGen = struct {...@@ -2557,7 +2548,7 @@ pub const DeclGen = struct {
2557 llvm_fn.setUnnamedAddr(.True);2548 llvm_fn.setUnnamedAddr(.True);
2558 } else {2549 } else {
2559 if (target.isWasm()) {2550 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));
2561 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {2552 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
2562 if (!std.mem.eql(u8, lib_name, "c")) {2553 if (!std.mem.eql(u8, lib_name, "c")) {
2563 dg.addFnAttrString(llvm_fn, "wasm-import-module", lib_name);2554 dg.addFnAttrString(llvm_fn, "wasm-import-module", lib_name);
...@@ -2699,8 +2690,7 @@ pub const DeclGen = struct {...@@ -2699,8 +2690,7 @@ pub const DeclGen = struct {
26992690
2700 const mod = dg.module;2691 const mod = dg.module;
2701 const decl = mod.declPtr(decl_index);2692 const decl = mod.declPtr(decl_index);
2702 const fqn = try decl.getFullyQualifiedName(mod);2693 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
2703 defer dg.gpa.free(fqn);
27042694
2705 const target = mod.getTarget();2695 const target = mod.getTarget();
27062696
...@@ -2716,7 +2706,7 @@ pub const DeclGen = struct {...@@ -2716,7 +2706,7 @@ pub const DeclGen = struct {
27162706
2717 // This is needed for declarations created by `@extern`.2707 // This is needed for declarations created by `@extern`.
2718 if (decl.isExtern(mod)) {2708 if (decl.isExtern(mod)) {
2719 llvm_global.setValueName(decl.name);2709 llvm_global.setValueName(mod.intern_pool.stringToSlice(decl.name));
2720 llvm_global.setUnnamedAddr(.False);2710 llvm_global.setUnnamedAddr(.False);
2721 llvm_global.setLinkage(.External);2711 llvm_global.setLinkage(.External);
2722 if (decl.val.getVariable(mod)) |variable| {2712 if (decl.val.getVariable(mod)) |variable| {
...@@ -2811,8 +2801,7 @@ pub const DeclGen = struct {...@@ -2811,8 +2801,7 @@ pub const DeclGen = struct {
2811 if (gop.found_existing) return gop.value_ptr.*;2801 if (gop.found_existing) return gop.value_ptr.*;
28122802
2813 const opaque_type = mod.intern_pool.indexToKey(t.toIntern()).opaque_type;2803 const opaque_type = mod.intern_pool.indexToKey(t.toIntern()).opaque_type;
2814 const name = try mod.opaqueFullyQualifiedName(opaque_type);2804 const name = mod.intern_pool.stringToSlice(try mod.opaqueFullyQualifiedName(opaque_type));
2815 defer gpa.free(name);
28162805
2817 const llvm_struct_ty = dg.context.structCreateNamed(name);2806 const llvm_struct_ty = dg.context.structCreateNamed(name);
2818 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls2807 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
...@@ -2963,8 +2952,7 @@ pub const DeclGen = struct {...@@ -2963,8 +2952,7 @@ pub const DeclGen = struct {
2963 return int_llvm_ty;2952 return int_llvm_ty;
2964 }2953 }
29652954
2966 const name = try struct_obj.getFullyQualifiedName(mod);2955 const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
2967 defer gpa.free(name);
29682956
2969 const llvm_struct_ty = dg.context.structCreateNamed(name);2957 const llvm_struct_ty = dg.context.structCreateNamed(name);
2970 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls2958 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
...@@ -3040,8 +3028,7 @@ pub const DeclGen = struct {...@@ -3040,8 +3028,7 @@ pub const DeclGen = struct {
3040 return enum_tag_llvm_ty;3028 return enum_tag_llvm_ty;
3041 }3029 }
30423030
3043 const name = try union_obj.getFullyQualifiedName(mod);3031 const name = mod.intern_pool.stringToSlice(try union_obj.getFullyQualifiedName(mod));
3044 defer gpa.free(name);
30453032
3046 const llvm_union_ty = dg.context.structCreateNamed(name);3033 const llvm_union_ty = dg.context.structCreateNamed(name);
3047 gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls3034 gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls
...@@ -3119,7 +3106,7 @@ pub const DeclGen = struct {...@@ -3119,7 +3106,7 @@ pub const DeclGen = struct {
3119 if (fn_info.return_type.toType().isError(mod) and3106 if (fn_info.return_type.toType().isError(mod) and
3120 mod.comp.bin_file.options.error_return_tracing)3107 mod.comp.bin_file.options.error_return_tracing)
3121 {3108 {
3122 const ptr_ty = try mod.singleMutPtrType(dg.object.getStackTraceType());3109 const ptr_ty = try mod.singleMutPtrType(try dg.object.getStackTraceType());
3123 try llvm_params.append(try dg.lowerType(ptr_ty));3110 try llvm_params.append(try dg.lowerType(ptr_ty));
3124 }3111 }
31253112
...@@ -3266,9 +3253,8 @@ pub const DeclGen = struct {...@@ -3266,9 +3253,8 @@ pub const DeclGen = struct {
3266 },3253 },
3267 .err => |err| {3254 .err => |err| {
3268 const llvm_ty = try dg.lowerType(Type.anyerror);3255 const llvm_ty = try dg.lowerType(Type.anyerror);
3269 const name = mod.intern_pool.stringToSlice(err.name);3256 const int = try mod.getErrorValue(err.name);
3270 const kv = try mod.getErrorValue(name);3257 return llvm_ty.constInt(int, .False);
3271 return llvm_ty.constInt(kv.value, .False);
3272 },3258 },
3273 .error_union => |error_union| {3259 .error_union => |error_union| {
3274 const err_tv: TypedValue = switch (error_union.val) {3260 const err_tv: TypedValue = switch (error_union.val) {
...@@ -5960,8 +5946,7 @@ pub const FuncGen = struct {...@@ -5960,8 +5946,7 @@ pub const FuncGen = struct {
5960 .base_line = self.base_line,5946 .base_line = self.base_line,
5961 });5947 });
59625948
5963 const fqn = try decl.getFullyQualifiedName(mod);5949 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
5964 defer self.gpa.free(fqn);
59655950
5966 const is_internal_linkage = !mod.decl_exports.contains(decl_index);5951 const is_internal_linkage = !mod.decl_exports.contains(decl_index);
5967 const fn_ty = try mod.funcType(.{5952 const fn_ty = try mod.funcType(.{
...@@ -5981,7 +5966,7 @@ pub const FuncGen = struct {...@@ -5981,7 +5966,7 @@ pub const FuncGen = struct {
5981 });5966 });
5982 const subprogram = dib.createFunction(5967 const subprogram = dib.createFunction(
5983 di_file.toScope(),5968 di_file.toScope(),
5984 decl.name,5969 mod.intern_pool.stringToSlice(decl.name),
5985 fqn,5970 fqn,
5986 di_file,5971 di_file,
5987 line_number,5972 line_number,
...@@ -8629,9 +8614,8 @@ pub const FuncGen = struct {...@@ -8629,9 +8614,8 @@ pub const FuncGen = struct {
8629 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");8614 const end_block = self.context.appendBasicBlock(self.llvm_func, "End");
8630 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));8615 const switch_instr = self.builder.buildSwitch(operand, invalid_block, @intCast(c_uint, names.len));
86318616
8632 for (names) |name_ip| {8617 for (names) |name| {
8633 const name = mod.intern_pool.stringToSlice(name_ip);8618 const err_int = @intCast(Module.ErrorInt, mod.global_error_set.getIndex(name).?);
8634 const err_int = mod.global_error_set.get(name).?;
8635 const this_tag_int_value = try self.dg.lowerValue(.{8619 const this_tag_int_value = try self.dg.lowerValue(.{
8636 .ty = Type.err_int,8620 .ty = Type.err_int,
8637 .val = try mod.intValue(Type.err_int, err_int),8621 .val = try mod.intValue(Type.err_int, err_int),
...@@ -8681,8 +8665,7 @@ pub const FuncGen = struct {...@@ -8681,8 +8665,7 @@ pub const FuncGen = struct {
8681 defer arena_allocator.deinit();8665 defer arena_allocator.deinit();
8682 const arena = arena_allocator.allocator();8666 const arena = arena_allocator.allocator();
86838667
8684 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);8668 const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod));
8685 defer self.gpa.free(fqn);
8686 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});8669 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{s}", .{fqn});
86878670
8688 const param_types = [_]*llvm.Type{try self.dg.lowerType(enum_type.tag_ty.toType())};8671 const param_types = [_]*llvm.Type{try self.dg.lowerType(enum_type.tag_ty.toType())};
...@@ -8754,8 +8737,7 @@ pub const FuncGen = struct {...@@ -8754,8 +8737,7 @@ pub const FuncGen = struct {
8754 defer arena_allocator.deinit();8737 defer arena_allocator.deinit();
8755 const arena = arena_allocator.allocator();8738 const arena = arena_allocator.allocator();
87568739
8757 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);8740 const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod));
8758 defer self.gpa.free(fqn);
8759 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});8741 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
87608742
8761 const slice_ty = Type.slice_const_u8_sentinel_0;8743 const slice_ty = Type.slice_const_u8_sentinel_0;
src/codegen/spirv.zig+4-9
...@@ -593,7 +593,6 @@ pub const DeclGen = struct {...@@ -593,7 +593,6 @@ pub const DeclGen = struct {
593 .extern_func => unreachable, // TODO593 .extern_func => unreachable, // TODO
594 else => {594 else => {
595 const result_id = dg.spv.allocId();595 const result_id = dg.spv.allocId();
596 log.debug("addDeclRef: id = {}, index = {}, name = {s}", .{ result_id.id, @enumToInt(spv_decl_index), decl.name });
597596
598 try self.decl_deps.put(spv_decl_index, {});597 try self.decl_deps.put(spv_decl_index, {});
599598
...@@ -664,9 +663,8 @@ pub const DeclGen = struct {...@@ -664,9 +663,8 @@ pub const DeclGen = struct {
664 => unreachable, // non-runtime values663 => unreachable, // non-runtime values
665 .int => try self.addInt(ty, val),664 .int => try self.addInt(ty, val),
666 .err => |err| {665 .err => |err| {
667 const name = mod.intern_pool.stringToSlice(err.name);666 const int = try mod.getErrorValue(err.name);
668 const kv = try mod.getErrorValue(name);667 try self.addConstInt(u16, @intCast(u16, int));
669 try self.addConstInt(u16, @intCast(u16, kv.value));
670 },668 },
671 .error_union => |error_union| {669 .error_union => |error_union| {
672 const payload_ty = ty.errorUnionPayload(mod);670 const payload_ty = ty.errorUnionPayload(mod);
...@@ -1288,8 +1286,7 @@ pub const DeclGen = struct {...@@ -1288,8 +1286,7 @@ pub const DeclGen = struct {
1288 member_index += 1;1286 member_index += 1;
1289 }1287 }
12901288
1291 const name = try struct_obj.getFullyQualifiedName(self.module);1289 const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(self.module));
1292 defer self.module.gpa.free(name);
12931290
1294 return try self.spv.resolve(.{ .struct_type = .{1291 return try self.spv.resolve(.{ .struct_type = .{
1295 .name = try self.spv.resolveString(name),1292 .name = try self.spv.resolveString(name),
...@@ -1500,7 +1497,6 @@ pub const DeclGen = struct {...@@ -1500,7 +1497,6 @@ pub const DeclGen = struct {
1500 const spv_decl_index = try self.resolveDecl(self.decl_index);1497 const spv_decl_index = try self.resolveDecl(self.decl_index);
15011498
1502 const decl_id = self.spv.declPtr(spv_decl_index).result_id;1499 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
1505 if (decl.val.getFunction(mod)) |_| {1501 if (decl.val.getFunction(mod)) |_| {
1506 assert(decl.ty.zigTypeTag(mod) == .Fn);1502 assert(decl.ty.zigTypeTag(mod) == .Fn);
...@@ -1542,8 +1538,7 @@ pub const DeclGen = struct {...@@ -1542,8 +1538,7 @@ pub const DeclGen = struct {
1542 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});1538 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
1543 try self.spv.addFunction(spv_decl_index, self.func);1539 try self.spv.addFunction(spv_decl_index, self.func);
15441540
1545 const fqn = try decl.getFullyQualifiedName(self.module);1541 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(self.module));
1546 defer self.module.gpa.free(fqn);
15471542
1548 try self.spv.sections.debug_names.emit(self.gpa, .OpName, .{1543 try self.spv.sections.debug_names.emit(self.gpa, .OpName, .{
1549 .target = decl_id,1544 .target = decl_id,
src/link.zig-11
...@@ -502,8 +502,6 @@ pub const File = struct {...@@ -502,8 +502,6 @@ pub const File = struct {
502 /// of the final binary.502 /// of the final binary.
503 pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: Module.Decl.Index) UpdateDeclError!u32 {503 pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: Module.Decl.Index) UpdateDeclError!u32 {
504 if (build_options.only_c) @compileError("unreachable");504 if (build_options.only_c) @compileError("unreachable");
505 const decl = base.options.module.?.declPtr(decl_index);
506 log.debug("lowerUnnamedConst {*} ({s})", .{ decl, decl.name });
507 switch (base.tag) {505 switch (base.tag) {
508 // zig fmt: off506 // zig fmt: off
509 .coff => return @fieldParentPtr(Coff, "base", base).lowerUnnamedConst(tv, decl_index),507 .coff => return @fieldParentPtr(Coff, "base", base).lowerUnnamedConst(tv, decl_index),
...@@ -543,7 +541,6 @@ pub const File = struct {...@@ -543,7 +541,6 @@ pub const File = struct {
543 /// May be called before or after updateDeclExports for any given Decl.541 /// May be called before or after updateDeclExports for any given Decl.
544 pub fn updateDecl(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {542 pub fn updateDecl(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {
545 const decl = module.declPtr(decl_index);543 const decl = module.declPtr(decl_index);
546 log.debug("updateDecl {*} ({s}), type={}", .{ decl, decl.name, decl.ty.fmt(module) });
547 assert(decl.has_tv);544 assert(decl.has_tv);
548 if (build_options.only_c) {545 if (build_options.only_c) {
549 assert(base.tag == .c);546 assert(base.tag == .c);
...@@ -566,10 +563,6 @@ pub const File = struct {...@@ -566,10 +563,6 @@ pub const File = struct {
566 /// May be called before or after updateDeclExports for any given Decl.563 /// May be called before or after updateDeclExports for any given Decl.
567 pub fn updateFunc(base: *File, module: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) UpdateDeclError!void {564 pub fn updateFunc(base: *File, module: *Module, func_index: Module.Fn.Index, air: Air, liveness: Liveness) UpdateDeclError!void {
568 const func = module.funcPtr(func_index);565 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 });
573 if (build_options.only_c) {566 if (build_options.only_c) {
574 assert(base.tag == .c);567 assert(base.tag == .c);
575 return @fieldParentPtr(C, "base", base).updateFunc(module, func, air, liveness);568 return @fieldParentPtr(C, "base", base).updateFunc(module, func, air, liveness);
...@@ -590,9 +583,6 @@ pub const File = struct {...@@ -590,9 +583,6 @@ pub const File = struct {
590583
591 pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {584 pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: Module.Decl.Index) UpdateDeclError!void {
592 const decl = module.declPtr(decl_index);585 const decl = module.declPtr(decl_index);
593 log.debug("updateDeclLineNumber {*} ({s}), line={}", .{
594 decl, decl.name, decl.src_line + 1,
595 });
596 assert(decl.has_tv);586 assert(decl.has_tv);
597 if (build_options.only_c) {587 if (build_options.only_c) {
598 assert(base.tag == .c);588 assert(base.tag == .c);
...@@ -868,7 +858,6 @@ pub const File = struct {...@@ -868,7 +858,6 @@ pub const File = struct {
868 exports: []const *Module.Export,858 exports: []const *Module.Export,
869 ) UpdateDeclExportsError!void {859 ) UpdateDeclExportsError!void {
870 const decl = module.declPtr(decl_index);860 const decl = module.declPtr(decl_index);
871 log.debug("updateDeclExports {*} ({s})", .{ decl, decl.name });
872 assert(decl.has_tv);861 assert(decl.has_tv);
873 if (build_options.only_c) {862 if (build_options.only_c) {
874 assert(base.tag == .c);863 assert(base.tag == .c);
src/link/C.zig+5-4
...@@ -6,6 +6,7 @@ const fs = std.fs;...@@ -6,6 +6,7 @@ const fs = std.fs;
66
7const C = @This();7const C = @This();
8const Module = @import("../Module.zig");8const Module = @import("../Module.zig");
9const InternPool = @import("../InternPool.zig");
9const Compilation = @import("../Compilation.zig");10const Compilation = @import("../Compilation.zig");
10const codegen = @import("../codegen/c.zig");11const codegen = @import("../codegen/c.zig");
11const link = @import("../link.zig");12const link = @import("../link.zig");
...@@ -289,11 +290,11 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo...@@ -289,11 +290,11 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
289 }290 }
290291
291 {292 {
292 var export_names = std.StringHashMapUnmanaged(void){};293 var export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
293 defer export_names.deinit(gpa);294 defer export_names.deinit(gpa);
294 try export_names.ensureTotalCapacity(gpa, @intCast(u32, module.decl_exports.entries.len));295 try export_names.ensureTotalCapacity(gpa, @intCast(u32, module.decl_exports.entries.len));
295 for (module.decl_exports.values()) |exports| for (exports.items) |@"export"|296 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
298 while (f.remaining_decls.popOrNull()) |kv| {299 while (f.remaining_decls.popOrNull()) |kv| {
299 const decl_index = kv.key;300 const decl_index = kv.key;
...@@ -553,7 +554,7 @@ fn flushDecl(...@@ -553,7 +554,7 @@ fn flushDecl(
553 self: *C,554 self: *C,
554 f: *Flush,555 f: *Flush,
555 decl_index: Module.Decl.Index,556 decl_index: Module.Decl.Index,
556 export_names: std.StringHashMapUnmanaged(void),557 export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
557) FlushDeclError!void {558) FlushDeclError!void {
558 const gpa = self.base.allocator;559 const gpa = self.base.allocator;
559 const mod = self.base.options.module.?;560 const mod = self.base.options.module.?;
...@@ -571,7 +572,7 @@ fn flushDecl(...@@ -571,7 +572,7 @@ fn flushDecl(
571572
572 try self.flushLazyFns(f, decl_block.lazy_fns);573 try self.flushLazyFns(f, decl_block.lazy_fns);
573 try f.all_buffers.ensureUnusedCapacity(gpa, 1);574 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)))
575 f.appendBufAssumeCapacity(decl_block.fwd_decl.items);576 f.appendBufAssumeCapacity(decl_block.fwd_decl.items);
576}577}
577578
src/link/Coff.zig+27-23
...@@ -1097,8 +1097,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In...@@ -1097,8 +1097,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
1097 const atom_index = try self.createAtom();1097 const atom_index = try self.createAtom();
10981098
1099 const sym_name = blk: {1099 const sym_name = blk: {
1100 const decl_name = try decl.getFullyQualifiedName(mod);1100 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1101 defer gpa.free(decl_name);
11021101
1103 const index = unnamed_consts.items.len;1102 const index = unnamed_consts.items.len;
1104 break :blk try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });1103 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 {...@@ -1324,12 +1323,10 @@ fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 {
1324}1323}
13251324
1326fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []u8, complex_type: coff.ComplexType) !void {1325fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []u8, complex_type: coff.ComplexType) !void {
1327 const gpa = self.base.allocator;
1328 const mod = self.base.options.module.?;1326 const mod = self.base.options.module.?;
1329 const decl = mod.declPtr(decl_index);1327 const decl = mod.declPtr(decl_index);
13301328
1331 const decl_name = try decl.getFullyQualifiedName(mod);1329 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1332 defer gpa.free(decl_name);
13331330
1334 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });1331 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
1335 const required_alignment = decl.getAlignment(mod);1332 const required_alignment = decl.getAlignment(mod);
...@@ -1420,6 +1417,8 @@ pub fn updateDeclExports(...@@ -1420,6 +1417,8 @@ pub fn updateDeclExports(
1420 @panic("Attempted to compile for object format that was disabled by build configuration");1417 @panic("Attempted to compile for object format that was disabled by build configuration");
1421 }1418 }
14221419
1420 const ip = &mod.intern_pool;
1421
1423 if (build_options.have_llvm) {1422 if (build_options.have_llvm) {
1424 // Even in the case of LLVM, we need to notice certain exported symbols in order to1423 // Even in the case of LLVM, we need to notice certain exported symbols in order to
1425 // detect the default subsystem.1424 // detect the default subsystem.
...@@ -1431,20 +1430,20 @@ pub fn updateDeclExports(...@@ -1431,20 +1430,20 @@ pub fn updateDeclExports(
1431 else => std.builtin.CallingConvention.C,1430 else => std.builtin.CallingConvention.C,
1432 };1431 };
1433 const decl_cc = exported_decl.ty.fnCallingConvention(mod);1432 const decl_cc = exported_decl.ty.fnCallingConvention(mod);
1434 if (decl_cc == .C and mem.eql(u8, exp.options.name, "main") and1433 if (decl_cc == .C and ip.stringEqlSlice(exp.name, "main") and
1435 self.base.options.link_libc)1434 self.base.options.link_libc)
1436 {1435 {
1437 mod.stage1_flags.have_c_main = true;1436 mod.stage1_flags.have_c_main = true;
1438 } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) {1437 } 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")) {
1440 mod.stage1_flags.have_winmain = true;1439 mod.stage1_flags.have_winmain = true;
1441 } else if (mem.eql(u8, exp.options.name, "wWinMain")) {1440 } else if (ip.stringEqlSlice(exp.name, "wWinMain")) {
1442 mod.stage1_flags.have_wwinmain = true;1441 mod.stage1_flags.have_wwinmain = true;
1443 } else if (mem.eql(u8, exp.options.name, "WinMainCRTStartup")) {1442 } else if (ip.stringEqlSlice(exp.name, "WinMainCRTStartup")) {
1444 mod.stage1_flags.have_winmain_crt_startup = true;1443 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")) {
1446 mod.stage1_flags.have_wwinmain_crt_startup = true;1445 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")) {
1448 mod.stage1_flags.have_dllmain_crt_startup = true;1447 mod.stage1_flags.have_dllmain_crt_startup = true;
1449 }1448 }
1450 }1449 }
...@@ -1453,9 +1452,6 @@ pub fn updateDeclExports(...@@ -1453,9 +1452,6 @@ pub fn updateDeclExports(
1453 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(mod, decl_index, exports);1452 if (self.llvm_object) |llvm_object| return llvm_object.updateDeclExports(mod, decl_index, exports);
1454 }1453 }
14551454
1456 const tracy = trace(@src());
1457 defer tracy.end();
1458
1459 const gpa = self.base.allocator;1455 const gpa = self.base.allocator;
14601456
1461 const decl = mod.declPtr(decl_index);1457 const decl = mod.declPtr(decl_index);
...@@ -1465,12 +1461,13 @@ pub fn updateDeclExports(...@@ -1465,12 +1461,13 @@ pub fn updateDeclExports(
1465 const decl_metadata = self.decls.getPtr(decl_index).?;1461 const decl_metadata = self.decls.getPtr(decl_index).?;
14661462
1467 for (exports) |exp| {1463 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| {
1471 if (!mem.eql(u8, section_name, ".text")) {1468 if (!mem.eql(u8, section_name, ".text")) {
1472 try mod.failed_exports.putNoClobber(1469 try mod.failed_exports.putNoClobber(
1473 mod.gpa,1470 gpa,
1474 exp,1471 exp,
1475 try Module.ErrorMsg.create(1472 try Module.ErrorMsg.create(
1476 gpa,1473 gpa,
...@@ -1483,9 +1480,9 @@ pub fn updateDeclExports(...@@ -1483,9 +1480,9 @@ pub fn updateDeclExports(
1483 }1480 }
1484 }1481 }
14851482
1486 if (exp.options.linkage == .LinkOnce) {1483 if (exp.linkage == .LinkOnce) {
1487 try mod.failed_exports.putNoClobber(1484 try mod.failed_exports.putNoClobber(
1488 mod.gpa,1485 gpa,
1489 exp,1486 exp,
1490 try Module.ErrorMsg.create(1487 try Module.ErrorMsg.create(
1491 gpa,1488 gpa,
...@@ -1497,19 +1494,19 @@ pub fn updateDeclExports(...@@ -1497,19 +1494,19 @@ pub fn updateDeclExports(
1497 continue;1494 continue;
1498 }1495 }
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: {
1501 const sym_index = try self.allocateSymbol();1498 const sym_index = try self.allocateSymbol();
1502 try decl_metadata.exports.append(gpa, sym_index);1499 try decl_metadata.exports.append(gpa, sym_index);
1503 break :blk sym_index;1500 break :blk sym_index;
1504 };1501 };
1505 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };1502 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };
1506 const sym = self.getSymbolPtr(sym_loc);1503 const sym = self.getSymbolPtr(sym_loc);
1507 try self.setSymbolName(sym, exp.options.name);1504 try self.setSymbolName(sym, exp_name);
1508 sym.value = decl_sym.value;1505 sym.value = decl_sym.value;
1509 sym.section_number = @intToEnum(coff.SectionNumber, self.text_section_index.? + 1);1506 sym.section_number = @intToEnum(coff.SectionNumber, self.text_section_index.? + 1);
1510 sym.type = .{ .complex_type = .FUNCTION, .base_type = .NULL };1507 sym.type = .{ .complex_type = .FUNCTION, .base_type = .NULL };
15111508
1512 switch (exp.options.linkage) {1509 switch (exp.linkage) {
1513 .Strong => {1510 .Strong => {
1514 sym.storage_class = .EXTERNAL;1511 sym.storage_class = .EXTERNAL;
1515 },1512 },
...@@ -1522,9 +1519,15 @@ pub fn updateDeclExports(...@@ -1522,9 +1519,15 @@ pub fn updateDeclExports(
1522 }1519 }
1523}1520}
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 {
1526 if (self.llvm_object) |_| return;1527 if (self.llvm_object) |_| return;
1527 const metadata = self.decls.getPtr(decl_index) orelse return;1528 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);
1528 const sym_index = metadata.getExportPtr(self, name) orelse return;1531 const sym_index = metadata.getExportPtr(self, name) orelse return;
15291532
1530 const gpa = self.base.allocator;1533 const gpa = self.base.allocator;
...@@ -2540,6 +2543,7 @@ const ImportTable = @import("Coff/ImportTable.zig");...@@ -2540,6 +2543,7 @@ const ImportTable = @import("Coff/ImportTable.zig");
2540const Liveness = @import("../Liveness.zig");2543const Liveness = @import("../Liveness.zig");
2541const LlvmObject = @import("../codegen/llvm.zig").Object;2544const LlvmObject = @import("../codegen/llvm.zig").Object;
2542const Module = @import("../Module.zig");2545const Module = @import("../Module.zig");
2546const InternPool = @import("../InternPool.zig");
2543const Object = @import("Coff/Object.zig");2547const Object = @import("Coff/Object.zig");
2544const Relocation = @import("Coff/Relocation.zig");2548const Relocation = @import("Coff/Relocation.zig");
2545const TableSection = @import("table_section.zig").TableSection;2549const TableSection = @import("table_section.zig").TableSection;
src/link/Dwarf.zig+8-17
...@@ -358,8 +358,9 @@ pub const DeclState = struct {...@@ -358,8 +358,9 @@ pub const DeclState = struct {
358 struct_obj.fields.keys(),358 struct_obj.fields.keys(),
359 struct_obj.fields.values(),359 struct_obj.fields.values(),
360 0..,360 0..,
361 ) |field_name, field, field_index| {361 ) |field_name_ip, field, field_index| {
362 if (!field.ty.hasRuntimeBits(mod)) continue;362 if (!field.ty.hasRuntimeBits(mod)) continue;
363 const field_name = mod.intern_pool.stringToSlice(field_name_ip);
363 // DW.AT.member364 // DW.AT.member
364 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);365 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
365 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));366 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
...@@ -469,7 +470,8 @@ pub const DeclState = struct {...@@ -469,7 +470,8 @@ pub const DeclState = struct {
469 // DW.AT.member470 // DW.AT.member
470 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));471 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));
471 // DW.AT.name, DW.FORM.string472 // 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);
473 // DW.AT.type, DW.FORM.ref4475 // DW.AT.type, DW.FORM.ref4
474 const index = dbg_info_buffer.items.len;476 const index = dbg_info_buffer.items.len;
475 try dbg_info_buffer.resize(index + 4);477 try dbg_info_buffer.resize(index + 4);
...@@ -949,8 +951,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)...@@ -949,8 +951,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
949 defer tracy.end();951 defer tracy.end();
950952
951 const decl = mod.declPtr(decl_index);953 const decl = mod.declPtr(decl_index);
952 const decl_name = try decl.getFullyQualifiedName(mod);954 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
953 defer self.allocator.free(decl_name);
954955
955 log.debug("initDeclState {s}{*}", .{ decl_name, decl });956 log.debug("initDeclState {s}{*}", .{ decl_name, decl });
956957
...@@ -1273,7 +1274,6 @@ pub fn commitDeclState(...@@ -1273,7 +1274,6 @@ pub fn commitDeclState(
1273 }1274 }
1274 }1275 }
12751276
1276 log.debug("updateDeclDebugInfoAllocation for '{s}'", .{decl.name});
1277 try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(u32, dbg_info_buffer.items.len));1277 try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(u32, dbg_info_buffer.items.len));
12781278
1279 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {1279 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
...@@ -1345,7 +1345,6 @@ pub fn commitDeclState(...@@ -1345,7 +1345,6 @@ pub fn commitDeclState(
1345 }1345 }
1346 }1346 }
13471347
1348 log.debug("writeDeclDebugInfo for '{s}", .{decl.name});
1349 try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);1348 try self.writeDeclDebugInfo(di_atom_index, dbg_info_buffer.items);
1350}1349}
13511350
...@@ -2523,15 +2522,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {...@@ -2523,15 +2522,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
25232522
2524 // TODO: don't create a zig type for this, just make the dwarf info2523 // TODO: don't create a zig type for this, just make the dwarf info
2525 // without touching the zig type system.2524 // without touching the zig type system.
2526 const names = try arena.alloc(InternPool.NullTerminatedString, module.global_error_set.count());2525 const names = try arena.dupe(InternPool.NullTerminatedString, module.global_error_set.keys());
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
2535 std.mem.sort(InternPool.NullTerminatedString, names, {}, InternPool.NullTerminatedString.indexLessThan);2526 std.mem.sort(InternPool.NullTerminatedString, names, {}, InternPool.NullTerminatedString.indexLessThan);
25362527
2537 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });2528 const error_ty = try module.intern(.{ .error_set_type = .{ .names = names } });
...@@ -2682,8 +2673,8 @@ fn addDbgInfoErrorSet(...@@ -2682,8 +2673,8 @@ fn addDbgInfoErrorSet(
26822673
2683 const error_names = ty.errorSetNames(mod);2674 const error_names = ty.errorSetNames(mod);
2684 for (error_names) |error_name_ip| {2675 for (error_names) |error_name_ip| {
2676 const int = try mod.getErrorValue(error_name_ip);
2685 const error_name = mod.intern_pool.stringToSlice(error_name_ip);2677 const error_name = mod.intern_pool.stringToSlice(error_name_ip);
2686 const kv = mod.getErrorValue(error_name) catch unreachable;
2687 // DW.AT.enumerator2678 // DW.AT.enumerator
2688 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));2679 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));
2689 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));2680 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
...@@ -2691,7 +2682,7 @@ fn addDbgInfoErrorSet(...@@ -2691,7 +2682,7 @@ fn addDbgInfoErrorSet(
2691 dbg_info_buffer.appendSliceAssumeCapacity(error_name);2682 dbg_info_buffer.appendSliceAssumeCapacity(error_name);
2692 dbg_info_buffer.appendAssumeCapacity(0);2683 dbg_info_buffer.appendAssumeCapacity(0);
2693 // DW.AT.const_value, DW.FORM.data82684 // 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);
2695 }2686 }
26962687
2697 // DW.AT.enumeration_type delimit children2688 // DW.AT.enumeration_type delimit children
src/link/Elf.zig+18-15
...@@ -28,6 +28,7 @@ const File = link.File;...@@ -28,6 +28,7 @@ const File = link.File;
28const Liveness = @import("../Liveness.zig");28const Liveness = @import("../Liveness.zig");
29const LlvmObject = @import("../codegen/llvm.zig").Object;29const LlvmObject = @import("../codegen/llvm.zig").Object;
30const Module = @import("../Module.zig");30const Module = @import("../Module.zig");
31const InternPool = @import("../InternPool.zig");
31const Package = @import("../Package.zig");32const Package = @import("../Package.zig");
32const StringTable = @import("strtab.zig").StringTable;33const StringTable = @import("strtab.zig").StringTable;
33const TableSection = @import("table_section.zig").TableSection;34const TableSection = @import("table_section.zig").TableSection;
...@@ -2480,8 +2481,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s...@@ -2480,8 +2481,7 @@ fn updateDeclCode(self: *Elf, decl_index: Module.Decl.Index, code: []const u8, s
2480 const mod = self.base.options.module.?;2481 const mod = self.base.options.module.?;
2481 const decl = mod.declPtr(decl_index);2482 const decl = mod.declPtr(decl_index);
24822483
2483 const decl_name = try decl.getFullyQualifiedName(mod);2484 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
2484 defer self.base.allocator.free(decl_name);
24852485
2486 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });2486 log.debug("updateDeclCode {s}{*}", .{ decl_name, decl });
2487 const required_alignment = decl.getAlignment(mod);2487 const required_alignment = decl.getAlignment(mod);
...@@ -2802,8 +2802,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module...@@ -2802,8 +2802,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
28022802
2803 const decl = mod.declPtr(decl_index);2803 const decl = mod.declPtr(decl_index);
2804 const name_str_index = blk: {2804 const name_str_index = blk: {
2805 const decl_name = try decl.getFullyQualifiedName(mod);2805 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
2806 defer gpa.free(decl_name);
2807 const index = unnamed_consts.items.len;2806 const index = unnamed_consts.items.len;
2808 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });2807 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
2809 defer gpa.free(name);2808 defer gpa.free(name);
...@@ -2880,7 +2879,8 @@ pub fn updateDeclExports(...@@ -2880,7 +2879,8 @@ pub fn updateDeclExports(
2880 try self.global_symbols.ensureUnusedCapacity(gpa, exports.len);2879 try self.global_symbols.ensureUnusedCapacity(gpa, exports.len);
28812880
2882 for (exports) |exp| {2881 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| {
2884 if (!mem.eql(u8, section_name, ".text")) {2884 if (!mem.eql(u8, section_name, ".text")) {
2885 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);2885 try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1);
2886 mod.failed_exports.putAssumeCapacityNoClobber(2886 mod.failed_exports.putAssumeCapacityNoClobber(
...@@ -2890,11 +2890,11 @@ pub fn updateDeclExports(...@@ -2890,11 +2890,11 @@ pub fn updateDeclExports(
2890 continue;2890 continue;
2891 }2891 }
2892 }2892 }
2893 const stb_bits: u8 = switch (exp.options.linkage) {2893 const stb_bits: u8 = switch (exp.linkage) {
2894 .Internal => elf.STB_LOCAL,2894 .Internal => elf.STB_LOCAL,
2895 .Strong => blk: {2895 .Strong => blk: {
2896 const entry_name = self.base.options.entry orelse "_start";2896 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)) {
2898 self.entry_addr = decl_sym.st_value;2898 self.entry_addr = decl_sym.st_value;
2899 }2899 }
2900 break :blk elf.STB_GLOBAL;2900 break :blk elf.STB_GLOBAL;
...@@ -2910,10 +2910,10 @@ pub fn updateDeclExports(...@@ -2910,10 +2910,10 @@ pub fn updateDeclExports(
2910 },2910 },
2911 };2911 };
2912 const stt_bits: u8 = @truncate(u4, decl_sym.st_info);2912 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| {
2914 const sym = &self.global_symbols.items[i];2914 const sym = &self.global_symbols.items[i];
2915 sym.* = .{2915 sym.* = .{
2916 .st_name = try self.shstrtab.insert(gpa, exp.options.name),2916 .st_name = try self.shstrtab.insert(gpa, exp_name),
2917 .st_info = (stb_bits << 4) | stt_bits,2917 .st_info = (stb_bits << 4) | stt_bits,
2918 .st_other = 0,2918 .st_other = 0,
2919 .st_shndx = shdr_index,2919 .st_shndx = shdr_index,
...@@ -2927,7 +2927,7 @@ pub fn updateDeclExports(...@@ -2927,7 +2927,7 @@ pub fn updateDeclExports(
2927 };2927 };
2928 try decl_metadata.exports.append(gpa, @intCast(u32, i));2928 try decl_metadata.exports.append(gpa, @intCast(u32, i));
2929 self.global_symbols.items[i] = .{2929 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),
2931 .st_info = (stb_bits << 4) | stt_bits,2931 .st_info = (stb_bits << 4) | stt_bits,
2932 .st_other = 0,2932 .st_other = 0,
2933 .st_shndx = shdr_index,2933 .st_shndx = shdr_index,
...@@ -2944,8 +2944,7 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: Module.Decl.In...@@ -2944,8 +2944,7 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: Module.Decl.In
2944 defer tracy.end();2944 defer tracy.end();
29452945
2946 const decl = mod.declPtr(decl_index);2946 const decl = mod.declPtr(decl_index);
2947 const decl_name = try decl.getFullyQualifiedName(mod);2947 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
2948 defer self.base.allocator.free(decl_name);
29492948
2950 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });2949 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
29512950
...@@ -2955,11 +2954,15 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: Module.Decl.In...@@ -2955,11 +2954,15 @@ pub fn updateDeclLineNumber(self: *Elf, mod: *Module, decl_index: Module.Decl.In
2955 }2954 }
2956}2955}
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 {
2959 if (self.llvm_object) |_| return;2962 if (self.llvm_object) |_| return;
2960 const metadata = self.decls.getPtr(decl_index) orelse return;2963 const metadata = self.decls.getPtr(decl_index) orelse return;
2961 const sym_index = metadata.getExportPtr(self, name) orelse return;2964 const mod = self.base.options.module.?;
2962 log.debug("deleting export '{s}'", .{name});2965 const sym_index = metadata.getExportPtr(self, mod.intern_pool.stringToSlice(name)) orelse return;
2963 self.global_symbol_free_list.append(self.base.allocator, sym_index.*) catch {};2966 self.global_symbol_free_list.append(self.base.allocator, sym_index.*) catch {};
2964 self.global_symbols.items[sym_index.*].st_info = 0;2967 self.global_symbols.items[sym_index.*].st_info = 0;
2965 sym_index.* = 0;2968 sym_index.* = 0;
src/link/MachO.zig+17-12
...@@ -40,6 +40,7 @@ const Liveness = @import("../Liveness.zig");...@@ -40,6 +40,7 @@ const Liveness = @import("../Liveness.zig");
40const LlvmObject = @import("../codegen/llvm.zig").Object;40const LlvmObject = @import("../codegen/llvm.zig").Object;
41const Md5 = std.crypto.hash.Md5;41const Md5 = std.crypto.hash.Md5;
42const Module = @import("../Module.zig");42const Module = @import("../Module.zig");
43const InternPool = @import("../InternPool.zig");
43const Relocation = @import("MachO/Relocation.zig");44const Relocation = @import("MachO/Relocation.zig");
44const StringTable = @import("strtab.zig").StringTable;45const StringTable = @import("strtab.zig").StringTable;
45const TableSection = @import("table_section.zig").TableSection;46const TableSection = @import("table_section.zig").TableSection;
...@@ -1921,8 +1922,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu...@@ -1921,8 +1922,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
1921 const unnamed_consts = gop.value_ptr;1922 const unnamed_consts = gop.value_ptr;
19221923
1923 const decl = mod.declPtr(decl_index);1924 const decl = mod.declPtr(decl_index);
1924 const decl_name = try decl.getFullyQualifiedName(mod);1925 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1925 defer gpa.free(decl_name);
19261926
1927 const name_str_index = blk: {1927 const name_str_index = blk: {
1928 const index = unnamed_consts.items.len;1928 const index = unnamed_consts.items.len;
...@@ -2206,8 +2206,7 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D...@@ -2206,8 +2206,7 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D
22062206
2207 const required_alignment = decl.getAlignment(mod);2207 const required_alignment = decl.getAlignment(mod);
22082208
2209 const decl_name = try decl.getFullyQualifiedName(module);2209 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(module));
2210 defer gpa.free(decl_name);
22112210
2212 const init_sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{decl_name});2211 const init_sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{decl_name});
2213 defer gpa.free(init_sym_name);2212 defer gpa.free(init_sym_name);
...@@ -2306,8 +2305,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64...@@ -2306,8 +2305,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
23062305
2307 const required_alignment = decl.getAlignment(mod);2306 const required_alignment = decl.getAlignment(mod);
23082307
2309 const decl_name = try decl.getFullyQualifiedName(mod);2308 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
2310 defer gpa.free(decl_name);
23112309
2312 const decl_metadata = self.decls.get(decl_index).?;2310 const decl_metadata = self.decls.get(decl_index).?;
2313 const atom_index = decl_metadata.atom;2311 const atom_index = decl_metadata.atom;
...@@ -2403,12 +2401,14 @@ pub fn updateDeclExports(...@@ -2403,12 +2401,14 @@ pub fn updateDeclExports(
2403 const decl_metadata = self.decls.getPtr(decl_index).?;2401 const decl_metadata = self.decls.getPtr(decl_index).?;
24042402
2405 for (exports) |exp| {2403 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 });
2407 defer gpa.free(exp_name);2407 defer gpa.free(exp_name);
24082408
2409 log.debug("adding new export '{s}'", .{exp_name});2409 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| {
2412 if (!mem.eql(u8, section_name, "__text")) {2412 if (!mem.eql(u8, section_name, "__text")) {
2413 try mod.failed_exports.putNoClobber(2413 try mod.failed_exports.putNoClobber(
2414 mod.gpa,2414 mod.gpa,
...@@ -2424,7 +2424,7 @@ pub fn updateDeclExports(...@@ -2424,7 +2424,7 @@ pub fn updateDeclExports(
2424 }2424 }
2425 }2425 }
24262426
2427 if (exp.options.linkage == .LinkOnce) {2427 if (exp.linkage == .LinkOnce) {
2428 try mod.failed_exports.putNoClobber(2428 try mod.failed_exports.putNoClobber(
2429 mod.gpa,2429 mod.gpa,
2430 exp,2430 exp,
...@@ -2453,7 +2453,7 @@ pub fn updateDeclExports(...@@ -2453,7 +2453,7 @@ pub fn updateDeclExports(
2453 .n_value = decl_sym.n_value,2453 .n_value = decl_sym.n_value,
2454 };2454 };
24552455
2456 switch (exp.options.linkage) {2456 switch (exp.linkage) {
2457 .Internal => {2457 .Internal => {
2458 // Symbol should be hidden, or in MachO lingo, private extern.2458 // Symbol should be hidden, or in MachO lingo, private extern.
2459 // We should also mark the symbol as Weak: n_desc == N_WEAK_DEF.2459 // We should also mark the symbol as Weak: n_desc == N_WEAK_DEF.
...@@ -2488,12 +2488,17 @@ pub fn updateDeclExports(...@@ -2488,12 +2488,17 @@ pub fn updateDeclExports(
2488 }2488 }
2489}2489}
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 {
2492 if (self.llvm_object) |_| return;2496 if (self.llvm_object) |_| return;
2493 const metadata = self.decls.getPtr(decl_index) orelse return;2497 const metadata = self.decls.getPtr(decl_index) orelse return;
24942498
2495 const gpa = self.base.allocator;2499 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)});
2497 defer gpa.free(exp_name);2502 defer gpa.free(exp_name);
2498 const sym_index = metadata.getExportPtr(self, exp_name) orelse return;2503 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:...@@ -287,7 +287,6 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: Module.Fn.Index, air:
287 self.freeUnnamedConsts(decl_index);287 self.freeUnnamedConsts(decl_index);
288288
289 _ = try self.seeDecl(decl_index);289 _ = try self.seeDecl(decl_index);
290 log.debug("codegen decl {*} ({s})", .{ decl, decl.name });
291290
292 var code_buffer = std.ArrayList(u8).init(self.base.allocator);291 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
293 defer code_buffer.deinit();292 defer code_buffer.deinit();
...@@ -345,8 +344,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I...@@ -345,8 +344,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: Module.Decl.I
345 }344 }
346 const unnamed_consts = gop.value_ptr;345 const unnamed_consts = gop.value_ptr;
347346
348 const decl_name = try decl.getFullyQualifiedName(mod);347 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
349 defer self.base.allocator.free(decl_name);
350348
351 const index = unnamed_consts.items.len;349 const index = unnamed_consts.items.len;
352 // name is freed when the unnamed const is freed350 // 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...@@ -403,8 +401,6 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: Module.Decl.Index) !vo
403401
404 _ = try self.seeDecl(decl_index);402 _ = try self.seeDecl(decl_index);
405403
406 log.debug("codegen decl {*} ({s}) ({d})", .{ decl, decl.name, decl_index });
407
408 var code_buffer = std.ArrayList(u8).init(self.base.allocator);404 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
409 defer code_buffer.deinit();405 defer code_buffer.deinit();
410 const decl_val = if (decl.val.getVariable(mod)) |variable| variable.init.toValue() else decl.val;406 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 {...@@ -435,7 +431,6 @@ fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void {
435 const mod = self.base.options.module.?;431 const mod = self.base.options.module.?;
436 const decl = mod.declPtr(decl_index);432 const decl = mod.declPtr(decl_index);
437 const is_fn = (decl.ty.zigTypeTag(mod) == .Fn);433 const is_fn = (decl.ty.zigTypeTag(mod) == .Fn);
438 log.debug("update the symbol table and got for decl {*} ({s})", .{ decl, decl.name });
439 const sym_t: aout.Sym.Type = if (is_fn) .t else .d;434 const sym_t: aout.Sym.Type = if (is_fn) .t else .d;
440435
441 const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);436 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 {...@@ -446,7 +441,7 @@ fn updateFinish(self: *Plan9, decl_index: Module.Decl.Index) !void {
446 const sym: aout.Sym = .{441 const sym: aout.Sym = .{
447 .value = undefined, // the value of stuff gets filled in in flushModule442 .value = undefined, // the value of stuff gets filled in in flushModule
448 .type = decl_block.type,443 .type = decl_block.type,
449 .name = mem.span(decl.name),444 .name = mod.intern_pool.stringToSlice(decl.name),
450 };445 };
451446
452 if (decl_block.sym_index) |s| {447 if (decl_block.sym_index) |s| {
...@@ -567,10 +562,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -567,10 +562,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
567 var it = fentry.value_ptr.functions.iterator();562 var it = fentry.value_ptr.functions.iterator();
568 while (it.next()) |entry| {563 while (it.next()) |entry| {
569 const decl_index = entry.key_ptr.*;564 const decl_index = entry.key_ptr.*;
570 const decl = mod.declPtr(decl_index);
571 const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);565 const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);
572 const out = entry.value_ptr.*;566 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 });
574 {567 {
575 // connect the previous decl to the next568 // connect the previous decl to the next
576 const delta_line = @intCast(i32, out.start_line) - @intCast(i32, linecount);569 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...@@ -616,10 +609,8 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
616 var it = self.data_decl_table.iterator();609 var it = self.data_decl_table.iterator();
617 while (it.next()) |entry| {610 while (it.next()) |entry| {
618 const decl_index = entry.key_ptr.*;611 const decl_index = entry.key_ptr.*;
619 const decl = mod.declPtr(decl_index);
620 const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);612 const decl_block = self.getDeclBlockPtr(self.decls.get(decl_index).?.index);
621 const code = entry.value_ptr.*;613 const code = entry.value_ptr.*;
622 log.debug("write data decl {*} ({s})", .{ decl, decl.name });
623614
624 foff += code.len;615 foff += code.len;
625 iovecs[iovecs_i] = .{ .iov_base = code.ptr, .iov_len = code.len };616 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...@@ -695,15 +686,12 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
695 const source_decl = mod.declPtr(source_decl_index);686 const source_decl = mod.declPtr(source_decl_index);
696 for (kv.value_ptr.items) |reloc| {687 for (kv.value_ptr.items) |reloc| {
697 const target_decl_index = reloc.target;688 const target_decl_index = reloc.target;
698 const target_decl = mod.declPtr(target_decl_index);
699 const target_decl_block = self.getDeclBlock(self.decls.get(target_decl_index).?.index);689 const target_decl_block = self.getDeclBlock(self.decls.get(target_decl_index).?.index);
700 const target_decl_offset = target_decl_block.offset.?;690 const target_decl_offset = target_decl_block.offset.?;
701691
702 const offset = reloc.offset;692 const offset = reloc.offset;
703 const addend = reloc.addend;693 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
707 const code = blk: {695 const code = blk: {
708 const is_fn = source_decl.ty.zigTypeTag(mod) == .Fn;696 const is_fn = source_decl.ty.zigTypeTag(mod) == .Fn;
709 if (is_fn) {697 if (is_fn) {
...@@ -737,8 +725,9 @@ fn addDeclExports(...@@ -737,8 +725,9 @@ fn addDeclExports(
737 const decl_block = self.getDeclBlock(metadata.index);725 const decl_block = self.getDeclBlock(metadata.index);
738726
739 for (exports) |exp| {727 for (exports) |exp| {
728 const exp_name = mod.intern_pool.stringToSlice(exp.name);
740 // plan9 does not support custom sections729 // plan9 does not support custom sections
741 if (exp.options.section) |section_name| {730 if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section_name| {
742 if (!mem.eql(u8, section_name, ".text") or !mem.eql(u8, section_name, ".data")) {731 if (!mem.eql(u8, section_name, ".text") or !mem.eql(u8, section_name, ".data")) {
743 try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(732 try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
744 self.base.allocator,733 self.base.allocator,
...@@ -752,10 +741,10 @@ fn addDeclExports(...@@ -752,10 +741,10 @@ fn addDeclExports(
752 const sym = .{741 const sym = .{
753 .value = decl_block.offset.?,742 .value = decl_block.offset.?,
754 .type = decl_block.type.toGlobal(),743 .type = decl_block.type.toGlobal(),
755 .name = exp.options.name,744 .name = exp_name,
756 };745 };
757746
758 if (metadata.getExport(self, exp.options.name)) |i| {747 if (metadata.getExport(self, exp_name)) |i| {
759 self.syms.items[i] = sym;748 self.syms.items[i] = sym;
760 } else {749 } else {
761 try self.syms.append(self.base.allocator, sym);750 try self.syms.append(self.base.allocator, sym);
...@@ -956,7 +945,10 @@ pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void {...@@ -956,7 +945,10 @@ pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void {
956 try w.writeAll(sym.name);945 try w.writeAll(sym.name);
957 try w.writeByte(0);946 try w.writeByte(0);
958}947}
948
959pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {949pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
950 const mod = self.base.options.module.?;
951 const ip = &mod.intern_pool;
960 const writer = buf.writer();952 const writer = buf.writer();
961 // write the f symbols953 // write the f symbols
962 {954 {
...@@ -980,7 +972,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -980,7 +972,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
980 const sym = self.syms.items[decl_block.sym_index.?];972 const sym = self.syms.items[decl_block.sym_index.?];
981 try self.writeSym(writer, sym);973 try self.writeSym(writer, sym);
982 if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {974 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| {
984 try self.writeSym(writer, self.syms.items[exp_i]);976 try self.writeSym(writer, self.syms.items[exp_i]);
985 };977 };
986 }978 }
...@@ -1006,7 +998,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {...@@ -1006,7 +998,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
1006 const sym = self.syms.items[decl_block.sym_index.?];998 const sym = self.syms.items[decl_block.sym_index.?];
1007 try self.writeSym(writer, sym);999 try self.writeSym(writer, sym);
1008 if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {1000 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| {
1010 const s = self.syms.items[exp_i];1002 const s = self.syms.items[exp_i];
1011 if (mem.eql(u8, s.name, "_start"))1003 if (mem.eql(u8, s.name, "_start"))
1012 self.entry_val = s.value;1004 self.entry_val = s.value;
src/link/SpirV.zig+3-2
...@@ -147,7 +147,7 @@ pub fn updateDeclExports(...@@ -147,7 +147,7 @@ pub fn updateDeclExports(
147 const spv_decl_index = entry.value_ptr.*;147 const spv_decl_index = entry.value_ptr.*;
148148
149 for (exports) |exp| {149 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));
151 }151 }
152 }152 }
153153
...@@ -190,7 +190,8 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No...@@ -190,7 +190,8 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
190 var error_info = std.ArrayList(u8).init(self.spv.arena);190 var error_info = std.ArrayList(u8).init(self.spv.arena);
191 try error_info.appendSlice("zig_errors");191 try error_info.appendSlice("zig_errors");
192 const module = self.base.options.module.?;192 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);
194 // Errors can contain pretty much any character - to encode them in a string we must escape195 // Errors can contain pretty much any character - to encode them in a string we must escape
195 // them somehow. Easiest here is to use some established scheme, one which also preseves the196 // them somehow. Easiest here is to use some established scheme, one which also preseves the
196 // name if it contains no strange characters is nice for debugging. URI encoding fits the bill.197 // 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...@@ -1416,7 +1416,7 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi
14161416
1417 if (decl.isExtern(mod)) {1417 if (decl.isExtern(mod)) {
1418 const variable = decl.getOwnedVariable(mod).?;1418 const variable = decl.getOwnedVariable(mod).?;
1419 const name = mem.sliceTo(decl.name, 0);1419 const name = mod.intern_pool.stringToSlice(decl.name);
1420 const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);1420 const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);
1421 return wasm.addOrUpdateImport(name, atom.sym_index, lib_name, null);1421 return wasm.addOrUpdateImport(name, atom.sym_index, lib_name, null);
1422 }1422 }
...@@ -1453,8 +1453,7 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.I...@@ -1453,8 +1453,7 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: Module.Decl.I
1453 defer tracy.end();1453 defer tracy.end();
14541454
1455 const decl = mod.declPtr(decl_index);1455 const decl = mod.declPtr(decl_index);
1456 const decl_name = try decl.getFullyQualifiedName(mod);1456 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1457 defer wasm.base.allocator.free(decl_name);
14581457
1459 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });1458 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
1460 try dw.updateDeclLineNumber(mod, decl_index);1459 try dw.updateDeclLineNumber(mod, decl_index);
...@@ -1467,8 +1466,7 @@ fn finishUpdateDecl(wasm: *Wasm, decl_index: Module.Decl.Index, code: []const u8...@@ -1467,8 +1466,7 @@ fn finishUpdateDecl(wasm: *Wasm, decl_index: Module.Decl.Index, code: []const u8
1467 const atom_index = wasm.decls.get(decl_index).?;1466 const atom_index = wasm.decls.get(decl_index).?;
1468 const atom = wasm.getAtomPtr(atom_index);1467 const atom = wasm.getAtomPtr(atom_index);
1469 const symbol = &wasm.symbols.items[atom.sym_index];1468 const symbol = &wasm.symbols.items[atom.sym_index];
1470 const full_name = try decl.getFullyQualifiedName(mod);1469 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1471 defer wasm.base.allocator.free(full_name);
1472 symbol.name = try wasm.string_table.put(wasm.base.allocator, full_name);1470 symbol.name = try wasm.string_table.put(wasm.base.allocator, full_name);
1473 try atom.code.appendSlice(wasm.base.allocator, code);1471 try atom.code.appendSlice(wasm.base.allocator, code);
1474 try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {});1472 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...@@ -1535,9 +1533,10 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In
1535 const parent_atom = wasm.getAtomPtr(parent_atom_index);1533 const parent_atom = wasm.getAtomPtr(parent_atom_index);
1536 const local_index = parent_atom.locals.items.len;1534 const local_index = parent_atom.locals.items.len;
1537 try parent_atom.locals.append(wasm.base.allocator, atom_index);1535 try parent_atom.locals.append(wasm.base.allocator, atom_index);
1538 const fqdn = try decl.getFullyQualifiedName(mod);1536 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1539 defer wasm.base.allocator.free(fqdn);1537 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{
1540 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{ fqdn, local_index });1538 fqn, local_index,
1539 });
1541 defer wasm.base.allocator.free(name);1540 defer wasm.base.allocator.free(name);
1542 var value_bytes = std.ArrayList(u8).init(wasm.base.allocator);1541 var value_bytes = std.ArrayList(u8).init(wasm.base.allocator);
1543 defer value_bytes.deinit();1542 defer value_bytes.deinit();
...@@ -1690,11 +1689,12 @@ pub fn updateDeclExports(...@@ -1690,11 +1689,12 @@ pub fn updateDeclExports(
1690 const decl = mod.declPtr(decl_index);1689 const decl = mod.declPtr(decl_index);
1691 const atom_index = try wasm.getOrCreateAtomForDecl(decl_index);1690 const atom_index = try wasm.getOrCreateAtomForDecl(decl_index);
1692 const atom = wasm.getAtom(atom_index);1691 const atom = wasm.getAtom(atom_index);
1692 const gpa = mod.gpa;
16931693
1694 for (exports) |exp| {1694 for (exports) |exp| {
1695 if (exp.options.section) |section| {1695 if (mod.intern_pool.stringToSliceUnwrap(exp.section)) |section| {
1696 try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(1696 try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create(
1697 mod.gpa,1697 gpa,
1698 decl.srcLoc(mod),1698 decl.srcLoc(mod),
1699 "Unimplemented: ExportOptions.section '{s}'",1699 "Unimplemented: ExportOptions.section '{s}'",
1700 .{section},1700 .{section},
...@@ -1702,24 +1702,24 @@ pub fn updateDeclExports(...@@ -1702,24 +1702,24 @@ pub fn updateDeclExports(
1702 continue;1702 continue;
1703 }1703 }
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));
1706 if (wasm.globals.getPtr(export_name)) |existing_loc| {1706 if (wasm.globals.getPtr(export_name)) |existing_loc| {
1707 if (existing_loc.index == atom.sym_index) continue;1707 if (existing_loc.index == atom.sym_index) continue;
1708 const existing_sym: Symbol = existing_loc.getSymbol(wasm).*;1708 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;
1711 // When both the to-be-exported symbol and the already existing symbol1711 // When both the to-be-exported symbol and the already existing symbol
1712 // are strong symbols, we have a linker error.1712 // are strong symbols, we have a linker error.
1713 // In the other case we replace one with the other.1713 // In the other case we replace one with the other.
1714 if (!exp_is_weak and !existing_sym.isWeak()) {1714 if (!exp_is_weak and !existing_sym.isWeak()) {
1715 try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(1715 try mod.failed_exports.put(gpa, exp, try Module.ErrorMsg.create(
1716 mod.gpa,1716 gpa,
1717 decl.srcLoc(mod),1717 decl.srcLoc(mod),
1718 \\LinkError: symbol '{s}' defined multiple times1718 \\LinkError: symbol '{s}' defined multiple times
1719 \\ first definition in '{s}'1719 \\ first definition in '{s}'
1720 \\ next definition in '{s}'1720 \\ next definition in '{s}'
1721 ,1721 ,
1722 .{ exp.options.name, wasm.name, wasm.name },1722 .{ mod.intern_pool.stringToSlice(exp.name), wasm.name, wasm.name },
1723 ));1723 ));
1724 continue;1724 continue;
1725 } else if (exp_is_weak) {1725 } else if (exp_is_weak) {
...@@ -1736,7 +1736,7 @@ pub fn updateDeclExports(...@@ -1736,7 +1736,7 @@ pub fn updateDeclExports(
1736 const exported_atom = wasm.getAtom(exported_atom_index);1736 const exported_atom = wasm.getAtom(exported_atom_index);
1737 const sym_loc = exported_atom.symbolLoc();1737 const sym_loc = exported_atom.symbolLoc();
1738 const symbol = sym_loc.getSymbol(wasm);1738 const symbol = sym_loc.getSymbol(wasm);
1739 switch (exp.options.linkage) {1739 switch (exp.linkage) {
1740 .Internal => {1740 .Internal => {
1741 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);1741 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
1742 },1742 },
...@@ -1745,8 +1745,8 @@ pub fn updateDeclExports(...@@ -1745,8 +1745,8 @@ pub fn updateDeclExports(
1745 },1745 },
1746 .Strong => {}, // symbols are strong by default1746 .Strong => {}, // symbols are strong by default
1747 .LinkOnce => {1747 .LinkOnce => {
1748 try mod.failed_exports.putNoClobber(mod.gpa, exp, try Module.ErrorMsg.create(1748 try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create(
1749 mod.gpa,1749 gpa,
1750 decl.srcLoc(mod),1750 decl.srcLoc(mod),
1751 "Unimplemented: LinkOnce",1751 "Unimplemented: LinkOnce",
1752 .{},1752 .{},
...@@ -1755,7 +1755,7 @@ pub fn updateDeclExports(...@@ -1755,7 +1755,7 @@ pub fn updateDeclExports(
1755 },1755 },
1756 }1756 }
1757 // Ensure the symbol will be exported using the given name1757 // 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))) {
1759 try wasm.export_names.put(wasm.base.allocator, sym_loc, export_name);1759 try wasm.export_names.put(wasm.base.allocator, sym_loc, export_name);
1760 }1760 }
17611761
...@@ -1769,7 +1769,7 @@ pub fn updateDeclExports(...@@ -1769,7 +1769,7 @@ pub fn updateDeclExports(
17691769
1770 // if the symbol was previously undefined, remove it as an import1770 // if the symbol was previously undefined, remove it as an import
1771 _ = wasm.imports.remove(sym_loc);1771 _ = wasm.imports.remove(sym_loc);
1772 _ = wasm.undefs.swapRemove(exp.options.name);1772 _ = wasm.undefs.swapRemove(mod.intern_pool.stringToSlice(exp.name));
1773 }1773 }
1774}1774}
17751775
...@@ -2987,7 +2987,8 @@ fn populateErrorNameTable(wasm: *Wasm) !void {...@@ -2987,7 +2987,8 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
2987 // Addend for each relocation to the table2987 // Addend for each relocation to the table
2988 var addend: u32 = 0;2988 var addend: u32 = 0;
2989 const mod = wasm.base.options.module.?;2989 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);
2991 const len = @intCast(u32, error_name.len + 1); // names are 0-termianted2992 const len = @intCast(u32, error_name.len + 1); // names are 0-termianted
29922993
2993 const slice_ty = Type.slice_const_u8_sentinel_0;2994 const slice_ty = Type.slice_const_u8_sentinel_0;
src/print_air.zig+2-1
...@@ -685,8 +685,9 @@ const Writer = struct {...@@ -685,8 +685,9 @@ const Writer = struct {
685 fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {685 fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
686 const ty_fn = w.air.instructions.items(.data)[inst].ty_fn;686 const ty_fn = w.air.instructions.items(.data)[inst].ty_fn;
687 const func_index = ty_fn.func;687 const func_index = ty_fn.func;
688 const ip = &w.module.intern_pool;
688 const owner_decl = w.module.declPtr(w.module.funcPtr(func_index).owner_decl);689 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)});
690 }691 }
691692
692 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {693 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 {...@@ -2546,7 +2546,7 @@ pub const Type = struct {
2546 defer mod.gpa.free(field_vals);2546 defer mod.gpa.free(field_vals);
2547 for (field_vals, s.fields.values()) |*field_val, field| {2547 for (field_vals, s.fields.values()) |*field_val, field| {
2548 if (field.is_comptime) {2548 if (field.is_comptime) {
2549 field_val.* = try field.default_val.intern(field.ty, mod);2549 field_val.* = field.default_val;
2550 continue;2550 continue;
2551 }2551 }
2552 if (try field.ty.onePossibleValue(mod)) |field_opv| {2552 if (try field.ty.onePossibleValue(mod)) |field_opv| {
...@@ -2977,18 +2977,14 @@ pub const Type = struct {...@@ -2977,18 +2977,14 @@ pub const Type = struct {
2977 return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names.len;2977 return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names.len;
2978 }2978 }
29792979
2980 pub fn enumFieldName(ty: Type, field_index: usize, mod: *Module) [:0]const u8 {2980 pub fn enumFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString {
2981 const ip = &mod.intern_pool;2981 return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names[field_index];
2982 const field_name = ip.indexToKey(ty.toIntern()).enum_type.names[field_index];
2983 return ip.stringToSlice(field_name);
2984 }2982 }
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 {
2987 const ip = &mod.intern_pool;2985 const ip = &mod.intern_pool;
2988 const enum_type = ip.indexToKey(ty.toIntern()).enum_type;2986 const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
2989 // If the string is not interned, then the field certainly is not present.2987 return enum_type.nameIndex(ip, field_name);
2990 const field_name_interned = ip.getString(field_name).unwrap() orelse return null;
2991 return enum_type.nameIndex(ip, field_name_interned);
2992 }2988 }
29932989
2994 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or2990 /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or
...@@ -3017,19 +3013,16 @@ pub const Type = struct {...@@ -3017,19 +3013,16 @@ pub const Type = struct {
3017 }3013 }
3018 }3014 }
30193015
3020 pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) []const u8 {3016 pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString {
3021 switch (mod.intern_pool.indexToKey(ty.toIntern())) {3017 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3022 .struct_type => |struct_type| {3018 .struct_type => |struct_type| {
3023 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;3019 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3024 assert(struct_obj.haveFieldTypes());3020 assert(struct_obj.haveFieldTypes());
3025 return struct_obj.fields.keys()[field_index];3021 return struct_obj.fields.keys()[field_index];
3026 },3022 },
3027 .anon_struct_type => |anon_struct| {3023 .anon_struct_type => |anon_struct| anon_struct.names[field_index],
3028 const name = anon_struct.names[field_index];
3029 return mod.intern_pool.stringToSlice(name);
3030 },
3031 else => unreachable,3024 else => unreachable,
3032 }3025 };
3033 }3026 }
30343027
3035 pub fn structFieldCount(ty: Type, mod: *Module) usize {3028 pub fn structFieldCount(ty: Type, mod: *Module) usize {
...@@ -3082,7 +3075,10 @@ pub const Type = struct {...@@ -3082,7 +3075,10 @@ pub const Type = struct {
3082 switch (mod.intern_pool.indexToKey(ty.toIntern())) {3075 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3083 .struct_type => |struct_type| {3076 .struct_type => |struct_type| {
3084 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;3077 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();
3086 },3082 },
3087 .anon_struct_type => |anon_struct| {3083 .anon_struct_type => |anon_struct| {
3088 const val = anon_struct.values[index];3084 const val = anon_struct.values[index];
...@@ -3100,7 +3096,7 @@ pub const Type = struct {...@@ -3100,7 +3096,7 @@ pub const Type = struct {
3100 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;3096 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3101 const field = struct_obj.fields.values()[index];3097 const field = struct_obj.fields.values()[index];
3102 if (field.is_comptime) {3098 if (field.is_comptime) {
3103 return field.default_val;3099 return field.default_val.toValue();
3104 } else {3100 } else {
3105 return field.ty.onePossibleValue(mod);3101 return field.ty.onePossibleValue(mod);
3106 }3102 }
src/value.zig+70-46
...@@ -24,9 +24,6 @@ pub const Value = struct {...@@ -24,9 +24,6 @@ pub const Value = struct {
24 /// This union takes advantage of the fact that the first page of memory24 /// This union takes advantage of the fact that the first page of memory
25 /// is unmapped, giving us 4096 possible enum tags that have no payload.25 /// is unmapped, giving us 4096 possible enum tags that have no payload.
26 legacy: extern union {26 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,
30 ptr_otherwise: *Payload,27 ptr_otherwise: *Payload,
31 },28 },
3229
...@@ -64,8 +61,6 @@ pub const Value = struct {...@@ -64,8 +61,6 @@ pub const Value = struct {
64 /// An instance of a union.61 /// An instance of a union.
65 @"union",62 @"union",
6663
67 pub const no_payload_count = 0;
68
69 pub fn Type(comptime t: Tag) type {64 pub fn Type(comptime t: Tag) type {
70 return switch (t) {65 return switch (t) {
71 .eu_payload,66 .eu_payload,
...@@ -96,16 +91,7 @@ pub const Value = struct {...@@ -96,16 +91,7 @@ pub const Value = struct {
96 }91 }
97 };92 };
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
107 pub fn initPayload(payload: *Payload) Value {94 pub fn initPayload(payload: *Payload) Value {
108 assert(@enumToInt(payload.tag) >= Tag.no_payload_count);
109 return Value{95 return Value{
110 .ip_index = .none,96 .ip_index = .none,
111 .legacy = .{ .ptr_otherwise = payload },97 .legacy = .{ .ptr_otherwise = payload },
...@@ -114,11 +100,7 @@ pub const Value = struct {...@@ -114,11 +100,7 @@ pub const Value = struct {
114100
115 pub fn tag(self: Value) Tag {101 pub fn tag(self: Value) Tag {
116 assert(self.ip_index == .none);102 assert(self.ip_index == .none);
117 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {103 return self.legacy.ptr_otherwise.tag;
118 return self.legacy.tag_if_small_enough;
119 } else {
120 return self.legacy.ptr_otherwise.tag;
121 }
122 }104 }
123105
124 /// Prefer `castTag` to this.106 /// Prefer `castTag` to this.
...@@ -129,12 +111,7 @@ pub const Value = struct {...@@ -129,12 +111,7 @@ pub const Value = struct {
129 if (@hasField(T, "base_tag")) {111 if (@hasField(T, "base_tag")) {
130 return self.castTag(T.base_tag);112 return self.castTag(T.base_tag);
131 }113 }
132 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
133 return null;
134 }
135 inline for (@typeInfo(Tag).Enum.fields) |field| {114 inline for (@typeInfo(Tag).Enum.fields) |field| {
136 if (field.value < Tag.no_payload_count)
137 continue;
138 const t = @intToEnum(Tag, field.value);115 const t = @intToEnum(Tag, field.value);
139 if (self.legacy.ptr_otherwise.tag == t) {116 if (self.legacy.ptr_otherwise.tag == t) {
140 if (T == t.Type()) {117 if (T == t.Type()) {
...@@ -149,9 +126,6 @@ pub const Value = struct {...@@ -149,9 +126,6 @@ pub const Value = struct {
149 pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() {126 pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() {
150 if (self.ip_index != .none) return null;127 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
155 if (self.legacy.ptr_otherwise.tag == t)129 if (self.legacy.ptr_otherwise.tag == t)
156 return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);130 return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);
157131
...@@ -164,12 +138,7 @@ pub const Value = struct {...@@ -164,12 +138,7 @@ pub const Value = struct {
164 if (self.ip_index != .none) {138 if (self.ip_index != .none) {
165 return Value{ .ip_index = self.ip_index, .legacy = undefined };139 return Value{ .ip_index = self.ip_index, .legacy = undefined };
166 }140 }
167 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {141 switch (self.legacy.ptr_otherwise.tag) {
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) {
173 .bytes => {142 .bytes => {
174 const bytes = self.castTag(.bytes).?.data;143 const bytes = self.castTag(.bytes).?.data;
175 const new_payload = try arena.create(Payload.Bytes);144 const new_payload = try arena.create(Payload.Bytes);
...@@ -312,6 +281,30 @@ pub const Value = struct {...@@ -312,6 +281,30 @@ pub const Value = struct {
312 } };281 } };
313 }282 }
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
315 /// Asserts that the value is representable as an array of bytes.308 /// Asserts that the value is representable as an array of bytes.
316 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.309 /// Copies the value into a freshly allocated slice of memory, which is owned by the caller.
317 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {310 pub fn toAllocatedBytes(val: Value, ty: Type, allocator: Allocator, mod: *Module) ![]u8 {
...@@ -319,11 +312,11 @@ pub const Value = struct {...@@ -319,11 +312,11 @@ pub const Value = struct {
319 .enum_literal => |enum_literal| allocator.dupe(u8, mod.intern_pool.stringToSlice(enum_literal)),312 .enum_literal => |enum_literal| allocator.dupe(u8, mod.intern_pool.stringToSlice(enum_literal)),
320 .ptr => |ptr| switch (ptr.len) {313 .ptr => |ptr| switch (ptr.len) {
321 .none => unreachable,314 .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),
323 },316 },
324 .aggregate => |aggregate| switch (aggregate.storage) {317 .aggregate => |aggregate| switch (aggregate.storage) {
325 .bytes => |bytes| try allocator.dupe(u8, bytes),318 .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),
327 .repeated_elem => |elem| {320 .repeated_elem => |elem| {
328 const byte = @intCast(u8, elem.toValue().toUnsignedInt(mod));321 const byte = @intCast(u8, elem.toValue().toUnsignedInt(mod));
329 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen(mod)));322 const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen(mod)));
...@@ -344,6 +337,23 @@ pub const Value = struct {...@@ -344,6 +337,23 @@ pub const Value = struct {
344 return result;337 return result;
345 }338 }
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
347 pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {357 pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
348 if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern();358 if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern();
349 switch (val.tag()) {359 switch (val.tag()) {
...@@ -498,7 +508,7 @@ pub const Value = struct {...@@ -498,7 +508,7 @@ pub const Value = struct {
498 // Assume it is already an integer and return it directly.508 // Assume it is already an integer and return it directly.
499 .simple_type, .int_type => val,509 .simple_type, .int_type => val,
500 .enum_literal => |enum_literal| {510 .enum_literal => |enum_literal| {
501 const field_index = ty.enumFieldIndex(ip.stringToSlice(enum_literal), mod).?;511 const field_index = ty.enumFieldIndex(enum_literal, mod).?;
502 return switch (ip.indexToKey(ty.toIntern())) {512 return switch (ip.indexToKey(ty.toIntern())) {
503 // Assume it is already an integer and return it directly.513 // Assume it is already an integer and return it directly.
504 .simple_type, .int_type => val,514 .simple_type, .int_type => val,
...@@ -776,7 +786,7 @@ pub const Value = struct {...@@ -776,7 +786,7 @@ pub const Value = struct {
776 .error_union => |error_union| error_union.val.err_name,786 .error_union => |error_union| error_union.val.err_name,
777 else => unreachable,787 else => unreachable,
778 };788 };
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).?);
780 std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], @intCast(Int, int), endian);790 std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], @intCast(Int, int), endian);
781 },791 },
782 .Union => switch (ty.containerLayout(mod)) {792 .Union => switch (ty.containerLayout(mod)) {
...@@ -1028,10 +1038,10 @@ pub const Value = struct {...@@ -1028,10 +1038,10 @@ pub const Value = struct {
1028 // TODO revisit this when we have the concept of the error tag type1038 // TODO revisit this when we have the concept of the error tag type
1029 const Int = u16;1039 const Int = u16;
1030 const int = std.mem.readInt(Int, buffer[0..@sizeOf(Int)], endian);1040 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)];
1032 return (try mod.intern(.{ .err = .{1042 return (try mod.intern(.{ .err = .{
1033 .ty = ty.toIntern(),1043 .ty = ty.toIntern(),
1034 .name = mod.intern_pool.getString(name).unwrap().?,1044 .name = name,
1035 } })).toValue();1045 } })).toValue();
1036 },1046 },
1037 .Pointer => {1047 .Pointer => {
...@@ -2155,15 +2165,29 @@ pub const Value = struct {...@@ -2155,15 +2165,29 @@ pub const Value = struct {
2155 /// unreachable. For error unions, prefer `errorUnionIsPayload` to find out whether2165 /// unreachable. For error unions, prefer `errorUnionIsPayload` to find out whether
2156 /// something is an error or not because it works without having to figure out the2166 /// something is an error or not because it works without having to figure out the
2157 /// string.2167 /// string.
2158 pub fn getError(self: Value, mod: *const Module) ?[]const u8 {2168 pub fn getError(val: Value, mod: *const Module) ?[]const u8 {
2159 return mod.intern_pool.stringToSliceUnwrap(switch (mod.intern_pool.indexToKey(self.toIntern())) {2169 return switch (getErrorName(val, mod)) {
2160 .err => |err| err.name.toOptional(),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,
2161 .error_union => |error_union| switch (error_union.val) {2178 .error_union => |error_union| switch (error_union.val) {
2162 .err_name => |err_name| err_name.toOptional(),2179 .err_name => |err_name| err_name,
2163 .payload => .none,2180 .payload => .empty,
2164 },2181 },
2165 else => unreachable,2182 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 };
2167 }2191 }
21682192
2169 /// Assumes the type is an error union. Returns true if and only if the value is2193 /// Assumes the type is an error union. Returns true if and only if the value is
...@@ -4225,7 +4249,7 @@ pub const Value = struct {...@@ -4225,7 +4249,7 @@ pub const Value = struct {
4225 var fields: [tags.len]std.builtin.Type.StructField = undefined;4249 var fields: [tags.len]std.builtin.Type.StructField = undefined;
4226 for (&fields, tags) |*field, t| field.* = .{4250 for (&fields, tags) |*field, t| field.* = .{
4227 .name = t.name,4251 .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(),
4229 .default_value = null,4253 .default_value = null,
4230 .is_comptime = false,4254 .is_comptime = false,
4231 .alignment = 0,4255 .alignment = 0,