authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-12-30 13:22:48-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-15 15:11:36-08:00
log4fccb5ae7a3c3ad0f0ec79bf5eb628807c10eb62
tree1e0d758a607bfce81eb9e285d5ef255f32b42f5b
parent7d224516c4414015186bc1497ca6641b7390bf92

wasm linker: improve error messages by making source locations more lazy


5 files changed, 92 insertions(+), 47 deletions(-)

lib/std/zig/ErrorBundle.zig+15-13
...@@ -11,6 +11,11 @@ string_bytes: []const u8,...@@ -11,6 +11,11 @@ string_bytes: []const u8,
11/// The first thing in this array is an `ErrorMessageList`.11/// The first thing in this array is an `ErrorMessageList`.
12extra: []const u32,12extra: []const u32,
1313
14/// Index into `string_bytes`.
15pub const String = u32;
16/// Index into `string_bytes`, or null.
17pub const OptionalString = u32;
18
14/// Special encoding when there are no errors.19/// Special encoding when there are no errors.
15pub const empty: ErrorBundle = .{20pub const empty: ErrorBundle = .{
16 .string_bytes = &.{},21 .string_bytes = &.{},
...@@ -33,14 +38,13 @@ pub const ErrorMessageList = struct {...@@ -33,14 +38,13 @@ pub const ErrorMessageList = struct {
33 len: u32,38 len: u32,
34 start: u32,39 start: u32,
35 /// null-terminated string index. 0 means no compile log text.40 /// null-terminated string index. 0 means no compile log text.
36 compile_log_text: u32,41 compile_log_text: OptionalString,
37};42};
3843
39/// Trailing:44/// Trailing:
40/// * ReferenceTrace for each reference_trace_len45/// * ReferenceTrace for each reference_trace_len
41pub const SourceLocation = struct {46pub const SourceLocation = struct {
42 /// null terminated string index47 src_path: String,
43 src_path: u32,
44 line: u32,48 line: u32,
45 column: u32,49 column: u32,
46 /// byte offset of starting token50 /// byte offset of starting token
...@@ -49,17 +53,15 @@ pub const SourceLocation = struct {...@@ -49,17 +53,15 @@ pub const SourceLocation = struct {
49 span_main: u32,53 span_main: u32,
50 /// byte offset of end of last token54 /// byte offset of end of last token
51 span_end: u32,55 span_end: u32,
52 /// null terminated string index, possibly null.
53 /// Does not include the trailing newline.56 /// Does not include the trailing newline.
54 source_line: u32 = 0,57 source_line: OptionalString = 0,
55 reference_trace_len: u32 = 0,58 reference_trace_len: u32 = 0,
56};59};
5760
58/// Trailing:61/// Trailing:
59/// * MessageIndex for each notes_len.62/// * MessageIndex for each notes_len.
60pub const ErrorMessage = struct {63pub const ErrorMessage = struct {
61 /// null terminated string index64 msg: String,
62 msg: u32,
63 /// Usually one, but incremented for redundant messages.65 /// Usually one, but incremented for redundant messages.
64 count: u32 = 1,66 count: u32 = 1,
65 src_loc: SourceLocationIndex = .none,67 src_loc: SourceLocationIndex = .none,
...@@ -71,7 +73,7 @@ pub const ReferenceTrace = struct {...@@ -71,7 +73,7 @@ pub const ReferenceTrace = struct {
71 /// Except for the sentinel ReferenceTrace element, in which case:73 /// Except for the sentinel ReferenceTrace element, in which case:
72 /// * 0 means remaining references hidden74 /// * 0 means remaining references hidden
73 /// * >0 means N references hidden75 /// * >0 means N references hidden
74 decl_name: u32,76 decl_name: String,
75 /// Index into extra of a SourceLocation77 /// Index into extra of a SourceLocation
76 /// If this is 0, this is the sentinel ReferenceTrace element.78 /// If this is 0, this is the sentinel ReferenceTrace element.
77 src_loc: SourceLocationIndex,79 src_loc: SourceLocationIndex,
...@@ -138,7 +140,7 @@ fn extraData(eb: ErrorBundle, comptime T: type, index: usize) struct { data: T,...@@ -138,7 +140,7 @@ fn extraData(eb: ErrorBundle, comptime T: type, index: usize) struct { data: T,
138}140}
139141
140/// Given an index into `string_bytes` returns the null-terminated string found there.142/// Given an index into `string_bytes` returns the null-terminated string found there.
141pub fn nullTerminatedString(eb: ErrorBundle, index: usize) [:0]const u8 {143pub fn nullTerminatedString(eb: ErrorBundle, index: String) [:0]const u8 {
142 const string_bytes = eb.string_bytes;144 const string_bytes = eb.string_bytes;
143 var end: usize = index;145 var end: usize = index;
144 while (string_bytes[end] != 0) {146 while (string_bytes[end] != 0) {
...@@ -384,18 +386,18 @@ pub const Wip = struct {...@@ -384,18 +386,18 @@ pub const Wip = struct {
384 };386 };
385 }387 }
386388
387 pub fn addString(wip: *Wip, s: []const u8) Allocator.Error!u32 {389 pub fn addString(wip: *Wip, s: []const u8) Allocator.Error!String {
388 const gpa = wip.gpa;390 const gpa = wip.gpa;
389 const index: u32 = @intCast(wip.string_bytes.items.len);391 const index: String = @intCast(wip.string_bytes.items.len);
390 try wip.string_bytes.ensureUnusedCapacity(gpa, s.len + 1);392 try wip.string_bytes.ensureUnusedCapacity(gpa, s.len + 1);
391 wip.string_bytes.appendSliceAssumeCapacity(s);393 wip.string_bytes.appendSliceAssumeCapacity(s);
392 wip.string_bytes.appendAssumeCapacity(0);394 wip.string_bytes.appendAssumeCapacity(0);
393 return index;395 return index;
394 }396 }
395397
396 pub fn printString(wip: *Wip, comptime fmt: []const u8, args: anytype) Allocator.Error!u32 {398 pub fn printString(wip: *Wip, comptime fmt: []const u8, args: anytype) Allocator.Error!String {
397 const gpa = wip.gpa;399 const gpa = wip.gpa;
398 const index: u32 = @intCast(wip.string_bytes.items.len);400 const index: String = @intCast(wip.string_bytes.items.len);
399 try wip.string_bytes.writer(gpa).print(fmt, args);401 try wip.string_bytes.writer(gpa).print(fmt, args);
400 try wip.string_bytes.append(gpa, 0);402 try wip.string_bytes.append(gpa, 0);
401 return index;403 return index;
src/Compilation.zig+1-1
...@@ -3291,7 +3291,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3291,7 +3291,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3291 }));3291 }));
3292 }3292 }
32933293
3294 try comp.link_diags.addMessagesToBundle(&bundle);3294 try comp.link_diags.addMessagesToBundle(&bundle, comp.bin_file);
32953295
3296 if (comp.zcu) |zcu| {3296 if (comp.zcu) |zcu| {
3297 if (bundle.root_list.items.len == 0 and zcu.compile_log_sources.count() != 0) {3297 if (bundle.root_list.items.len == 0 and zcu.compile_log_sources.count() != 0) {
src/link.zig+25-4
...@@ -38,6 +38,11 @@ pub const Diags = struct {...@@ -38,6 +38,11 @@ pub const Diags = struct {
38 flags: Flags,38 flags: Flags,
39 lld: std.ArrayListUnmanaged(Lld),39 lld: std.ArrayListUnmanaged(Lld),
4040
41 pub const SourceLocation = union(enum) {
42 none,
43 wasm: File.Wasm.SourceLocation,
44 };
45
41 pub const Flags = packed struct {46 pub const Flags = packed struct {
42 no_entry_point_found: bool = false,47 no_entry_point_found: bool = false,
43 missing_libc: bool = false,48 missing_libc: bool = false,
...@@ -70,9 +75,25 @@ pub const Diags = struct {...@@ -70,9 +75,25 @@ pub const Diags = struct {
70 };75 };
7176
72 pub const Msg = struct {77 pub const Msg = struct {
78 source_location: SourceLocation = .none,
73 msg: []const u8,79 msg: []const u8,
74 notes: []Msg = &.{},80 notes: []Msg = &.{},
7581
82 fn string(
83 msg: *const Msg,
84 bundle: *std.zig.ErrorBundle.Wip,
85 base: ?*File,
86 ) Allocator.Error!std.zig.ErrorBundle.String {
87 return switch (msg.source_location) {
88 .none => try bundle.addString(msg.msg),
89 .wasm => |sl| {
90 dev.check(.wasm_linker);
91 const wasm = base.?.cast(.wasm).?;
92 return sl.string(msg.msg, bundle, wasm);
93 },
94 };
95 }
96
76 pub fn deinit(self: *Msg, gpa: Allocator) void {97 pub fn deinit(self: *Msg, gpa: Allocator) void {
77 for (self.notes) |*note| note.deinit(gpa);98 for (self.notes) |*note| note.deinit(gpa);
78 gpa.free(self.notes);99 gpa.free(self.notes);
...@@ -326,16 +347,16 @@ pub const Diags = struct {...@@ -326,16 +347,16 @@ pub const Diags = struct {
326 diags.flags.alloc_failure_occurred = true;347 diags.flags.alloc_failure_occurred = true;
327 }348 }
328349
329 pub fn addMessagesToBundle(diags: *const Diags, bundle: *std.zig.ErrorBundle.Wip) Allocator.Error!void {350 pub fn addMessagesToBundle(diags: *const Diags, bundle: *std.zig.ErrorBundle.Wip, base: ?*File) Allocator.Error!void {
330 for (diags.msgs.items) |link_err| {351 for (diags.msgs.items) |link_err| {
331 try bundle.addRootErrorMessage(.{352 try bundle.addRootErrorMessage(.{
332 .msg = try bundle.addString(link_err.msg),353 .msg = try link_err.string(bundle, base),
333 .notes_len = @intCast(link_err.notes.len),354 .notes_len = @intCast(link_err.notes.len),
334 });355 });
335 const notes_start = try bundle.reserveNotes(@intCast(link_err.notes.len));356 const notes_start = try bundle.reserveNotes(@intCast(link_err.notes.len));
336 for (link_err.notes, 0..) |note, i| {357 for (link_err.notes, 0..) |note, i| {
337 bundle.extra.items[notes_start + i] = @intFromEnum(try bundle.addErrorMessage(.{358 bundle.extra.items[notes_start + i] = @intFromEnum(try bundle.addErrorMessage(.{
338 .msg = try bundle.addString(note.msg),359 .msg = try note.string(bundle, base),
339 }));360 }));
340 }361 }
341 }362 }
...@@ -2224,7 +2245,7 @@ fn resolvePathInputLib(...@@ -2224,7 +2245,7 @@ fn resolvePathInputLib(
2224 try wip_errors.init(gpa);2245 try wip_errors.init(gpa);
2225 defer wip_errors.deinit();2246 defer wip_errors.deinit();
22262247
2227 try diags.addMessagesToBundle(&wip_errors);2248 try diags.addMessagesToBundle(&wip_errors, null);
22282249
2229 var error_bundle = try wip_errors.toOwnedBundle("");2250 var error_bundle = try wip_errors.toOwnedBundle("");
2230 defer error_bundle.deinit(gpa);2251 defer error_bundle.deinit(gpa);
src/link/Wasm.zig+28-6
...@@ -465,17 +465,33 @@ pub const SourceLocation = enum(u32) {...@@ -465,17 +465,33 @@ pub const SourceLocation = enum(u32) {
465465
466 pub fn addNote(466 pub fn addNote(
467 sl: SourceLocation,467 sl: SourceLocation,
468 wasm: *Wasm,
469 err: *link.Diags.ErrorWithNotes,468 err: *link.Diags.ErrorWithNotes,
470 comptime f: []const u8,469 comptime f: []const u8,
471 args: anytype,470 args: anytype,
472 ) void {471 ) void {
473 switch (sl.unpack(wasm)) {472 err.addNote(f, args);
474 .none => err.addNote(f, args),473 const err_msg = &err.diags.msgs.items[err.index];
475 .zig_object_nofile => err.addNote("zig compilation unit: " ++ f, args),474 err_msg.notes[err.note_slot - 1].source_location = .{ .wasm = sl };
476 .object_index => |i| err.addNote("{}: " ++ f, .{i.ptr(wasm).path} ++ args),475 }
476
477 pub fn string(
478 sl: SourceLocation,
479 msg: []const u8,
480 bundle: *std.zig.ErrorBundle.Wip,
481 wasm: *const Wasm,
482 ) Allocator.Error!std.zig.ErrorBundle.String {
483 return switch (sl.unpack(wasm)) {
484 .none => try bundle.addString(msg),
485 .zig_object_nofile => try bundle.printString("zig compilation unit: {s}", .{msg}),
486 .object_index => |i| {
487 const obj = i.ptr(wasm);
488 return if (obj.archive_member_name.slice(wasm)) |obj_name|
489 try bundle.printString("{} ({s}): {s}", .{ obj.path, std.fs.path.basename(obj_name), msg })
490 else
491 try bundle.printString("{}: {s}", .{ obj.path, msg });
492 },
477 .source_location_index => @panic("TODO"),493 .source_location_index => @panic("TODO"),
478 }494 };
479 }495 }
480};496};
481497
...@@ -3679,6 +3695,12 @@ fn defaultEntrySymbolName(...@@ -3679,6 +3695,12 @@ fn defaultEntrySymbolName(
3679 };3695 };
3680}3696}
36813697
3698pub fn internOptionalString(wasm: *Wasm, optional_bytes: ?[]const u8) Allocator.Error!OptionalString {
3699 const bytes = optional_bytes orelse return .none;
3700 const string = try internString(wasm, bytes);
3701 return string.toOptional();
3702}
3703
3682pub fn internString(wasm: *Wasm, bytes: []const u8) Allocator.Error!String {3704pub fn internString(wasm: *Wasm, bytes: []const u8) Allocator.Error!String {
3683 assert(mem.indexOfScalar(u8, bytes, 0) == null);3705 assert(mem.indexOfScalar(u8, bytes, 0) == null);
3684 wasm.string_bytes_lock.lock();3706 wasm.string_bytes_lock.lock();
src/link/Wasm/Object.zig+23-23
...@@ -17,7 +17,7 @@ path: Path,...@@ -17,7 +17,7 @@ path: Path,
17/// For error reporting purposes only.17/// For error reporting purposes only.
18/// If this represents an object in an archive, it's the basename of the18/// If this represents an object in an archive, it's the basename of the
19/// object, and path refers to the archive.19/// object, and path refers to the archive.
20archive_member_name: ?[]const u8,20archive_member_name: Wasm.OptionalString,
21/// Represents the function ID that must be called on startup.21/// Represents the function ID that must be called on startup.
22/// This is `null` by default as runtimes may determine the startup22/// This is `null` by default as runtimes may determine the startup
23/// function themselves. This is essentially legacy.23/// function themselves. This is essentially legacy.
...@@ -965,21 +965,21 @@ pub fn parse(...@@ -965,21 +965,21 @@ pub fn parse(
965 if (gop.value_ptr.type != fn_ty_index) {965 if (gop.value_ptr.type != fn_ty_index) {
966 var err = try diags.addErrorWithNotes(2);966 var err = try diags.addErrorWithNotes(2);
967 try err.addMsg("symbol '{s}' mismatching function signatures", .{name.slice(wasm)});967 try err.addMsg("symbol '{s}' mismatching function signatures", .{name.slice(wasm)});
968 gop.value_ptr.source_location.addNote(wasm, &err, "imported as {} here", .{968 gop.value_ptr.source_location.addNote(&err, "imported as {} here", .{
969 gop.value_ptr.type.fmt(wasm),969 gop.value_ptr.type.fmt(wasm),
970 });970 });
971 err.addNote("{}: imported as {} here", .{ path, fn_ty_index.fmt(wasm) });971 source_location.addNote(&err, "imported as {} here", .{fn_ty_index.fmt(wasm)});
972 continue;972 continue;
973 }973 }
974 if (gop.value_ptr.module_name != ptr.module_name.toOptional()) {974 if (gop.value_ptr.module_name != ptr.module_name.toOptional()) {
975 var err = try diags.addErrorWithNotes(2);975 var err = try diags.addErrorWithNotes(2);
976 try err.addMsg("symbol '{s}' mismatching module names", .{name.slice(wasm)});976 try err.addMsg("symbol '{s}' mismatching module names", .{name.slice(wasm)});
977 if (gop.value_ptr.module_name.slice(wasm)) |module_name| {977 if (gop.value_ptr.module_name.slice(wasm)) |module_name| {
978 gop.value_ptr.source_location.addNote(wasm, &err, "module '{s}' here", .{module_name});978 gop.value_ptr.source_location.addNote(&err, "module '{s}' here", .{module_name});
979 } else {979 } else {
980 gop.value_ptr.source_location.addNote(wasm, &err, "no module here", .{});980 gop.value_ptr.source_location.addNote(&err, "no module here", .{});
981 }981 }
982 err.addNote("{}: module '{s}' here", .{ path, ptr.module_name.slice(wasm) });982 source_location.addNote(&err, "module '{s}' here", .{ptr.module_name.slice(wasm)});
983 continue;983 continue;
984 }984 }
985 if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong;985 if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong;
...@@ -1008,18 +1008,18 @@ pub fn parse(...@@ -1008,18 +1008,18 @@ pub fn parse(
1008 if (ptr.valtype != existing_ty.valtype) {1008 if (ptr.valtype != existing_ty.valtype) {
1009 var err = try diags.addErrorWithNotes(2);1009 var err = try diags.addErrorWithNotes(2);
1010 try err.addMsg("symbol '{s}' mismatching global types", .{name.slice(wasm)});1010 try err.addMsg("symbol '{s}' mismatching global types", .{name.slice(wasm)});
1011 gop.value_ptr.source_location.addNote(wasm, &err, "type {s} here", .{@tagName(existing_ty.valtype)});1011 gop.value_ptr.source_location.addNote(&err, "type {s} here", .{@tagName(existing_ty.valtype)});
1012 err.addNote("{}: type {s} here", .{ path, @tagName(ptr.valtype) });1012 source_location.addNote(&err, "type {s} here", .{@tagName(ptr.valtype)});
1013 continue;1013 continue;
1014 }1014 }
1015 if (ptr.mutable != existing_ty.mutable) {1015 if (ptr.mutable != existing_ty.mutable) {
1016 var err = try diags.addErrorWithNotes(2);1016 var err = try diags.addErrorWithNotes(2);
1017 try err.addMsg("symbol '{s}' mismatching global mutability", .{name.slice(wasm)});1017 try err.addMsg("symbol '{s}' mismatching global mutability", .{name.slice(wasm)});
1018 gop.value_ptr.source_location.addNote(wasm, &err, "{s} here", .{1018 gop.value_ptr.source_location.addNote(&err, "{s} here", .{
1019 if (existing_ty.mutable) "mutable" else "not mutable",1019 if (existing_ty.mutable) "mutable" else "not mutable",
1020 });1020 });
1021 err.addNote("{}: {s} here", .{1021 source_location.addNote(&err, "{s} here", .{
1022 path, if (ptr.mutable) "mutable" else "not mutable",1022 if (ptr.mutable) "mutable" else "not mutable",
1023 });1023 });
1024 continue;1024 continue;
1025 }1025 }
...@@ -1027,11 +1027,11 @@ pub fn parse(...@@ -1027,11 +1027,11 @@ pub fn parse(
1027 var err = try diags.addErrorWithNotes(2);1027 var err = try diags.addErrorWithNotes(2);
1028 try err.addMsg("symbol '{s}' mismatching module names", .{name.slice(wasm)});1028 try err.addMsg("symbol '{s}' mismatching module names", .{name.slice(wasm)});
1029 if (gop.value_ptr.module_name.slice(wasm)) |module_name| {1029 if (gop.value_ptr.module_name.slice(wasm)) |module_name| {
1030 gop.value_ptr.source_location.addNote(wasm, &err, "module '{s}' here", .{module_name});1030 gop.value_ptr.source_location.addNote(&err, "module '{s}' here", .{module_name});
1031 } else {1031 } else {
1032 gop.value_ptr.source_location.addNote(wasm, &err, "no module here", .{});1032 gop.value_ptr.source_location.addNote(&err, "no module here", .{});
1033 }1033 }
1034 err.addNote("{}: module '{s}' here", .{ path, ptr.module_name.slice(wasm) });1034 source_location.addNote(&err, "module '{s}' here", .{ptr.module_name.slice(wasm)});
1035 continue;1035 continue;
1036 }1036 }
1037 if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong;1037 if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong;
...@@ -1063,17 +1063,17 @@ pub fn parse(...@@ -1063,17 +1063,17 @@ pub fn parse(
1063 if (ptr.ref_type != existing_reftype) {1063 if (ptr.ref_type != existing_reftype) {
1064 var err = try diags.addErrorWithNotes(2);1064 var err = try diags.addErrorWithNotes(2);
1065 try err.addMsg("symbol '{s}' mismatching table reftypes", .{name.slice(wasm)});1065 try err.addMsg("symbol '{s}' mismatching table reftypes", .{name.slice(wasm)});
1066 gop.value_ptr.source_location.addNote(wasm, &err, "{s} here", .{@tagName(existing_reftype)});1066 gop.value_ptr.source_location.addNote(&err, "{s} here", .{@tagName(existing_reftype)});
1067 err.addNote("{}: {s} here", .{ path, @tagName(ptr.ref_type) });1067 source_location.addNote(&err, "{s} here", .{@tagName(ptr.ref_type)});
1068 continue;1068 continue;
1069 }1069 }
1070 if (gop.value_ptr.module_name != ptr.module_name) {1070 if (gop.value_ptr.module_name != ptr.module_name) {
1071 var err = try diags.addErrorWithNotes(2);1071 var err = try diags.addErrorWithNotes(2);
1072 try err.addMsg("symbol '{s}' mismatching module names", .{name.slice(wasm)});1072 try err.addMsg("symbol '{s}' mismatching module names", .{name.slice(wasm)});
1073 gop.value_ptr.source_location.addNote(wasm, &err, "module '{s}' here", .{1073 gop.value_ptr.source_location.addNote(&err, "module '{s}' here", .{
1074 gop.value_ptr.module_name.slice(wasm),1074 gop.value_ptr.module_name.slice(wasm),
1075 });1075 });
1076 err.addNote("{}: module '{s}' here", .{ path, ptr.module_name.slice(wasm) });1076 source_location.addNote(&err, "module '{s}' here", .{ptr.module_name.slice(wasm)});
1077 continue;1077 continue;
1078 }1078 }
1079 if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong;1079 if (symbol.flags.binding == .strong) gop.value_ptr.flags.binding = .strong;
...@@ -1105,11 +1105,11 @@ pub fn parse(...@@ -1105,11 +1105,11 @@ pub fn parse(
1105 if (gop.value_ptr.type != ptr.type_index) {1105 if (gop.value_ptr.type != ptr.type_index) {
1106 var err = try diags.addErrorWithNotes(2);1106 var err = try diags.addErrorWithNotes(2);
1107 try err.addMsg("function signature mismatch: {s}", .{name.slice(wasm)});1107 try err.addMsg("function signature mismatch: {s}", .{name.slice(wasm)});
1108 gop.value_ptr.source_location.addNote(wasm, &err, "exported as {} here", .{1108 gop.value_ptr.source_location.addNote(&err, "exported as {} here", .{
1109 ptr.type_index.fmt(wasm),1109 ptr.type_index.fmt(wasm),
1110 });1110 });
1111 const word = if (gop.value_ptr.resolution == .unresolved) "imported" else "exported";1111 const word = if (gop.value_ptr.resolution == .unresolved) "imported" else "exported";
1112 err.addNote("{}: {s} as {} here", .{ path, word, gop.value_ptr.type.fmt(wasm) });1112 source_location.addNote(&err, "{s} as {} here", .{ word, gop.value_ptr.type.fmt(wasm) });
1113 continue;1113 continue;
1114 }1114 }
1115 if (gop.value_ptr.resolution == .unresolved or gop.value_ptr.flags.binding == .weak) {1115 if (gop.value_ptr.resolution == .unresolved or gop.value_ptr.flags.binding == .weak) {
...@@ -1121,8 +1121,8 @@ pub fn parse(...@@ -1121,8 +1121,8 @@ pub fn parse(
1121 }1121 }
1122 var err = try diags.addErrorWithNotes(2);1122 var err = try diags.addErrorWithNotes(2);
1123 try err.addMsg("symbol collision: {s}", .{name.slice(wasm)});1123 try err.addMsg("symbol collision: {s}", .{name.slice(wasm)});
1124 gop.value_ptr.source_location.addNote(wasm, &err, "exported as {} here", .{ptr.type_index.fmt(wasm)});1124 gop.value_ptr.source_location.addNote(&err, "exported as {} here", .{ptr.type_index.fmt(wasm)});
1125 err.addNote("{}: exported as {} here", .{ path, gop.value_ptr.type.fmt(wasm) });1125 source_location.addNote(&err, "exported as {} here", .{gop.value_ptr.type.fmt(wasm)});
1126 continue;1126 continue;
1127 } else {1127 } else {
1128 gop.value_ptr.* = .{1128 gop.value_ptr.* = .{
...@@ -1242,7 +1242,7 @@ pub fn parse(...@@ -1242,7 +1242,7 @@ pub fn parse(
1242 return .{1242 return .{
1243 .version = version,1243 .version = version,
1244 .path = path,1244 .path = path,
1245 .archive_member_name = archive_member_name,1245 .archive_member_name = try wasm.internOptionalString(archive_member_name),
1246 .start_function = start_function,1246 .start_function = start_function,
1247 .features = features,1247 .features = features,
1248 .functions = .{1248 .functions = .{