| author | |
| committer | |
| log | 6f717b18f05ba02439603e0987e9c9551fbadedb |
| tree | c95613ef714eed338372d1947c0132808beffab4 |
| parent | 572cb24d1a4f70c662ddf17df72d27dec44bc4fc |
* Separate into a "WIP" struct and a "finished" struct.
* Use a bit of indirection for error notes to simplify ergonomics of
this data structure.6 files changed, 425 insertions(+), 390 deletions(-)
lib/std/zig/ErrorBundle.zig+227-183| ... | @@ -3,24 +3,22 @@ | ... | @@ -3,24 +3,22 @@ |
| 3 | //! is used to collect all the errors from the various places into one | 3 | //! is used to collect all the errors from the various places into one |
| 4 | //! convenient place for API users to consume. | 4 | //! convenient place for API users to consume. |
| 5 | 5 | ||
| 6 | string_bytes: std.ArrayListUnmanaged(u8), | 6 | string_bytes: []const u8, |
| 7 | /// The first thing in this array is a ErrorMessageListIndex. | 7 | /// The first thing in this array is an `ErrorMessageList`. |
| 8 | extra: std.ArrayListUnmanaged(u32), | 8 | extra: []const u32, |
| 9 | 9 | ||
| 10 | // An index into `extra` pointing at an `ErrorMessage`. | 10 | // An index into `extra` pointing at an `ErrorMessage`. |
| 11 | pub const MessageIndex = enum(u32) { | 11 | pub const MessageIndex = enum(u32) { |
| 12 | _, | 12 | _, |
| 13 | }; | 13 | }; |
| 14 | 14 | ||
| 15 | /// After the header is: | 15 | // An index into `extra` pointing at an `SourceLocation`. |
| 16 | /// * string_bytes | 16 | pub const SourceLocationIndex = enum(u32) { |
| 17 | /// * extra (little endian) | 17 | none = 0, |
| 18 | pub const Header = struct { | 18 | _, |
| 19 | string_bytes_len: u32, | ||
| 20 | extra_len: u32, | ||
| 21 | }; | 19 | }; |
| 22 | 20 | ||
| 23 | /// Trailing: ErrorMessage for each len | 21 | /// There will be a MessageIndex for each len at start. |
| 24 | pub const ErrorMessageList = struct { | 22 | pub const ErrorMessageList = struct { |
| 25 | len: u32, | 23 | len: u32, |
| 26 | start: u32, | 24 | start: u32, |
| ... | @@ -46,14 +44,13 @@ pub const SourceLocation = struct { | ... | @@ -46,14 +44,13 @@ pub const SourceLocation = struct { |
| 46 | }; | 44 | }; |
| 47 | 45 | ||
| 48 | /// Trailing: | 46 | /// Trailing: |
| 49 | /// * ErrorMessage for each notes_len. | 47 | /// * MessageIndex for each notes_len. |
| 50 | pub const ErrorMessage = struct { | 48 | pub const ErrorMessage = struct { |
| 51 | /// null terminated string index | 49 | /// null terminated string index |
| 52 | msg: u32, | 50 | msg: u32, |
| 53 | /// Usually one, but incremented for redundant messages. | 51 | /// Usually one, but incremented for redundant messages. |
| 54 | count: u32 = 1, | 52 | count: u32 = 1, |
| 55 | /// 0 or the index into extra of a SourceLocation | 53 | src_loc: SourceLocationIndex = .none, |
| 56 | src_loc: u32 = 0, | ||
| 57 | notes_len: u32 = 0, | 54 | notes_len: u32 = 0, |
| 58 | }; | 55 | }; |
| 59 | 56 | ||
| ... | @@ -65,170 +62,41 @@ pub const ReferenceTrace = struct { | ... | @@ -65,170 +62,41 @@ pub const ReferenceTrace = struct { |
| 65 | decl_name: u32, | 62 | decl_name: u32, |
| 66 | /// Index into extra of a SourceLocation | 63 | /// Index into extra of a SourceLocation |
| 67 | /// If this is 0, this is the sentinel ReferenceTrace element. | 64 | /// If this is 0, this is the sentinel ReferenceTrace element. |
| 68 | src_loc: u32, | 65 | src_loc: SourceLocationIndex, |
| 69 | }; | 66 | }; |
| 70 | 67 | ||
| 71 | pub fn init(eb: *ErrorBundle, gpa: Allocator) !void { | ||
| 72 | eb.* = .{ | ||
| 73 | .string_bytes = .{}, | ||
| 74 | .extra = .{}, | ||
| 75 | }; | ||
| 76 | |||
| 77 | // So that 0 can be used to indicate a null string. | ||
| 78 | try eb.string_bytes.append(gpa, 0); | ||
| 79 | |||
| 80 | _ = try addExtra(eb, gpa, ErrorMessageList{ | ||
| 81 | .len = 0, | ||
| 82 | .start = 0, | ||
| 83 | }); | ||
| 84 | } | ||
| 85 | |||
| 86 | pub fn deinit(eb: *ErrorBundle, gpa: Allocator) void { | 68 | pub fn deinit(eb: *ErrorBundle, gpa: Allocator) void { |
| 87 | eb.string_bytes.deinit(gpa); | 69 | gpa.free(eb.string_bytes); |
| 88 | eb.extra.deinit(gpa); | 70 | gpa.free(eb.extra); |
| 89 | eb.* = undefined; | 71 | eb.* = undefined; |
| 90 | } | 72 | } |
| 91 | 73 | ||
| 92 | pub fn addString(eb: *ErrorBundle, gpa: Allocator, s: []const u8) !u32 { | ||
| 93 | const index = @intCast(u32, eb.string_bytes.items.len); | ||
| 94 | try eb.string_bytes.ensureUnusedCapacity(gpa, s.len + 1); | ||
| 95 | eb.string_bytes.appendSliceAssumeCapacity(s); | ||
| 96 | eb.string_bytes.appendAssumeCapacity(0); | ||
| 97 | return index; | ||
| 98 | } | ||
| 99 | |||
| 100 | pub fn printString(eb: *ErrorBundle, gpa: Allocator, comptime fmt: []const u8, args: anytype) !u32 { | ||
| 101 | const index = @intCast(u32, eb.string_bytes.items.len); | ||
| 102 | try eb.string_bytes.writer(gpa).print(fmt, args); | ||
| 103 | try eb.string_bytes.append(gpa, 0); | ||
| 104 | return index; | ||
| 105 | } | ||
| 106 | |||
| 107 | pub fn addErrorMessage(eb: *ErrorBundle, gpa: Allocator, em: ErrorMessage) !void { | ||
| 108 | if (eb.errorMessageCount() == 0) { | ||
| 109 | eb.setStartIndex(@intCast(u32, eb.extra.items.len)); | ||
| 110 | } | ||
| 111 | _ = try addExtra(eb, gpa, em); | ||
| 112 | } | ||
| 113 | |||
| 114 | pub fn addSourceLocation(eb: *ErrorBundle, gpa: Allocator, sl: SourceLocation) !u32 { | ||
| 115 | return addExtra(eb, gpa, sl); | ||
| 116 | } | ||
| 117 | |||
| 118 | pub fn addReferenceTrace(eb: *ErrorBundle, gpa: Allocator, rt: ReferenceTrace) !void { | ||
| 119 | _ = try addExtra(eb, gpa, rt); | ||
| 120 | } | ||
| 121 | |||
| 122 | pub fn addBundle(eb: *ErrorBundle, gpa: Allocator, other: ErrorBundle) !void { | ||
| 123 | // Skip over the initial ErrorMessageList len field. | ||
| 124 | const root_fields_len = @typeInfo(ErrorMessageList).Struct.fields.len; | ||
| 125 | const other_list = other.extraData(ErrorMessageList, 0).data; | ||
| 126 | const other_extra = other.extra.items[root_fields_len..]; | ||
| 127 | |||
| 128 | try eb.string_bytes.ensureUnusedCapacity(gpa, other.string_bytes.items.len); | ||
| 129 | try eb.extra.ensureUnusedCapacity(gpa, other_extra.len); | ||
| 130 | |||
| 131 | const new_string_base = @intCast(u32, eb.string_bytes.items.len); | ||
| 132 | const new_data_base = @intCast(u32, eb.extra.items.len - root_fields_len); | ||
| 133 | |||
| 134 | eb.string_bytes.appendSliceAssumeCapacity(other.string_bytes.items); | ||
| 135 | eb.extra.appendSliceAssumeCapacity(other_extra); | ||
| 136 | |||
| 137 | // Now we must offset the string indexes and extra indexes of the newly | ||
| 138 | // added extra. | ||
| 139 | var index = new_data_base + other_list.start; | ||
| 140 | for (0..other_list.len) |_| { | ||
| 141 | index = try patchMessage(eb, index, new_string_base, new_data_base); | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | fn patchMessage(eb: *ErrorBundle, msg_idx: usize, new_string_base: u32, new_data_base: u32) !u32 { | ||
| 146 | var msg = eb.extraData(ErrorMessage, msg_idx); | ||
| 147 | if (msg.data.msg != 0) msg.data.msg += new_string_base; | ||
| 148 | if (msg.data.src_loc != 0) msg.data.src_loc += new_data_base; | ||
| 149 | eb.setExtra(msg_idx, msg.data); | ||
| 150 | |||
| 151 | try patchSrcLoc(eb, msg.data.src_loc, new_string_base, new_data_base); | ||
| 152 | |||
| 153 | var index = @intCast(u32, msg.end); | ||
| 154 | for (0..msg.data.notes_len) |_| { | ||
| 155 | index = try patchMessage(eb, index, new_string_base, new_data_base); | ||
| 156 | } | ||
| 157 | return index; | ||
| 158 | } | ||
| 159 | |||
| 160 | fn patchSrcLoc(eb: *ErrorBundle, idx: usize, new_string_base: u32, new_data_base: u32) !void { | ||
| 161 | if (idx == 0) return; | ||
| 162 | |||
| 163 | var src_loc = eb.extraData(SourceLocation, idx); | ||
| 164 | if (src_loc.data.src_path != 0) src_loc.data.src_path += new_string_base; | ||
| 165 | if (src_loc.data.source_line != 0) src_loc.data.source_line += new_string_base; | ||
| 166 | eb.setExtra(idx, src_loc.data); | ||
| 167 | |||
| 168 | var index = src_loc.end; | ||
| 169 | for (0..src_loc.data.reference_trace_len) |_| { | ||
| 170 | var ref_trace = eb.extraData(ReferenceTrace, index); | ||
| 171 | if (ref_trace.data.decl_name != 0) ref_trace.data.decl_name += new_string_base; | ||
| 172 | if (ref_trace.data.src_loc != 0) ref_trace.data.src_loc += new_data_base; | ||
| 173 | eb.setExtra(index, ref_trace.data); | ||
| 174 | try patchSrcLoc(eb, ref_trace.data.src_loc, new_string_base, new_data_base); | ||
| 175 | index = ref_trace.end; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | fn addExtra(eb: *ErrorBundle, gpa: Allocator, extra: anytype) Allocator.Error!u32 { | ||
| 180 | const fields = @typeInfo(@TypeOf(extra)).Struct.fields; | ||
| 181 | try eb.extra.ensureUnusedCapacity(gpa, fields.len); | ||
| 182 | return addExtraAssumeCapacity(eb, extra); | ||
| 183 | } | ||
| 184 | |||
| 185 | fn addExtraAssumeCapacity(eb: *ErrorBundle, extra: anytype) u32 { | ||
| 186 | const fields = @typeInfo(@TypeOf(extra)).Struct.fields; | ||
| 187 | const result = @intCast(u32, eb.extra.items.len); | ||
| 188 | eb.extra.items.len += fields.len; | ||
| 189 | setExtra(eb, result, extra); | ||
| 190 | return result; | ||
| 191 | } | ||
| 192 | |||
| 193 | fn setExtra(eb: *ErrorBundle, index: usize, extra: anytype) void { | ||
| 194 | const fields = @typeInfo(@TypeOf(extra)).Struct.fields; | ||
| 195 | var i = index; | ||
| 196 | inline for (fields) |field| { | ||
| 197 | eb.extra.items[i] = switch (field.type) { | ||
| 198 | u32 => @field(extra, field.name), | ||
| 199 | else => @compileError("bad field type"), | ||
| 200 | }; | ||
| 201 | i += 1; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | pub fn errorMessageCount(eb: ErrorBundle) u32 { | 74 | pub fn errorMessageCount(eb: ErrorBundle) u32 { |
| 206 | return eb.extra.items[0]; | 75 | return eb.getErrorMessageList().len; |
| 207 | } | ||
| 208 | |||
| 209 | pub fn setErrorMessageCount(eb: *ErrorBundle, count: u32) void { | ||
| 210 | eb.extra.items[0] = count; | ||
| 211 | } | 76 | } |
| 212 | 77 | ||
| 213 | pub fn incrementCount(eb: *ErrorBundle, delta: u32) void { | 78 | pub fn getErrorMessageList(eb: ErrorBundle) ErrorMessageList { |
| 214 | eb.extra.items[0] += delta; | 79 | return eb.extraData(ErrorMessageList, 0).data; |
| 215 | } | 80 | } |
| 216 | 81 | ||
| 217 | pub fn getStartIndex(eb: ErrorBundle) u32 { | 82 | pub fn getMessages(eb: ErrorBundle) []const MessageIndex { |
| 218 | return eb.extra.items[1]; | 83 | const list = eb.getErrorMessageList(); |
| 219 | } | 84 | return @ptrCast([]const MessageIndex, eb.extra[list.start..][0..list.len]); |
| 220 | |||
| 221 | pub fn setStartIndex(eb: *ErrorBundle, index: u32) void { | ||
| 222 | eb.extra.items[1] = index; | ||
| 223 | } | 85 | } |
| 224 | 86 | ||
| 225 | pub fn getErrorMessage(eb: ErrorBundle, index: MessageIndex) ErrorMessage { | 87 | pub fn getErrorMessage(eb: ErrorBundle, index: MessageIndex) ErrorMessage { |
| 226 | return eb.extraData(ErrorMessage, @enumToInt(index)).data; | 88 | return eb.extraData(ErrorMessage, @enumToInt(index)).data; |
| 227 | } | 89 | } |
| 228 | 90 | ||
| 229 | pub fn getSourceLocation(eb: ErrorBundle, index: u32) SourceLocation { | 91 | pub fn getSourceLocation(eb: ErrorBundle, index: SourceLocationIndex) SourceLocation { |
| 230 | assert(index != 0); | 92 | assert(index != .none); |
| 231 | return eb.extraData(SourceLocation, index).data; | 93 | return eb.extraData(SourceLocation, @enumToInt(index)).data; |
| 94 | } | ||
| 95 | |||
| 96 | pub fn getNotes(eb: ErrorBundle, index: MessageIndex) []const MessageIndex { | ||
| 97 | const notes_len = eb.getErrorMessage(index).notes_len; | ||
| 98 | const start = @enumToInt(index) + @typeInfo(ErrorMessage).Struct.fields.len; | ||
| 99 | return @ptrCast([]const MessageIndex, eb.extra[start..][0..notes_len]); | ||
| 232 | } | 100 | } |
| 233 | 101 | ||
| 234 | /// Returns the requested data, as well as the new index which is at the start of the | 102 | /// Returns the requested data, as well as the new index which is at the start of the |
| ... | @@ -239,7 +107,9 @@ fn extraData(eb: ErrorBundle, comptime T: type, index: usize) struct { data: T, | ... | @@ -239,7 +107,9 @@ fn extraData(eb: ErrorBundle, comptime T: type, index: usize) struct { data: T, |
| 239 | var result: T = undefined; | 107 | var result: T = undefined; |
| 240 | inline for (fields) |field| { | 108 | inline for (fields) |field| { |
| 241 | @field(result, field.name) = switch (field.type) { | 109 | @field(result, field.name) = switch (field.type) { |
| 242 | u32 => eb.extra.items[i], | 110 | u32 => eb.extra[i], |
| 111 | MessageIndex => @intToEnum(MessageIndex, eb.extra[i]), | ||
| 112 | SourceLocationIndex => @intToEnum(SourceLocationIndex, eb.extra[i]), | ||
| 243 | else => @compileError("bad field type"), | 113 | else => @compileError("bad field type"), |
| 244 | }; | 114 | }; |
| 245 | i += 1; | 115 | i += 1; |
| ... | @@ -252,7 +122,7 @@ fn extraData(eb: ErrorBundle, comptime T: type, index: usize) struct { data: T, | ... | @@ -252,7 +122,7 @@ fn extraData(eb: ErrorBundle, comptime T: type, index: usize) struct { data: T, |
| 252 | 122 | ||
| 253 | /// Given an index into `string_bytes` returns the null-terminated string found there. | 123 | /// Given an index into `string_bytes` returns the null-terminated string found there. |
| 254 | pub fn nullTerminatedString(eb: ErrorBundle, index: usize) [:0]const u8 { | 124 | pub fn nullTerminatedString(eb: ErrorBundle, index: usize) [:0]const u8 { |
| 255 | const string_bytes = eb.string_bytes.items; | 125 | const string_bytes = eb.string_bytes; |
| 256 | var end: usize = index; | 126 | var end: usize = index; |
| 257 | while (string_bytes[end] != 0) { | 127 | while (string_bytes[end] != 0) { |
| 258 | end += 1; | 128 | end += 1; |
| ... | @@ -272,28 +142,25 @@ pub fn renderToWriter( | ... | @@ -272,28 +142,25 @@ pub fn renderToWriter( |
| 272 | ttyconf: std.debug.TTY.Config, | 142 | ttyconf: std.debug.TTY.Config, |
| 273 | writer: anytype, | 143 | writer: anytype, |
| 274 | ) anyerror!void { | 144 | ) anyerror!void { |
| 275 | const list = eb.extraData(ErrorMessageList, 0).data; | 145 | for (eb.getMessages()) |err_msg| { |
| 276 | var index: usize = list.start; | 146 | try renderErrorMessageToWriter(eb, err_msg, ttyconf, writer, "error", .Red, 0); |
| 277 | for (0..list.len) |_| { | ||
| 278 | const err_msg = eb.extraData(ErrorMessage, index); | ||
| 279 | index = try renderErrorMessageToWriter(eb, err_msg.data, err_msg.end, ttyconf, writer, "error", .Red, 0); | ||
| 280 | } | 147 | } |
| 281 | } | 148 | } |
| 282 | 149 | ||
| 283 | fn renderErrorMessageToWriter( | 150 | fn renderErrorMessageToWriter( |
| 284 | eb: ErrorBundle, | 151 | eb: ErrorBundle, |
| 285 | err_msg: ErrorMessage, | 152 | err_msg_index: MessageIndex, |
| 286 | end_index: usize, | ||
| 287 | ttyconf: std.debug.TTY.Config, | 153 | ttyconf: std.debug.TTY.Config, |
| 288 | stderr: anytype, | 154 | stderr: anytype, |
| 289 | kind: []const u8, | 155 | kind: []const u8, |
| 290 | color: std.debug.TTY.Color, | 156 | color: std.debug.TTY.Color, |
| 291 | indent: usize, | 157 | indent: usize, |
| 292 | ) anyerror!usize { | 158 | ) anyerror!void { |
| 293 | var counting_writer = std.io.countingWriter(stderr); | 159 | var counting_writer = std.io.countingWriter(stderr); |
| 294 | const counting_stderr = counting_writer.writer(); | 160 | const counting_stderr = counting_writer.writer(); |
| 295 | if (err_msg.src_loc != 0) { | 161 | const err_msg = eb.getErrorMessage(err_msg_index); |
| 296 | const src = eb.extraData(SourceLocation, err_msg.src_loc); | 162 | if (err_msg.src_loc != .none) { |
| 163 | const src = eb.extraData(SourceLocation, @enumToInt(err_msg.src_loc)); | ||
| 297 | try counting_stderr.writeByteNTimes(' ', indent); | 164 | try counting_stderr.writeByteNTimes(' ', indent); |
| 298 | try ttyconf.setColor(stderr, .Bold); | 165 | try ttyconf.setColor(stderr, .Bold); |
| 299 | try counting_stderr.print("{s}:{d}:{d}: ", .{ | 166 | try counting_stderr.print("{s}:{d}:{d}: ", .{ |
| ... | @@ -337,10 +204,8 @@ fn renderErrorMessageToWriter( | ... | @@ -337,10 +204,8 @@ fn renderErrorMessageToWriter( |
| 337 | try stderr.writeByte('\n'); | 204 | try stderr.writeByte('\n'); |
| 338 | try ttyconf.setColor(stderr, .Reset); | 205 | try ttyconf.setColor(stderr, .Reset); |
| 339 | } | 206 | } |
| 340 | var index = end_index; | 207 | for (eb.getNotes(err_msg_index)) |note| { |
| 341 | for (0..err_msg.notes_len) |_| { | 208 | try renderErrorMessageToWriter(eb, note, ttyconf, stderr, "note", .Cyan, indent); |
| 342 | const note = eb.extraData(ErrorMessage, index); | ||
| 343 | index = try renderErrorMessageToWriter(eb, note.data, note.end, ttyconf, stderr, "note", .Cyan, indent); | ||
| 344 | } | 209 | } |
| 345 | if (src.data.reference_trace_len > 0) { | 210 | if (src.data.reference_trace_len > 0) { |
| 346 | try ttyconf.setColor(stderr, .Reset); | 211 | try ttyconf.setColor(stderr, .Reset); |
| ... | @@ -350,7 +215,7 @@ fn renderErrorMessageToWriter( | ... | @@ -350,7 +215,7 @@ fn renderErrorMessageToWriter( |
| 350 | for (0..src.data.reference_trace_len) |_| { | 215 | for (0..src.data.reference_trace_len) |_| { |
| 351 | const ref_trace = eb.extraData(ReferenceTrace, ref_index); | 216 | const ref_trace = eb.extraData(ReferenceTrace, ref_index); |
| 352 | ref_index = ref_trace.end; | 217 | ref_index = ref_trace.end; |
| 353 | if (ref_trace.data.src_loc != 0) { | 218 | if (ref_trace.data.src_loc != .none) { |
| 354 | const ref_src = eb.getSourceLocation(ref_trace.data.src_loc); | 219 | const ref_src = eb.getSourceLocation(ref_trace.data.src_loc); |
| 355 | try stderr.print(" {s}: {s}:{d}:{d}\n", .{ | 220 | try stderr.print(" {s}: {s}:{d}:{d}\n", .{ |
| 356 | eb.nullTerminatedString(ref_trace.data.decl_name), | 221 | eb.nullTerminatedString(ref_trace.data.decl_name), |
| ... | @@ -374,7 +239,6 @@ fn renderErrorMessageToWriter( | ... | @@ -374,7 +239,6 @@ fn renderErrorMessageToWriter( |
| 374 | try stderr.writeByte('\n'); | 239 | try stderr.writeByte('\n'); |
| 375 | try ttyconf.setColor(stderr, .Reset); | 240 | try ttyconf.setColor(stderr, .Reset); |
| 376 | } | 241 | } |
| 377 | return index; | ||
| 378 | } else { | 242 | } else { |
| 379 | try ttyconf.setColor(stderr, color); | 243 | try ttyconf.setColor(stderr, color); |
| 380 | try stderr.writeByteNTimes(' ', indent); | 244 | try stderr.writeByteNTimes(' ', indent); |
| ... | @@ -390,12 +254,9 @@ fn renderErrorMessageToWriter( | ... | @@ -390,12 +254,9 @@ fn renderErrorMessageToWriter( |
| 390 | try stderr.print(" ({d} times)\n", .{err_msg.count}); | 254 | try stderr.print(" ({d} times)\n", .{err_msg.count}); |
| 391 | } | 255 | } |
| 392 | try ttyconf.setColor(stderr, .Reset); | 256 | try ttyconf.setColor(stderr, .Reset); |
| 393 | var index = end_index; | 257 | for (eb.getNotes(err_msg_index)) |note| { |
| 394 | for (0..err_msg.notes_len) |_| { | 258 | try renderErrorMessageToWriter(eb, note, ttyconf, stderr, "note", .Cyan, indent + 4); |
| 395 | const note = eb.extraData(ErrorMessage, index); | ||
| 396 | index = try renderErrorMessageToWriter(eb, note.data, note.end, ttyconf, stderr, "note", .Cyan, indent + 4); | ||
| 397 | } | 259 | } |
| 398 | return index; | ||
| 399 | } | 260 | } |
| 400 | } | 261 | } |
| 401 | 262 | ||
| ... | @@ -417,3 +278,186 @@ const std = @import("std"); | ... | @@ -417,3 +278,186 @@ const std = @import("std"); |
| 417 | const ErrorBundle = @This(); | 278 | const ErrorBundle = @This(); |
| 418 | const Allocator = std.mem.Allocator; | 279 | const Allocator = std.mem.Allocator; |
| 419 | const assert = std.debug.assert; | 280 | const assert = std.debug.assert; |
| 281 | |||
| 282 | pub const Wip = struct { | ||
| 283 | gpa: Allocator, | ||
| 284 | string_bytes: std.ArrayListUnmanaged(u8), | ||
| 285 | /// The first thing in this array is a ErrorMessageList. | ||
| 286 | extra: std.ArrayListUnmanaged(u32), | ||
| 287 | root_list: std.ArrayListUnmanaged(MessageIndex), | ||
| 288 | |||
| 289 | pub fn init(wip: *Wip, gpa: Allocator) !void { | ||
| 290 | wip.* = .{ | ||
| 291 | .gpa = gpa, | ||
| 292 | .string_bytes = .{}, | ||
| 293 | .extra = .{}, | ||
| 294 | .root_list = .{}, | ||
| 295 | }; | ||
| 296 | |||
| 297 | // So that 0 can be used to indicate a null string. | ||
| 298 | try wip.string_bytes.append(gpa, 0); | ||
| 299 | |||
| 300 | assert(0 == try addExtra(wip, ErrorMessageList{ | ||
| 301 | .len = 0, | ||
| 302 | .start = 0, | ||
| 303 | })); | ||
| 304 | } | ||
| 305 | |||
| 306 | pub fn deinit(wip: *Wip) void { | ||
| 307 | const gpa = wip.gpa; | ||
| 308 | wip.root_list.deinit(gpa); | ||
| 309 | wip.string_bytes.deinit(gpa); | ||
| 310 | wip.extra.deinit(gpa); | ||
| 311 | wip.* = undefined; | ||
| 312 | } | ||
| 313 | |||
| 314 | pub fn toOwnedBundle(wip: *Wip) !ErrorBundle { | ||
| 315 | const gpa = wip.gpa; | ||
| 316 | wip.setExtra(0, ErrorMessageList{ | ||
| 317 | .len = @intCast(u32, wip.root_list.items.len), | ||
| 318 | .start = @intCast(u32, wip.extra.items.len), | ||
| 319 | }); | ||
| 320 | try wip.extra.appendSlice(gpa, @ptrCast([]const u32, wip.root_list.items)); | ||
| 321 | wip.root_list.clearAndFree(gpa); | ||
| 322 | return .{ | ||
| 323 | .string_bytes = try wip.string_bytes.toOwnedSlice(gpa), | ||
| 324 | .extra = try wip.extra.toOwnedSlice(gpa), | ||
| 325 | }; | ||
| 326 | } | ||
| 327 | |||
| 328 | pub fn tmpBundle(wip: Wip) ErrorBundle { | ||
| 329 | return .{ | ||
| 330 | .string_bytes = wip.string_bytes.items, | ||
| 331 | .extra = wip.extra.items, | ||
| 332 | }; | ||
| 333 | } | ||
| 334 | |||
| 335 | pub fn addString(wip: *Wip, s: []const u8) !u32 { | ||
| 336 | const gpa = wip.gpa; | ||
| 337 | const index = @intCast(u32, wip.string_bytes.items.len); | ||
| 338 | try wip.string_bytes.ensureUnusedCapacity(gpa, s.len + 1); | ||
| 339 | wip.string_bytes.appendSliceAssumeCapacity(s); | ||
| 340 | wip.string_bytes.appendAssumeCapacity(0); | ||
| 341 | return index; | ||
| 342 | } | ||
| 343 | |||
| 344 | pub fn printString(wip: *Wip, comptime fmt: []const u8, args: anytype) !u32 { | ||
| 345 | const gpa = wip.gpa; | ||
| 346 | const index = @intCast(u32, wip.string_bytes.items.len); | ||
| 347 | try wip.string_bytes.writer(gpa).print(fmt, args); | ||
| 348 | try wip.string_bytes.append(gpa, 0); | ||
| 349 | return index; | ||
| 350 | } | ||
| 351 | |||
| 352 | pub fn addRootErrorMessage(wip: *Wip, em: ErrorMessage) !void { | ||
| 353 | try wip.root_list.ensureUnusedCapacity(wip.gpa, 1); | ||
| 354 | wip.root_list.appendAssumeCapacity(try addErrorMessage(wip, em)); | ||
| 355 | } | ||
| 356 | |||
| 357 | pub fn addErrorMessage(wip: *Wip, em: ErrorMessage) !MessageIndex { | ||
| 358 | return @intToEnum(MessageIndex, try addExtra(wip, em)); | ||
| 359 | } | ||
| 360 | |||
| 361 | pub fn addErrorMessageAssumeCapacity(wip: *Wip, em: ErrorMessage) MessageIndex { | ||
| 362 | return @intToEnum(MessageIndex, addExtraAssumeCapacity(wip, em)); | ||
| 363 | } | ||
| 364 | |||
| 365 | pub fn addSourceLocation(wip: *Wip, sl: SourceLocation) !SourceLocationIndex { | ||
| 366 | return @intToEnum(SourceLocationIndex, try addExtra(wip, sl)); | ||
| 367 | } | ||
| 368 | |||
| 369 | pub fn addReferenceTrace(wip: *Wip, rt: ReferenceTrace) !void { | ||
| 370 | _ = try addExtra(wip, rt); | ||
| 371 | } | ||
| 372 | |||
| 373 | pub fn addBundle(wip: *Wip, other: ErrorBundle) !void { | ||
| 374 | const gpa = wip.gpa; | ||
| 375 | |||
| 376 | try wip.string_bytes.ensureUnusedCapacity(gpa, other.string_bytes.len); | ||
| 377 | try wip.extra.ensureUnusedCapacity(gpa, other.extra.len); | ||
| 378 | |||
| 379 | const other_list = other.getMessages(); | ||
| 380 | |||
| 381 | // The ensureUnusedCapacity call above guarantees this. | ||
| 382 | const notes_start = wip.reserveNotes(@intCast(u32, other_list.len)) catch unreachable; | ||
| 383 | for (notes_start.., other_list) |note, message| { | ||
| 384 | wip.extra.items[note] = @enumToInt(wip.addOtherMessage(other, message) catch unreachable); | ||
| 385 | } | ||
| 386 | } | ||
| 387 | |||
| 388 | pub fn reserveNotes(wip: *Wip, notes_len: u32) !u32 { | ||
| 389 | try wip.extra.ensureUnusedCapacity(wip.gpa, notes_len + | ||
| 390 | notes_len * @typeInfo(ErrorBundle.ErrorMessage).Struct.fields.len); | ||
| 391 | wip.extra.items.len += notes_len; | ||
| 392 | return @intCast(u32, wip.extra.items.len - notes_len); | ||
| 393 | } | ||
| 394 | |||
| 395 | fn addOtherMessage(wip: *Wip, other: ErrorBundle, msg_index: MessageIndex) !MessageIndex { | ||
| 396 | const other_msg = other.getErrorMessage(msg_index); | ||
| 397 | const src_loc = try wip.addOtherSourceLocation(other, other_msg.src_loc); | ||
| 398 | const msg = try wip.addErrorMessage(.{ | ||
| 399 | .msg = try wip.addString(other.nullTerminatedString(other_msg.msg)), | ||
| 400 | .count = other_msg.count, | ||
| 401 | .src_loc = src_loc, | ||
| 402 | .notes_len = other_msg.notes_len, | ||
| 403 | }); | ||
| 404 | const notes_start = try wip.reserveNotes(other_msg.notes_len); | ||
| 405 | for (notes_start.., other.getNotes(msg_index)) |note, other_note| { | ||
| 406 | wip.extra.items[note] = @enumToInt(try wip.addOtherMessage(other, other_note)); | ||
| 407 | } | ||
| 408 | return msg; | ||
| 409 | } | ||
| 410 | |||
| 411 | fn addOtherSourceLocation( | ||
| 412 | wip: *Wip, | ||
| 413 | other: ErrorBundle, | ||
| 414 | index: SourceLocationIndex, | ||
| 415 | ) !SourceLocationIndex { | ||
| 416 | if (index == .none) return .none; | ||
| 417 | const other_sl = other.getSourceLocation(index); | ||
| 418 | |||
| 419 | const src_loc = try wip.addSourceLocation(.{ | ||
| 420 | .src_path = try wip.addString(other.nullTerminatedString(other_sl.src_path)), | ||
| 421 | .line = other_sl.line, | ||
| 422 | .column = other_sl.column, | ||
| 423 | .span_start = other_sl.span_start, | ||
| 424 | .span_main = other_sl.span_main, | ||
| 425 | .span_end = other_sl.span_end, | ||
| 426 | .source_line = try wip.addString(other.nullTerminatedString(other_sl.source_line)), | ||
| 427 | .reference_trace_len = other_sl.reference_trace_len, | ||
| 428 | }); | ||
| 429 | |||
| 430 | // TODO: also add the reference trace | ||
| 431 | |||
| 432 | return src_loc; | ||
| 433 | } | ||
| 434 | |||
| 435 | fn addExtra(wip: *Wip, extra: anytype) Allocator.Error!u32 { | ||
| 436 | const gpa = wip.gpa; | ||
| 437 | const fields = @typeInfo(@TypeOf(extra)).Struct.fields; | ||
| 438 | try wip.extra.ensureUnusedCapacity(gpa, fields.len); | ||
| 439 | return addExtraAssumeCapacity(wip, extra); | ||
| 440 | } | ||
| 441 | |||
| 442 | fn addExtraAssumeCapacity(wip: *Wip, extra: anytype) u32 { | ||
| 443 | const fields = @typeInfo(@TypeOf(extra)).Struct.fields; | ||
| 444 | const result = @intCast(u32, wip.extra.items.len); | ||
| 445 | wip.extra.items.len += fields.len; | ||
| 446 | setExtra(wip, result, extra); | ||
| 447 | return result; | ||
| 448 | } | ||
| 449 | |||
| 450 | fn setExtra(wip: *Wip, index: usize, extra: anytype) void { | ||
| 451 | const fields = @typeInfo(@TypeOf(extra)).Struct.fields; | ||
| 452 | var i = index; | ||
| 453 | inline for (fields) |field| { | ||
| 454 | wip.extra.items[i] = switch (field.type) { | ||
| 455 | u32 => @field(extra, field.name), | ||
| 456 | MessageIndex => @enumToInt(@field(extra, field.name)), | ||
| 457 | SourceLocationIndex => @enumToInt(@field(extra, field.name)), | ||
| 458 | else => @compileError("bad field type"), | ||
| 459 | }; | ||
| 460 | i += 1; | ||
| 461 | } | ||
| 462 | } | ||
| 463 | }; |
src/Compilation.zig+123-130| ... | @@ -2546,9 +2546,9 @@ pub fn totalErrorCount(self: *Compilation) u32 { | ... | @@ -2546,9 +2546,9 @@ pub fn totalErrorCount(self: *Compilation) u32 { |
| 2546 | pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { | 2546 | pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 2547 | const gpa = self.gpa; | 2547 | const gpa = self.gpa; |
| 2548 | 2548 | ||
| 2549 | var bundle: ErrorBundle = undefined; | 2549 | var bundle: ErrorBundle.Wip = undefined; |
| 2550 | try bundle.init(gpa); | 2550 | try bundle.init(gpa); |
| 2551 | errdefer bundle.deinit(gpa); | 2551 | defer bundle.deinit(); |
| 2552 | 2552 | ||
| 2553 | { | 2553 | { |
| 2554 | var it = self.failed_c_objects.iterator(); | 2554 | var it = self.failed_c_objects.iterator(); |
| ... | @@ -2557,12 +2557,10 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { | ... | @@ -2557,12 +2557,10 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 2557 | const err_msg = entry.value_ptr.*; | 2557 | const err_msg = entry.value_ptr.*; |
| 2558 | // TODO these fields will need to be adjusted when we have proper | 2558 | // TODO these fields will need to be adjusted when we have proper |
| 2559 | // C error reporting bubbling up. | 2559 | // C error reporting bubbling up. |
| 2560 | try bundle.addErrorMessage(gpa, .{ | 2560 | try bundle.addRootErrorMessage(.{ |
| 2561 | .msg = try bundle.printString(gpa, "unable to build C object: {s}", .{ | 2561 | .msg = try bundle.printString("unable to build C object: {s}", .{err_msg.msg}), |
| 2562 | err_msg.msg, | 2562 | .src_loc = try bundle.addSourceLocation(.{ |
| 2563 | }), | 2563 | .src_path = try bundle.addString(c_object.src.src_path), |
| 2564 | .src_loc = try bundle.addSourceLocation(gpa, .{ | ||
| 2565 | .src_path = try bundle.addString(gpa, c_object.src.src_path), | ||
| 2566 | .span_start = 0, | 2564 | .span_start = 0, |
| 2567 | .span_main = 0, | 2565 | .span_main = 0, |
| 2568 | .span_end = 1, | 2566 | .span_end = 1, |
| ... | @@ -2571,49 +2569,46 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { | ... | @@ -2571,49 +2569,46 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 2571 | .source_line = 0, // TODO | 2569 | .source_line = 0, // TODO |
| 2572 | }), | 2570 | }), |
| 2573 | }); | 2571 | }); |
| 2574 | bundle.incrementCount(1); | ||
| 2575 | } | 2572 | } |
| 2576 | } | 2573 | } |
| 2577 | 2574 | ||
| 2578 | for (self.lld_errors.items) |lld_error| { | 2575 | for (self.lld_errors.items) |lld_error| { |
| 2579 | try bundle.addErrorMessage(gpa, .{ | 2576 | const notes_len = @intCast(u32, lld_error.context_lines.len); |
| 2580 | .msg = try bundle.addString(gpa, lld_error.msg), | ||
| 2581 | .notes_len = @intCast(u32, lld_error.context_lines.len), | ||
| 2582 | }); | ||
| 2583 | bundle.incrementCount(1); | ||
| 2584 | 2577 | ||
| 2585 | for (lld_error.context_lines) |context_line| { | 2578 | try bundle.addRootErrorMessage(.{ |
| 2586 | try bundle.addErrorMessage(gpa, .{ | 2579 | .msg = try bundle.addString(lld_error.msg), |
| 2587 | .msg = try bundle.addString(gpa, context_line), | 2580 | .notes_len = notes_len, |
| 2588 | }); | 2581 | }); |
| 2582 | const notes_start = try bundle.reserveNotes(notes_len); | ||
| 2583 | for (notes_start.., lld_error.context_lines) |note, context_line| { | ||
| 2584 | bundle.extra.items[note] = @enumToInt(bundle.addErrorMessageAssumeCapacity(.{ | ||
| 2585 | .msg = try bundle.addString(context_line), | ||
| 2586 | })); | ||
| 2589 | } | 2587 | } |
| 2590 | } | 2588 | } |
| 2591 | for (self.misc_failures.values()) |*value| { | 2589 | for (self.misc_failures.values()) |*value| { |
| 2592 | try bundle.addErrorMessage(gpa, .{ | 2590 | try bundle.addRootErrorMessage(.{ |
| 2593 | .msg = try bundle.addString(gpa, value.msg), | 2591 | .msg = try bundle.addString(value.msg), |
| 2594 | .notes_len = if (value.children) |b| b.errorMessageCount() else 0, | 2592 | .notes_len = if (value.children) |b| b.errorMessageCount() else 0, |
| 2595 | }); | 2593 | }); |
| 2596 | if (value.children) |b| try bundle.addBundle(gpa, b); | 2594 | if (value.children) |b| try bundle.addBundle(b); |
| 2597 | bundle.incrementCount(1); | ||
| 2598 | } | 2595 | } |
| 2599 | if (self.alloc_failure_occurred) { | 2596 | if (self.alloc_failure_occurred) { |
| 2600 | try bundle.addErrorMessage(gpa, .{ | 2597 | try bundle.addRootErrorMessage(.{ |
| 2601 | .msg = try bundle.addString(gpa, "memory allocation failure"), | 2598 | .msg = try bundle.addString("memory allocation failure"), |
| 2602 | }); | 2599 | }); |
| 2603 | bundle.incrementCount(1); | ||
| 2604 | } | 2600 | } |
| 2605 | if (self.bin_file.options.module) |module| { | 2601 | if (self.bin_file.options.module) |module| { |
| 2606 | { | 2602 | { |
| 2607 | var it = module.failed_files.iterator(); | 2603 | var it = module.failed_files.iterator(); |
| 2608 | while (it.next()) |entry| { | 2604 | while (it.next()) |entry| { |
| 2609 | if (entry.value_ptr.*) |msg| { | 2605 | if (entry.value_ptr.*) |msg| { |
| 2610 | try addModuleErrorMsg(gpa, &bundle, msg.*); | 2606 | try addModuleErrorMsg(&bundle, msg.*); |
| 2611 | } else { | 2607 | } else { |
| 2612 | // Must be ZIR errors. In order for ZIR errors to exist, the parsing | 2608 | // Must be ZIR errors. Note that this may include AST errors. |
| 2613 | // must have completed successfully. | 2609 | // addZirErrorMessages asserts that the tree is loaded. |
| 2614 | const tree = try entry.key_ptr.*.getTree(module.gpa); | 2610 | _ = try entry.key_ptr.*.getTree(gpa); |
| 2615 | assert(tree.errors.len == 0); | 2611 | try addZirErrorMessages(&bundle, entry.key_ptr.*); |
| 2616 | try addZirErrorMessages(gpa, &bundle, entry.key_ptr.*); | ||
| 2617 | } | 2612 | } |
| 2618 | } | 2613 | } |
| 2619 | } | 2614 | } |
| ... | @@ -2621,7 +2616,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { | ... | @@ -2621,7 +2616,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 2621 | var it = module.failed_embed_files.iterator(); | 2616 | var it = module.failed_embed_files.iterator(); |
| 2622 | while (it.next()) |entry| { | 2617 | while (it.next()) |entry| { |
| 2623 | const msg = entry.value_ptr.*; | 2618 | const msg = entry.value_ptr.*; |
| 2624 | try addModuleErrorMsg(gpa, &bundle, msg.*); | 2619 | try addModuleErrorMsg(&bundle, msg.*); |
| 2625 | } | 2620 | } |
| 2626 | } | 2621 | } |
| 2627 | { | 2622 | { |
| ... | @@ -2631,21 +2626,20 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { | ... | @@ -2631,21 +2626,20 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 2631 | // Skip errors for Decls within files that had a parse failure. | 2626 | // Skip errors for Decls within files that had a parse failure. |
| 2632 | // We'll try again once parsing succeeds. | 2627 | // We'll try again once parsing succeeds. |
| 2633 | if (decl.getFileScope().okToReportErrors()) { | 2628 | if (decl.getFileScope().okToReportErrors()) { |
| 2634 | try addModuleErrorMsg(gpa, &bundle, entry.value_ptr.*.*); | 2629 | try addModuleErrorMsg(&bundle, entry.value_ptr.*.*); |
| 2635 | if (module.cimport_errors.get(entry.key_ptr.*)) |cimport_errors| for (cimport_errors) |c_error| { | 2630 | if (module.cimport_errors.get(entry.key_ptr.*)) |cimport_errors| for (cimport_errors) |c_error| { |
| 2636 | try bundle.addErrorMessage(gpa, .{ | 2631 | try bundle.addRootErrorMessage(.{ |
| 2637 | .msg = try bundle.addString(gpa, std.mem.span(c_error.msg)), | 2632 | .msg = try bundle.addString(std.mem.span(c_error.msg)), |
| 2638 | .src_loc = if (c_error.path) |some| try bundle.addSourceLocation(gpa, .{ | 2633 | .src_loc = if (c_error.path) |some| try bundle.addSourceLocation(.{ |
| 2639 | .src_path = try bundle.addString(gpa, std.mem.span(some)), | 2634 | .src_path = try bundle.addString(std.mem.span(some)), |
| 2640 | .span_start = c_error.offset, | 2635 | .span_start = c_error.offset, |
| 2641 | .span_main = c_error.offset, | 2636 | .span_main = c_error.offset, |
| 2642 | .span_end = c_error.offset + 1, | 2637 | .span_end = c_error.offset + 1, |
| 2643 | .line = c_error.line, | 2638 | .line = c_error.line, |
| 2644 | .column = c_error.column, | 2639 | .column = c_error.column, |
| 2645 | .source_line = if (c_error.source_line) |line| try bundle.addString(gpa, std.mem.span(line)) else 0, | 2640 | .source_line = if (c_error.source_line) |line| try bundle.addString(std.mem.span(line)) else 0, |
| 2646 | }) else 0, | 2641 | }) else .none, |
| 2647 | }); | 2642 | }); |
| 2648 | bundle.incrementCount(1); | ||
| 2649 | }; | 2643 | }; |
| 2650 | } | 2644 | } |
| 2651 | } | 2645 | } |
| ... | @@ -2657,40 +2651,39 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { | ... | @@ -2657,40 +2651,39 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 2657 | // Skip errors for Decls within files that had a parse failure. | 2651 | // Skip errors for Decls within files that had a parse failure. |
| 2658 | // We'll try again once parsing succeeds. | 2652 | // We'll try again once parsing succeeds. |
| 2659 | if (decl.getFileScope().okToReportErrors()) { | 2653 | if (decl.getFileScope().okToReportErrors()) { |
| 2660 | try addModuleErrorMsg(gpa, &bundle, entry.value_ptr.*.*); | 2654 | try addModuleErrorMsg(&bundle, entry.value_ptr.*.*); |
| 2661 | } | 2655 | } |
| 2662 | } | 2656 | } |
| 2663 | } | 2657 | } |
| 2664 | for (module.failed_exports.values()) |value| { | 2658 | for (module.failed_exports.values()) |value| { |
| 2665 | try addModuleErrorMsg(gpa, &bundle, value.*); | 2659 | try addModuleErrorMsg(&bundle, value.*); |
| 2666 | } | 2660 | } |
| 2667 | } | 2661 | } |
| 2668 | 2662 | ||
| 2669 | if (bundle.errorMessageCount() == 0) { | 2663 | if (bundle.root_list.items.len == 0) { |
| 2670 | if (self.link_error_flags.no_entry_point_found) { | 2664 | if (self.link_error_flags.no_entry_point_found) { |
| 2671 | try bundle.addErrorMessage(gpa, .{ | 2665 | try bundle.addRootErrorMessage(.{ |
| 2672 | .msg = try bundle.addString(gpa, "no entry point found"), | 2666 | .msg = try bundle.addString("no entry point found"), |
| 2673 | }); | 2667 | }); |
| 2674 | bundle.incrementCount(1); | ||
| 2675 | } | 2668 | } |
| 2676 | } | 2669 | } |
| 2677 | 2670 | ||
| 2678 | if (self.link_error_flags.missing_libc) { | 2671 | if (self.link_error_flags.missing_libc) { |
| 2679 | try bundle.addErrorMessage(gpa, .{ | 2672 | try bundle.addRootErrorMessage(.{ |
| 2680 | .msg = try bundle.addString(gpa, "libc not available"), | 2673 | .msg = try bundle.addString("libc not available"), |
| 2681 | .notes_len = 2, | 2674 | .notes_len = 2, |
| 2682 | }); | 2675 | }); |
| 2683 | try bundle.addErrorMessage(gpa, .{ | 2676 | const notes_start = try bundle.reserveNotes(2); |
| 2684 | .msg = try bundle.addString(gpa, "run 'zig libc -h' to learn about libc installations"), | 2677 | bundle.extra.items[notes_start + 0] = @enumToInt(try bundle.addErrorMessage(.{ |
| 2685 | }); | 2678 | .msg = try bundle.addString("run 'zig libc -h' to learn about libc installations"), |
| 2686 | try bundle.addErrorMessage(gpa, .{ | 2679 | })); |
| 2687 | .msg = try bundle.addString(gpa, "run 'zig targets' to see the targets for which zig can always provide libc"), | 2680 | bundle.extra.items[notes_start + 1] = @enumToInt(try bundle.addErrorMessage(.{ |
| 2688 | }); | 2681 | .msg = try bundle.addString("run 'zig targets' to see the targets for which zig can always provide libc"), |
| 2689 | bundle.incrementCount(1); | 2682 | })); |
| 2690 | } | 2683 | } |
| 2691 | 2684 | ||
| 2692 | if (self.bin_file.options.module) |module| { | 2685 | if (self.bin_file.options.module) |module| { |
| 2693 | if (bundle.errorMessageCount() == 0 and module.compile_log_decls.count() != 0) { | 2686 | if (bundle.root_list.items.len == 0 and module.compile_log_decls.count() != 0) { |
| 2694 | const keys = module.compile_log_decls.keys(); | 2687 | const keys = module.compile_log_decls.keys(); |
| 2695 | const values = module.compile_log_decls.values(); | 2688 | const values = module.compile_log_decls.values(); |
| 2696 | // First one will be the error; subsequent ones will be notes. | 2689 | // First one will be the error; subsequent ones will be notes. |
| ... | @@ -2699,9 +2692,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { | ... | @@ -2699,9 +2692,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 2699 | const err_msg = Module.ErrorMsg{ | 2692 | const err_msg = Module.ErrorMsg{ |
| 2700 | .src_loc = src_loc, | 2693 | .src_loc = src_loc, |
| 2701 | .msg = "found compile log statement", | 2694 | .msg = "found compile log statement", |
| 2702 | .notes = try self.gpa.alloc(Module.ErrorMsg, module.compile_log_decls.count() - 1), | 2695 | .notes = try gpa.alloc(Module.ErrorMsg, module.compile_log_decls.count() - 1), |
| 2703 | }; | 2696 | }; |
| 2704 | defer self.gpa.free(err_msg.notes); | 2697 | defer gpa.free(err_msg.notes); |
| 2705 | 2698 | ||
| 2706 | for (keys[1..], 0..) |key, i| { | 2699 | for (keys[1..], 0..) |key, i| { |
| 2707 | const note_decl = module.declPtr(key); | 2700 | const note_decl = module.declPtr(key); |
| ... | @@ -2711,25 +2704,26 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { | ... | @@ -2711,25 +2704,26 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle { |
| 2711 | }; | 2704 | }; |
| 2712 | } | 2705 | } |
| 2713 | 2706 | ||
| 2714 | try addModuleErrorMsg(gpa, &bundle, err_msg); | 2707 | try addModuleErrorMsg(&bundle, err_msg); |
| 2715 | } | 2708 | } |
| 2716 | } | 2709 | } |
| 2717 | 2710 | ||
| 2718 | assert(self.totalErrorCount() == bundle.errorMessageCount()); | 2711 | assert(self.totalErrorCount() == bundle.root_list.items.len); |
| 2719 | 2712 | ||
| 2720 | return bundle; | 2713 | return bundle.toOwnedBundle(); |
| 2721 | } | 2714 | } |
| 2722 | 2715 | ||
| 2723 | pub const ErrorNoteHashContext = struct { | 2716 | pub const ErrorNoteHashContext = struct { |
| 2724 | eb: *const ErrorBundle, | 2717 | eb: *const ErrorBundle.Wip, |
| 2725 | 2718 | ||
| 2726 | pub fn hash(ctx: ErrorNoteHashContext, key: ErrorBundle.ErrorMessage) u32 { | 2719 | pub fn hash(ctx: ErrorNoteHashContext, key: ErrorBundle.ErrorMessage) u32 { |
| 2727 | var hasher = std.hash.Wyhash.init(0); | 2720 | var hasher = std.hash.Wyhash.init(0); |
| 2721 | const eb = ctx.eb.tmpBundle(); | ||
| 2728 | 2722 | ||
| 2729 | hasher.update(ctx.eb.nullTerminatedString(key.msg)); | 2723 | hasher.update(eb.nullTerminatedString(key.msg)); |
| 2730 | if (key.src_loc != 0) { | 2724 | if (key.src_loc != .none) { |
| 2731 | const src = ctx.eb.getSourceLocation(key.src_loc); | 2725 | const src = eb.getSourceLocation(key.src_loc); |
| 2732 | hasher.update(ctx.eb.nullTerminatedString(src.src_path)); | 2726 | hasher.update(eb.nullTerminatedString(src.src_path)); |
| 2733 | std.hash.autoHash(&hasher, src.line); | 2727 | std.hash.autoHash(&hasher, src.line); |
| 2734 | std.hash.autoHash(&hasher, src.column); | 2728 | std.hash.autoHash(&hasher, src.column); |
| 2735 | std.hash.autoHash(&hasher, src.span_main); | 2729 | std.hash.autoHash(&hasher, src.span_main); |
| ... | @@ -2745,17 +2739,18 @@ pub const ErrorNoteHashContext = struct { | ... | @@ -2745,17 +2739,18 @@ pub const ErrorNoteHashContext = struct { |
| 2745 | b_index: usize, | 2739 | b_index: usize, |
| 2746 | ) bool { | 2740 | ) bool { |
| 2747 | _ = b_index; | 2741 | _ = b_index; |
| 2748 | const msg_a = ctx.eb.nullTerminatedString(a.msg); | 2742 | const eb = ctx.eb.tmpBundle(); |
| 2749 | const msg_b = ctx.eb.nullTerminatedString(b.msg); | 2743 | const msg_a = eb.nullTerminatedString(a.msg); |
| 2744 | const msg_b = eb.nullTerminatedString(b.msg); | ||
| 2750 | if (!std.mem.eql(u8, msg_a, msg_b)) return false; | 2745 | if (!std.mem.eql(u8, msg_a, msg_b)) return false; |
| 2751 | 2746 | ||
| 2752 | if (a.src_loc == 0 and b.src_loc == 0) return true; | 2747 | if (a.src_loc == .none and b.src_loc == .none) return true; |
| 2753 | if (a.src_loc == 0 or b.src_loc == 0) return false; | 2748 | if (a.src_loc == .none or b.src_loc == .none) return false; |
| 2754 | const src_a = ctx.eb.getSourceLocation(a.src_loc); | 2749 | const src_a = eb.getSourceLocation(a.src_loc); |
| 2755 | const src_b = ctx.eb.getSourceLocation(b.src_loc); | 2750 | const src_b = eb.getSourceLocation(b.src_loc); |
| 2756 | 2751 | ||
| 2757 | const src_path_a = ctx.eb.nullTerminatedString(src_a.src_path); | 2752 | const src_path_a = eb.nullTerminatedString(src_a.src_path); |
| 2758 | const src_path_b = ctx.eb.nullTerminatedString(src_b.src_path); | 2753 | const src_path_b = eb.nullTerminatedString(src_b.src_path); |
| 2759 | 2754 | ||
| 2760 | return std.mem.eql(u8, src_path_a, src_path_b) and | 2755 | return std.mem.eql(u8, src_path_a, src_path_b) and |
| 2761 | src_a.line == src_b.line and | 2756 | src_a.line == src_b.line and |
| ... | @@ -2764,16 +2759,16 @@ pub const ErrorNoteHashContext = struct { | ... | @@ -2764,16 +2759,16 @@ pub const ErrorNoteHashContext = struct { |
| 2764 | } | 2759 | } |
| 2765 | }; | 2760 | }; |
| 2766 | 2761 | ||
| 2767 | pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Module.ErrorMsg) !void { | 2762 | pub fn addModuleErrorMsg(eb: *ErrorBundle.Wip, module_err_msg: Module.ErrorMsg) !void { |
| 2763 | const gpa = eb.gpa; | ||
| 2768 | const err_source = module_err_msg.src_loc.file_scope.getSource(gpa) catch |err| { | 2764 | const err_source = module_err_msg.src_loc.file_scope.getSource(gpa) catch |err| { |
| 2769 | const file_path = try module_err_msg.src_loc.file_scope.fullPath(gpa); | 2765 | const file_path = try module_err_msg.src_loc.file_scope.fullPath(gpa); |
| 2770 | defer gpa.free(file_path); | 2766 | defer gpa.free(file_path); |
| 2771 | try eb.addErrorMessage(gpa, .{ | 2767 | try eb.addRootErrorMessage(.{ |
| 2772 | .msg = try eb.printString(gpa, "unable to load '{s}': {s}", .{ | 2768 | .msg = try eb.printString("unable to load '{s}': {s}", .{ |
| 2773 | file_path, @errorName(err), | 2769 | file_path, @errorName(err), |
| 2774 | }), | 2770 | }), |
| 2775 | }); | 2771 | }); |
| 2776 | eb.incrementCount(1); | ||
| 2777 | return; | 2772 | return; |
| 2778 | }; | 2773 | }; |
| 2779 | const err_span = try module_err_msg.src_loc.span(gpa); | 2774 | const err_span = try module_err_msg.src_loc.span(gpa); |
| ... | @@ -2788,13 +2783,13 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul | ... | @@ -2788,13 +2783,13 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul |
| 2788 | if (module_reference.hidden != 0) { | 2783 | if (module_reference.hidden != 0) { |
| 2789 | try ref_traces.append(gpa, .{ | 2784 | try ref_traces.append(gpa, .{ |
| 2790 | .decl_name = module_reference.hidden, | 2785 | .decl_name = module_reference.hidden, |
| 2791 | .src_loc = 0, | 2786 | .src_loc = .none, |
| 2792 | }); | 2787 | }); |
| 2793 | break; | 2788 | break; |
| 2794 | } else if (module_reference.decl == null) { | 2789 | } else if (module_reference.decl == null) { |
| 2795 | try ref_traces.append(gpa, .{ | 2790 | try ref_traces.append(gpa, .{ |
| 2796 | .decl_name = 0, | 2791 | .decl_name = 0, |
| 2797 | .src_loc = 0, | 2792 | .src_loc = .none, |
| 2798 | }); | 2793 | }); |
| 2799 | break; | 2794 | break; |
| 2800 | } | 2795 | } |
| ... | @@ -2804,9 +2799,9 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul | ... | @@ -2804,9 +2799,9 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul |
| 2804 | const rt_file_path = try module_reference.src_loc.file_scope.fullPath(gpa); | 2799 | const rt_file_path = try module_reference.src_loc.file_scope.fullPath(gpa); |
| 2805 | defer gpa.free(rt_file_path); | 2800 | defer gpa.free(rt_file_path); |
| 2806 | try ref_traces.append(gpa, .{ | 2801 | try ref_traces.append(gpa, .{ |
| 2807 | .decl_name = try eb.addString(gpa, std.mem.sliceTo(module_reference.decl.?, 0)), | 2802 | .decl_name = try eb.addString(std.mem.sliceTo(module_reference.decl.?, 0)), |
| 2808 | .src_loc = try eb.addSourceLocation(gpa, .{ | 2803 | .src_loc = try eb.addSourceLocation(.{ |
| 2809 | .src_path = try eb.addString(gpa, rt_file_path), | 2804 | .src_path = try eb.addString(rt_file_path), |
| 2810 | .span_start = span.start, | 2805 | .span_start = span.start, |
| 2811 | .span_main = span.main, | 2806 | .span_main = span.main, |
| 2812 | .span_end = span.end, | 2807 | .span_end = span.end, |
| ... | @@ -2817,8 +2812,8 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul | ... | @@ -2817,8 +2812,8 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul |
| 2817 | }); | 2812 | }); |
| 2818 | } | 2813 | } |
| 2819 | 2814 | ||
| 2820 | const src_loc = try eb.addSourceLocation(gpa, .{ | 2815 | const src_loc = try eb.addSourceLocation(.{ |
| 2821 | .src_path = try eb.addString(gpa, file_path), | 2816 | .src_path = try eb.addString(file_path), |
| 2822 | .span_start = err_span.start, | 2817 | .span_start = err_span.start, |
| 2823 | .span_main = err_span.main, | 2818 | .span_main = err_span.main, |
| 2824 | .span_end = err_span.end, | 2819 | .span_end = err_span.end, |
| ... | @@ -2827,12 +2822,12 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul | ... | @@ -2827,12 +2822,12 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul |
| 2827 | .source_line = if (module_err_msg.src_loc.lazy == .entire_file) | 2822 | .source_line = if (module_err_msg.src_loc.lazy == .entire_file) |
| 2828 | 0 | 2823 | 0 |
| 2829 | else | 2824 | else |
| 2830 | try eb.addString(gpa, err_loc.source_line), | 2825 | try eb.addString(err_loc.source_line), |
| 2831 | .reference_trace_len = @intCast(u32, ref_traces.items.len), | 2826 | .reference_trace_len = @intCast(u32, ref_traces.items.len), |
| 2832 | }); | 2827 | }); |
| 2833 | 2828 | ||
| 2834 | for (ref_traces.items) |rt| { | 2829 | for (ref_traces.items) |rt| { |
| 2835 | try eb.addReferenceTrace(gpa, rt); | 2830 | try eb.addReferenceTrace(rt); |
| 2836 | } | 2831 | } |
| 2837 | 2832 | ||
| 2838 | // De-duplicate error notes. The main use case in mind for this is | 2833 | // De-duplicate error notes. The main use case in mind for this is |
| ... | @@ -2848,15 +2843,15 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul | ... | @@ -2848,15 +2843,15 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul |
| 2848 | defer gpa.free(note_file_path); | 2843 | defer gpa.free(note_file_path); |
| 2849 | 2844 | ||
| 2850 | const gop = try notes.getOrPutContext(gpa, .{ | 2845 | const gop = try notes.getOrPutContext(gpa, .{ |
| 2851 | .msg = try eb.addString(gpa, module_note.msg), | 2846 | .msg = try eb.addString(module_note.msg), |
| 2852 | .src_loc = try eb.addSourceLocation(gpa, .{ | 2847 | .src_loc = try eb.addSourceLocation(.{ |
| 2853 | .src_path = try eb.addString(gpa, note_file_path), | 2848 | .src_path = try eb.addString(note_file_path), |
| 2854 | .span_start = span.start, | 2849 | .span_start = span.start, |
| 2855 | .span_main = span.main, | 2850 | .span_main = span.main, |
| 2856 | .span_end = span.end, | 2851 | .span_end = span.end, |
| 2857 | .line = @intCast(u32, loc.line), | 2852 | .line = @intCast(u32, loc.line), |
| 2858 | .column = @intCast(u32, loc.column), | 2853 | .column = @intCast(u32, loc.column), |
| 2859 | .source_line = if (err_loc.eql(loc)) 0 else try eb.addString(gpa, loc.source_line), | 2854 | .source_line = if (err_loc.eql(loc)) 0 else try eb.addString(loc.source_line), |
| 2860 | }), | 2855 | }), |
| 2861 | }, .{ .eb = eb }); | 2856 | }, .{ .eb = eb }); |
| 2862 | if (gop.found_existing) { | 2857 | if (gop.found_existing) { |
| ... | @@ -2864,24 +2859,28 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul | ... | @@ -2864,24 +2859,28 @@ pub fn addModuleErrorMsg(gpa: Allocator, eb: *ErrorBundle, module_err_msg: Modul |
| 2864 | } | 2859 | } |
| 2865 | } | 2860 | } |
| 2866 | 2861 | ||
| 2867 | try eb.addErrorMessage(gpa, .{ | 2862 | const notes_len = @intCast(u32, notes.entries.len); |
| 2868 | .msg = try eb.addString(gpa, module_err_msg.msg), | 2863 | |
| 2864 | try eb.addRootErrorMessage(.{ | ||
| 2865 | .msg = try eb.addString(module_err_msg.msg), | ||
| 2869 | .src_loc = src_loc, | 2866 | .src_loc = src_loc, |
| 2870 | .notes_len = @intCast(u32, notes.entries.len), | 2867 | .notes_len = notes_len, |
| 2871 | }); | 2868 | }); |
| 2872 | eb.incrementCount(1); | ||
| 2873 | 2869 | ||
| 2874 | for (notes.keys()) |note| { | 2870 | const notes_start = try eb.reserveNotes(notes_len); |
| 2875 | try eb.addErrorMessage(gpa, note); | 2871 | |
| 2872 | for (notes_start.., notes.keys()) |i, note| { | ||
| 2873 | eb.extra.items[i] = @enumToInt(try eb.addErrorMessage(note)); | ||
| 2876 | } | 2874 | } |
| 2877 | } | 2875 | } |
| 2878 | 2876 | ||
| 2879 | pub fn addZirErrorMessages(gpa: Allocator, eb: *ErrorBundle, file: *Module.File) !void { | 2877 | pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Module.File) !void { |
| 2880 | assert(file.zir_loaded); | 2878 | assert(file.zir_loaded); |
| 2881 | assert(file.tree_loaded); | 2879 | assert(file.tree_loaded); |
| 2882 | assert(file.source_loaded); | 2880 | assert(file.source_loaded); |
| 2883 | const payload_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.compile_errors)]; | 2881 | const payload_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.compile_errors)]; |
| 2884 | assert(payload_index != 0); | 2882 | assert(payload_index != 0); |
| 2883 | const gpa = eb.gpa; | ||
| 2885 | 2884 | ||
| 2886 | const header = file.zir.extraData(Zir.Inst.CompileErrors, payload_index); | 2885 | const header = file.zir.extraData(Zir.Inst.CompileErrors, payload_index); |
| 2887 | const items_len = header.data.items_len; | 2886 | const items_len = header.data.items_len; |
| ... | @@ -2900,14 +2899,30 @@ pub fn addZirErrorMessages(gpa: Allocator, eb: *ErrorBundle, file: *Module.File) | ... | @@ -2900,14 +2899,30 @@ pub fn addZirErrorMessages(gpa: Allocator, eb: *ErrorBundle, file: *Module.File) |
| 2900 | }; | 2899 | }; |
| 2901 | const err_loc = std.zig.findLineColumn(file.source, err_span.main); | 2900 | const err_loc = std.zig.findLineColumn(file.source, err_span.main); |
| 2902 | 2901 | ||
| 2903 | var notes: []ErrorBundle.ErrorMessage = &.{}; | 2902 | { |
| 2904 | defer gpa.free(notes); | 2903 | const msg = file.zir.nullTerminatedString(item.data.msg); |
| 2904 | const src_path = try file.fullPath(gpa); | ||
| 2905 | defer gpa.free(src_path); | ||
| 2906 | try eb.addRootErrorMessage(.{ | ||
| 2907 | .msg = try eb.addString(msg), | ||
| 2908 | .src_loc = try eb.addSourceLocation(.{ | ||
| 2909 | .src_path = try eb.addString(src_path), | ||
| 2910 | .span_start = err_span.start, | ||
| 2911 | .span_main = err_span.main, | ||
| 2912 | .span_end = err_span.end, | ||
| 2913 | .line = @intCast(u32, err_loc.line), | ||
| 2914 | .column = @intCast(u32, err_loc.column), | ||
| 2915 | .source_line = try eb.addString(err_loc.source_line), | ||
| 2916 | }), | ||
| 2917 | .notes_len = item.data.notes, | ||
| 2918 | }); | ||
| 2919 | } | ||
| 2905 | 2920 | ||
| 2906 | if (item.data.notes != 0) { | 2921 | if (item.data.notes != 0) { |
| 2922 | const notes_start = try eb.reserveNotes(item.data.notes); | ||
| 2907 | const block = file.zir.extraData(Zir.Inst.Block, item.data.notes); | 2923 | const block = file.zir.extraData(Zir.Inst.Block, item.data.notes); |
| 2908 | const body = file.zir.extra[block.end..][0..block.data.body_len]; | 2924 | const body = file.zir.extra[block.end..][0..block.data.body_len]; |
| 2909 | notes = try gpa.alloc(ErrorBundle.ErrorMessage, body.len); | 2925 | for (notes_start.., body) |note_i, body_elem| { |
| 2910 | for (notes, body) |*note, body_elem| { | ||
| 2911 | const note_item = file.zir.extraData(Zir.Inst.CompileErrors.Item, body_elem); | 2926 | const note_item = file.zir.extraData(Zir.Inst.CompileErrors.Item, body_elem); |
| 2912 | const msg = file.zir.nullTerminatedString(note_item.data.msg); | 2927 | const msg = file.zir.nullTerminatedString(note_item.data.msg); |
| 2913 | const span = blk: { | 2928 | const span = blk: { |
| ... | @@ -2923,10 +2938,10 @@ pub fn addZirErrorMessages(gpa: Allocator, eb: *ErrorBundle, file: *Module.File) | ... | @@ -2923,10 +2938,10 @@ pub fn addZirErrorMessages(gpa: Allocator, eb: *ErrorBundle, file: *Module.File) |
| 2923 | const src_path = try file.fullPath(gpa); | 2938 | const src_path = try file.fullPath(gpa); |
| 2924 | defer gpa.free(src_path); | 2939 | defer gpa.free(src_path); |
| 2925 | 2940 | ||
| 2926 | note.* = .{ | 2941 | eb.extra.items[note_i] = @enumToInt(try eb.addErrorMessage(.{ |
| 2927 | .msg = try eb.addString(gpa, msg), | 2942 | .msg = try eb.addString(msg), |
| 2928 | .src_loc = try eb.addSourceLocation(gpa, .{ | 2943 | .src_loc = try eb.addSourceLocation(.{ |
| 2929 | .src_path = try eb.addString(gpa, src_path), | 2944 | .src_path = try eb.addString(src_path), |
| 2930 | .span_start = span.start, | 2945 | .span_start = span.start, |
| 2931 | .span_main = span.main, | 2946 | .span_main = span.main, |
| 2932 | .span_end = span.end, | 2947 | .span_end = span.end, |
| ... | @@ -2935,35 +2950,13 @@ pub fn addZirErrorMessages(gpa: Allocator, eb: *ErrorBundle, file: *Module.File) | ... | @@ -2935,35 +2950,13 @@ pub fn addZirErrorMessages(gpa: Allocator, eb: *ErrorBundle, file: *Module.File) |
| 2935 | .source_line = if (loc.eql(err_loc)) | 2950 | .source_line = if (loc.eql(err_loc)) |
| 2936 | 0 | 2951 | 0 |
| 2937 | else | 2952 | else |
| 2938 | try eb.addString(gpa, loc.source_line), | 2953 | try eb.addString(loc.source_line), |
| 2939 | }), | 2954 | }), |
| 2940 | .notes_len = 0, // TODO rework this function to be recursive | 2955 | .notes_len = 0, // TODO rework this function to be recursive |
| 2941 | }; | 2956 | })); |
| 2942 | } | 2957 | } |
| 2943 | } | 2958 | } |
| 2944 | |||
| 2945 | const msg = file.zir.nullTerminatedString(item.data.msg); | ||
| 2946 | const src_path = try file.fullPath(gpa); | ||
| 2947 | defer gpa.free(src_path); | ||
| 2948 | try eb.addErrorMessage(gpa, .{ | ||
| 2949 | .msg = try eb.addString(gpa, msg), | ||
| 2950 | .src_loc = try eb.addSourceLocation(gpa, .{ | ||
| 2951 | .src_path = try eb.addString(gpa, src_path), | ||
| 2952 | .span_start = err_span.start, | ||
| 2953 | .span_main = err_span.main, | ||
| 2954 | .span_end = err_span.end, | ||
| 2955 | .line = @intCast(u32, err_loc.line), | ||
| 2956 | .column = @intCast(u32, err_loc.column), | ||
| 2957 | .source_line = try eb.addString(gpa, err_loc.source_line), | ||
| 2958 | }), | ||
| 2959 | .notes_len = @intCast(u32, notes.len), | ||
| 2960 | }); | ||
| 2961 | |||
| 2962 | for (notes) |note| { | ||
| 2963 | try eb.addErrorMessage(gpa, note); | ||
| 2964 | } | ||
| 2965 | } | 2959 | } |
| 2966 | eb.incrementCount(items_len); | ||
| 2967 | } | 2960 | } |
| 2968 | 2961 | ||
| 2969 | pub fn getCompileLogOutput(self: *Compilation) []const u8 { | 2962 | pub fn getCompileLogOutput(self: *Compilation) []const u8 { |
src/Package.zig+17-19| ... | @@ -225,7 +225,7 @@ pub fn fetchAndAddDependencies( | ... | @@ -225,7 +225,7 @@ pub fn fetchAndAddDependencies( |
| 225 | dependencies_source: *std.ArrayList(u8), | 225 | dependencies_source: *std.ArrayList(u8), |
| 226 | build_roots_source: *std.ArrayList(u8), | 226 | build_roots_source: *std.ArrayList(u8), |
| 227 | name_prefix: []const u8, | 227 | name_prefix: []const u8, |
| 228 | error_bundle: *std.zig.ErrorBundle, | 228 | error_bundle: *std.zig.ErrorBundle.Wip, |
| 229 | all_modules: *AllModules, | 229 | all_modules: *AllModules, |
| 230 | ) !void { | 230 | ) !void { |
| 231 | const max_bytes = 10 * 1024 * 1024; | 231 | const max_bytes = 10 * 1024 * 1024; |
| ... | @@ -260,13 +260,12 @@ pub fn fetchAndAddDependencies( | ... | @@ -260,13 +260,12 @@ pub fn fetchAndAddDependencies( |
| 260 | if (manifest.errors.len > 0) { | 260 | if (manifest.errors.len > 0) { |
| 261 | const file_path = try directory.join(arena, &.{Manifest.basename}); | 261 | const file_path = try directory.join(arena, &.{Manifest.basename}); |
| 262 | for (manifest.errors) |msg| { | 262 | for (manifest.errors) |msg| { |
| 263 | try Report.addErrorMessage(gpa, ast, file_path, error_bundle, 0, msg); | 263 | try Report.addErrorMessage(ast, file_path, error_bundle, 0, msg); |
| 264 | } | 264 | } |
| 265 | return error.PackageFetchFailed; | 265 | return error.PackageFetchFailed; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | const report: Report = .{ | 268 | const report: Report = .{ |
| 269 | .gpa = gpa, | ||
| 270 | .ast = &ast, | 269 | .ast = &ast, |
| 271 | .directory = directory, | 270 | .directory = directory, |
| 272 | .error_bundle = error_bundle, | 271 | .error_bundle = error_bundle, |
| ... | @@ -343,10 +342,9 @@ pub fn createFilePkg( | ... | @@ -343,10 +342,9 @@ pub fn createFilePkg( |
| 343 | } | 342 | } |
| 344 | 343 | ||
| 345 | const Report = struct { | 344 | const Report = struct { |
| 346 | gpa: Allocator, | ||
| 347 | ast: *const std.zig.Ast, | 345 | ast: *const std.zig.Ast, |
| 348 | directory: Compilation.Directory, | 346 | directory: Compilation.Directory, |
| 349 | error_bundle: *std.zig.ErrorBundle, | 347 | error_bundle: *std.zig.ErrorBundle.Wip, |
| 350 | 348 | ||
| 351 | fn fail( | 349 | fn fail( |
| 352 | report: Report, | 350 | report: Report, |
| ... | @@ -354,7 +352,7 @@ const Report = struct { | ... | @@ -354,7 +352,7 @@ const Report = struct { |
| 354 | comptime fmt_string: []const u8, | 352 | comptime fmt_string: []const u8, |
| 355 | fmt_args: anytype, | 353 | fmt_args: anytype, |
| 356 | ) error{ PackageFetchFailed, OutOfMemory } { | 354 | ) error{ PackageFetchFailed, OutOfMemory } { |
| 357 | const gpa = report.gpa; | 355 | const gpa = report.error_bundle.gpa; |
| 358 | 356 | ||
| 359 | const file_path = try report.directory.join(gpa, &.{Manifest.basename}); | 357 | const file_path = try report.directory.join(gpa, &.{Manifest.basename}); |
| 360 | defer gpa.free(file_path); | 358 | defer gpa.free(file_path); |
| ... | @@ -362,7 +360,7 @@ const Report = struct { | ... | @@ -362,7 +360,7 @@ const Report = struct { |
| 362 | const msg = try std.fmt.allocPrint(gpa, fmt_string, fmt_args); | 360 | const msg = try std.fmt.allocPrint(gpa, fmt_string, fmt_args); |
| 363 | defer gpa.free(msg); | 361 | defer gpa.free(msg); |
| 364 | 362 | ||
| 365 | try addErrorMessage(report.gpa, report.ast.*, file_path, report.error_bundle, 0, .{ | 363 | try addErrorMessage(report.ast.*, file_path, report.error_bundle, 0, .{ |
| 366 | .tok = tok, | 364 | .tok = tok, |
| 367 | .off = 0, | 365 | .off = 0, |
| 368 | .msg = msg, | 366 | .msg = msg, |
| ... | @@ -372,30 +370,28 @@ const Report = struct { | ... | @@ -372,30 +370,28 @@ const Report = struct { |
| 372 | } | 370 | } |
| 373 | 371 | ||
| 374 | fn addErrorMessage( | 372 | fn addErrorMessage( |
| 375 | gpa: Allocator, | ||
| 376 | ast: std.zig.Ast, | 373 | ast: std.zig.Ast, |
| 377 | file_path: []const u8, | 374 | file_path: []const u8, |
| 378 | eb: *std.zig.ErrorBundle, | 375 | eb: *std.zig.ErrorBundle.Wip, |
| 379 | notes_len: u32, | 376 | notes_len: u32, |
| 380 | msg: Manifest.ErrorMessage, | 377 | msg: Manifest.ErrorMessage, |
| 381 | ) error{OutOfMemory}!void { | 378 | ) error{OutOfMemory}!void { |
| 382 | const token_starts = ast.tokens.items(.start); | 379 | const token_starts = ast.tokens.items(.start); |
| 383 | const start_loc = ast.tokenLocation(0, msg.tok); | 380 | const start_loc = ast.tokenLocation(0, msg.tok); |
| 384 | 381 | ||
| 385 | try eb.addErrorMessage(gpa, .{ | 382 | try eb.addRootErrorMessage(.{ |
| 386 | .msg = try eb.addString(gpa, msg.msg), | 383 | .msg = try eb.addString(msg.msg), |
| 387 | .src_loc = try eb.addSourceLocation(gpa, .{ | 384 | .src_loc = try eb.addSourceLocation(.{ |
| 388 | .src_path = try eb.addString(gpa, file_path), | 385 | .src_path = try eb.addString(file_path), |
| 389 | .span_start = token_starts[msg.tok], | 386 | .span_start = token_starts[msg.tok], |
| 390 | .span_end = @intCast(u32, token_starts[msg.tok] + ast.tokenSlice(msg.tok).len), | 387 | .span_end = @intCast(u32, token_starts[msg.tok] + ast.tokenSlice(msg.tok).len), |
| 391 | .span_main = token_starts[msg.tok] + msg.off, | 388 | .span_main = token_starts[msg.tok] + msg.off, |
| 392 | .line = @intCast(u32, start_loc.line), | 389 | .line = @intCast(u32, start_loc.line), |
| 393 | .column = @intCast(u32, start_loc.column), | 390 | .column = @intCast(u32, start_loc.column), |
| 394 | .source_line = try eb.addString(gpa, ast.source[start_loc.line_start..start_loc.line_end]), | 391 | .source_line = try eb.addString(ast.source[start_loc.line_start..start_loc.line_end]), |
| 395 | }), | 392 | }), |
| 396 | .notes_len = notes_len, | 393 | .notes_len = notes_len, |
| 397 | }); | 394 | }); |
| 398 | eb.incrementCount(1); | ||
| 399 | } | 395 | } |
| 400 | }; | 396 | }; |
| 401 | 397 | ||
| ... | @@ -526,14 +522,16 @@ fn fetchAndUnpack( | ... | @@ -526,14 +522,16 @@ fn fetchAndUnpack( |
| 526 | defer gpa.free(file_path); | 522 | defer gpa.free(file_path); |
| 527 | 523 | ||
| 528 | const eb = report.error_bundle; | 524 | const eb = report.error_bundle; |
| 529 | try Report.addErrorMessage(gpa, report.ast.*, file_path, eb, 1, .{ | 525 | const notes_len = 1; |
| 526 | try Report.addErrorMessage(report.ast.*, file_path, eb, notes_len, .{ | ||
| 530 | .tok = dep.url_tok, | 527 | .tok = dep.url_tok, |
| 531 | .off = 0, | 528 | .off = 0, |
| 532 | .msg = "url field is missing corresponding hash field", | 529 | .msg = "url field is missing corresponding hash field", |
| 533 | }); | 530 | }); |
| 534 | try eb.addErrorMessage(gpa, .{ | 531 | const notes_start = try eb.reserveNotes(notes_len); |
| 535 | .msg = try eb.printString(gpa, "expected .hash = \"{s}\",", .{&actual_hex}), | 532 | eb.extra.items[notes_start] = @enumToInt(try eb.addErrorMessage(.{ |
| 536 | }); | 533 | .msg = try eb.printString("expected .hash = \"{s}\",", .{&actual_hex}), |
| 534 | })); | ||
| 537 | return error.PackageFetchFailed; | 535 | return error.PackageFetchFailed; |
| 538 | } | 536 | } |
| 539 | 537 |
src/Sema.zig+5-4| ... | @@ -2215,11 +2215,12 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError { | ... | @@ -2215,11 +2215,12 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError { |
| 2215 | 2215 | ||
| 2216 | if (crash_report.is_enabled and sema.mod.comp.debug_compile_errors) { | 2216 | if (crash_report.is_enabled and sema.mod.comp.debug_compile_errors) { |
| 2217 | if (err_msg.src_loc.lazy == .unneeded) return error.NeededSourceLocation; | 2217 | if (err_msg.src_loc.lazy == .unneeded) return error.NeededSourceLocation; |
| 2218 | var errors: std.zig.ErrorBundle = undefined; | 2218 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 2219 | errors.init(gpa) catch unreachable; | 2219 | wip_errors.init(gpa) catch unreachable; |
| 2220 | Compilation.addModuleErrorMsg(gpa, &errors, err_msg.*) catch unreachable; | 2220 | Compilation.addModuleErrorMsg(&wip_errors, err_msg.*) catch unreachable; |
| 2221 | std.debug.print("compile error during Sema:\n", .{}); | 2221 | std.debug.print("compile error during Sema:\n", .{}); |
| 2222 | errors.renderToStdErr(.no_color); | 2222 | var error_bundle = wip_errors.toOwnedBundle() catch unreachable; |
| 2223 | error_bundle.renderToStdErr(.no_color); | ||
| 2223 | crash_report.compilerPanic("unexpected compile error occurred", null, null); | 2224 | crash_report.compilerPanic("unexpected compile error occurred", null, null); |
| 2224 | } | 2225 | } |
| 2225 | 2226 |
src/main.zig+50-36| ... | @@ -4436,9 +4436,9 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -4436,9 +4436,9 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 4436 | var all_modules: Package.AllModules = .{}; | 4436 | var all_modules: Package.AllModules = .{}; |
| 4437 | defer all_modules.deinit(gpa); | 4437 | defer all_modules.deinit(gpa); |
| 4438 | 4438 | ||
| 4439 | var errors: std.zig.ErrorBundle = undefined; | 4439 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 4440 | try errors.init(gpa); | 4440 | try wip_errors.init(gpa); |
| 4441 | defer errors.deinit(gpa); | 4441 | defer wip_errors.deinit(); |
| 4442 | 4442 | ||
| 4443 | // Here we borrow main package's table and will replace it with a fresh | 4443 | // Here we borrow main package's table and will replace it with a fresh |
| 4444 | // one after this process completes. | 4444 | // one after this process completes. |
| ... | @@ -4453,15 +4453,17 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -4453,15 +4453,17 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 4453 | &dependencies_source, | 4453 | &dependencies_source, |
| 4454 | &build_roots_source, | 4454 | &build_roots_source, |
| 4455 | "", | 4455 | "", |
| 4456 | &errors, | 4456 | &wip_errors, |
| 4457 | &all_modules, | 4457 | &all_modules, |
| 4458 | ); | 4458 | ); |
| 4459 | if (errors.errorMessageCount() > 0) { | 4459 | if (wip_errors.root_list.items.len > 0) { |
| 4460 | const ttyconf: std.debug.TTY.Config = switch (color) { | 4460 | const ttyconf: std.debug.TTY.Config = switch (color) { |
| 4461 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), | 4461 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), |
| 4462 | .on => .escape_codes, | 4462 | .on => .escape_codes, |
| 4463 | .off => .no_color, | 4463 | .off => .no_color, |
| 4464 | }; | 4464 | }; |
| 4465 | var errors = try wip_errors.toOwnedBundle(); | ||
| 4466 | defer errors.deinit(gpa); | ||
| 4465 | errors.renderToStdErr(ttyconf); | 4467 | errors.renderToStdErr(ttyconf); |
| 4466 | process.exit(1); | 4468 | process.exit(1); |
| 4467 | } | 4469 | } |
| ... | @@ -4721,16 +4723,18 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void | ... | @@ -4721,16 +4723,18 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void |
| 4721 | defer file.zir.deinit(gpa); | 4723 | defer file.zir.deinit(gpa); |
| 4722 | 4724 | ||
| 4723 | if (file.zir.hasCompileErrors()) { | 4725 | if (file.zir.hasCompileErrors()) { |
| 4724 | var errors: std.zig.ErrorBundle = undefined; | 4726 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 4725 | try errors.init(gpa); | 4727 | try wip_errors.init(gpa); |
| 4726 | defer errors.deinit(gpa); | 4728 | defer wip_errors.deinit(); |
| 4727 | try Compilation.addZirErrorMessages(gpa, &errors, &file); | 4729 | try Compilation.addZirErrorMessages(&wip_errors, &file); |
| 4728 | const ttyconf: std.debug.TTY.Config = switch (color) { | 4730 | const ttyconf: std.debug.TTY.Config = switch (color) { |
| 4729 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), | 4731 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), |
| 4730 | .on => .escape_codes, | 4732 | .on => .escape_codes, |
| 4731 | .off => .no_color, | 4733 | .off => .no_color, |
| 4732 | }; | 4734 | }; |
| 4733 | errors.renderToStdErr(ttyconf); | 4735 | var error_bundle = try wip_errors.toOwnedBundle(); |
| 4736 | defer error_bundle.deinit(gpa); | ||
| 4737 | error_bundle.renderToStdErr(ttyconf); | ||
| 4734 | has_ast_error = true; | 4738 | has_ast_error = true; |
| 4735 | } | 4739 | } |
| 4736 | } | 4740 | } |
| ... | @@ -4930,16 +4934,18 @@ fn fmtPathFile( | ... | @@ -4930,16 +4934,18 @@ fn fmtPathFile( |
| 4930 | defer file.zir.deinit(gpa); | 4934 | defer file.zir.deinit(gpa); |
| 4931 | 4935 | ||
| 4932 | if (file.zir.hasCompileErrors()) { | 4936 | if (file.zir.hasCompileErrors()) { |
| 4933 | var errors: std.zig.ErrorBundle = undefined; | 4937 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 4934 | try errors.init(gpa); | 4938 | try wip_errors.init(gpa); |
| 4935 | defer errors.deinit(gpa); | 4939 | defer wip_errors.deinit(); |
| 4936 | try Compilation.addZirErrorMessages(gpa, &errors, &file); | 4940 | try Compilation.addZirErrorMessages(&wip_errors, &file); |
| 4937 | const ttyconf: std.debug.TTY.Config = switch (fmt.color) { | 4941 | const ttyconf: std.debug.TTY.Config = switch (fmt.color) { |
| 4938 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), | 4942 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), |
| 4939 | .on => .escape_codes, | 4943 | .on => .escape_codes, |
| 4940 | .off => .no_color, | 4944 | .off => .no_color, |
| 4941 | }; | 4945 | }; |
| 4942 | errors.renderToStdErr(ttyconf); | 4946 | var error_bundle = try wip_errors.toOwnedBundle(); |
| 4947 | defer error_bundle.deinit(gpa); | ||
| 4948 | error_bundle.renderToStdErr(ttyconf); | ||
| 4943 | fmt.any_error = true; | 4949 | fmt.any_error = true; |
| 4944 | } | 4950 | } |
| 4945 | } | 4951 | } |
| ... | @@ -4968,17 +4974,19 @@ fn fmtPathFile( | ... | @@ -4968,17 +4974,19 @@ fn fmtPathFile( |
| 4968 | } | 4974 | } |
| 4969 | 4975 | ||
| 4970 | fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color: Color) !void { | 4976 | fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color: Color) !void { |
| 4971 | var error_bundle: std.zig.ErrorBundle = undefined; | 4977 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 4972 | try error_bundle.init(gpa); | 4978 | try wip_errors.init(gpa); |
| 4973 | defer error_bundle.deinit(gpa); | 4979 | defer wip_errors.deinit(); |
| 4974 | 4980 | ||
| 4975 | try putAstErrorsIntoBundle(gpa, tree, path, &error_bundle); | 4981 | try putAstErrorsIntoBundle(gpa, tree, path, &wip_errors); |
| 4976 | 4982 | ||
| 4977 | const ttyconf: std.debug.TTY.Config = switch (color) { | 4983 | const ttyconf: std.debug.TTY.Config = switch (color) { |
| 4978 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), | 4984 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), |
| 4979 | .on => .escape_codes, | 4985 | .on => .escape_codes, |
| 4980 | .off => .no_color, | 4986 | .off => .no_color, |
| 4981 | }; | 4987 | }; |
| 4988 | var error_bundle = try wip_errors.toOwnedBundle(); | ||
| 4989 | defer error_bundle.deinit(gpa); | ||
| 4982 | error_bundle.renderToStdErr(ttyconf); | 4990 | error_bundle.renderToStdErr(ttyconf); |
| 4983 | } | 4991 | } |
| 4984 | 4992 | ||
| ... | @@ -4986,7 +4994,7 @@ pub fn putAstErrorsIntoBundle( | ... | @@ -4986,7 +4994,7 @@ pub fn putAstErrorsIntoBundle( |
| 4986 | gpa: Allocator, | 4994 | gpa: Allocator, |
| 4987 | tree: Ast, | 4995 | tree: Ast, |
| 4988 | path: []const u8, | 4996 | path: []const u8, |
| 4989 | error_bundle: *std.zig.ErrorBundle, | 4997 | wip_errors: *std.zig.ErrorBundle.Wip, |
| 4990 | ) !void { | 4998 | ) !void { |
| 4991 | var file: Module.File = .{ | 4999 | var file: Module.File = .{ |
| 4992 | .status = .never_loaded, | 5000 | .status = .never_loaded, |
| ... | @@ -5013,7 +5021,7 @@ pub fn putAstErrorsIntoBundle( | ... | @@ -5013,7 +5021,7 @@ pub fn putAstErrorsIntoBundle( |
| 5013 | file.zir_loaded = true; | 5021 | file.zir_loaded = true; |
| 5014 | defer file.zir.deinit(gpa); | 5022 | defer file.zir.deinit(gpa); |
| 5015 | 5023 | ||
| 5016 | try Compilation.addZirErrorMessages(gpa, error_bundle, &file); | 5024 | try Compilation.addZirErrorMessages(wip_errors, &file); |
| 5017 | } | 5025 | } |
| 5018 | 5026 | ||
| 5019 | pub const info_zen = | 5027 | pub const info_zen = |
| ... | @@ -5595,16 +5603,18 @@ pub fn cmdAstCheck( | ... | @@ -5595,16 +5603,18 @@ pub fn cmdAstCheck( |
| 5595 | defer file.zir.deinit(gpa); | 5603 | defer file.zir.deinit(gpa); |
| 5596 | 5604 | ||
| 5597 | if (file.zir.hasCompileErrors()) { | 5605 | if (file.zir.hasCompileErrors()) { |
| 5598 | var errors: std.zig.ErrorBundle = undefined; | 5606 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 5599 | try errors.init(gpa); | 5607 | try wip_errors.init(gpa); |
| 5600 | defer errors.deinit(gpa); | 5608 | defer wip_errors.deinit(); |
| 5601 | try Compilation.addZirErrorMessages(gpa, &errors, &file); | 5609 | try Compilation.addZirErrorMessages(&wip_errors, &file); |
| 5602 | const ttyconf: std.debug.TTY.Config = switch (color) { | 5610 | const ttyconf: std.debug.TTY.Config = switch (color) { |
| 5603 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), | 5611 | .auto => std.debug.detectTTYConfig(std.io.getStdErr()), |
| 5604 | .on => .escape_codes, | 5612 | .on => .escape_codes, |
| 5605 | .off => .no_color, | 5613 | .off => .no_color, |
| 5606 | }; | 5614 | }; |
| 5607 | errors.renderToStdErr(ttyconf); | 5615 | var error_bundle = try wip_errors.toOwnedBundle(); |
| 5616 | defer error_bundle.deinit(gpa); | ||
| 5617 | error_bundle.renderToStdErr(ttyconf); | ||
| 5608 | process.exit(1); | 5618 | process.exit(1); |
| 5609 | } | 5619 | } |
| 5610 | 5620 | ||
| ... | @@ -5719,12 +5729,14 @@ pub fn cmdChangelist( | ... | @@ -5719,12 +5729,14 @@ pub fn cmdChangelist( |
| 5719 | defer file.zir.deinit(gpa); | 5729 | defer file.zir.deinit(gpa); |
| 5720 | 5730 | ||
| 5721 | if (file.zir.hasCompileErrors()) { | 5731 | if (file.zir.hasCompileErrors()) { |
| 5722 | var errors: std.zig.ErrorBundle = undefined; | 5732 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 5723 | try errors.init(gpa); | 5733 | try wip_errors.init(gpa); |
| 5724 | defer errors.deinit(gpa); | 5734 | defer wip_errors.deinit(); |
| 5725 | try Compilation.addZirErrorMessages(gpa, &errors, &file); | 5735 | try Compilation.addZirErrorMessages(&wip_errors, &file); |
| 5726 | const ttyconf = std.debug.detectTTYConfig(std.io.getStdErr()); | 5736 | const ttyconf = std.debug.detectTTYConfig(std.io.getStdErr()); |
| 5727 | errors.renderToStdErr(ttyconf); | 5737 | var error_bundle = try wip_errors.toOwnedBundle(); |
| 5738 | defer error_bundle.deinit(gpa); | ||
| 5739 | error_bundle.renderToStdErr(ttyconf); | ||
| 5728 | process.exit(1); | 5740 | process.exit(1); |
| 5729 | } | 5741 | } |
| 5730 | 5742 | ||
| ... | @@ -5758,12 +5770,14 @@ pub fn cmdChangelist( | ... | @@ -5758,12 +5770,14 @@ pub fn cmdChangelist( |
| 5758 | file.zir_loaded = true; | 5770 | file.zir_loaded = true; |
| 5759 | 5771 | ||
| 5760 | if (file.zir.hasCompileErrors()) { | 5772 | if (file.zir.hasCompileErrors()) { |
| 5761 | var errors: std.zig.ErrorBundle = undefined; | 5773 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 5762 | try errors.init(gpa); | 5774 | try wip_errors.init(gpa); |
| 5763 | defer errors.deinit(gpa); | 5775 | defer wip_errors.deinit(); |
| 5764 | try Compilation.addZirErrorMessages(gpa, &errors, &file); | 5776 | try Compilation.addZirErrorMessages(&wip_errors, &file); |
| 5765 | const ttyconf = std.debug.detectTTYConfig(std.io.getStdErr()); | 5777 | const ttyconf = std.debug.detectTTYConfig(std.io.getStdErr()); |
| 5766 | errors.renderToStdErr(ttyconf); | 5778 | var error_bundle = try wip_errors.toOwnedBundle(); |
| 5779 | defer error_bundle.deinit(gpa); | ||
| 5780 | error_bundle.renderToStdErr(ttyconf); | ||
| 5767 | process.exit(1); | 5781 | process.exit(1); |
| 5768 | } | 5782 | } |
| 5769 | 5783 |
src/test.zig+3-18| ... | @@ -1242,7 +1242,7 @@ pub const TestContext = struct { | ... | @@ -1242,7 +1242,7 @@ pub const TestContext = struct { |
| 1242 | defer self.gpa.free(zig_lib_directory.path.?); | 1242 | defer self.gpa.free(zig_lib_directory.path.?); |
| 1243 | 1243 | ||
| 1244 | var aux_thread_pool: ThreadPool = undefined; | 1244 | var aux_thread_pool: ThreadPool = undefined; |
| 1245 | try aux_thread_pool.init(self.gpa); | 1245 | try aux_thread_pool.init(.{ .allocator = self.gpa }); |
| 1246 | defer aux_thread_pool.deinit(); | 1246 | defer aux_thread_pool.deinit(); |
| 1247 | 1247 | ||
| 1248 | // Use the same global cache dir for all the tests, such that we for example don't have to | 1248 | // Use the same global cache dir for all the tests, such that we for example don't have to |
| ... | @@ -1614,23 +1614,8 @@ pub const TestContext = struct { | ... | @@ -1614,23 +1614,8 @@ pub const TestContext = struct { |
| 1614 | if (update.case != .Error) { | 1614 | if (update.case != .Error) { |
| 1615 | var all_errors = try comp.getAllErrorsAlloc(); | 1615 | var all_errors = try comp.getAllErrorsAlloc(); |
| 1616 | defer all_errors.deinit(allocator); | 1616 | defer all_errors.deinit(allocator); |
| 1617 | if (all_errors.list.len != 0) { | 1617 | if (all_errors.errorMessageCount() > 0) { |
| 1618 | print( | 1618 | all_errors.renderToStdErr(std.debug.detectTTYConfig(std.io.getStdErr())); |
| 1619 | "\nCase '{s}': unexpected errors at update_index={d}:\n{s}\n", | ||
| 1620 | .{ case.name, update_index, hr }, | ||
| 1621 | ); | ||
| 1622 | for (all_errors.list) |err_msg| { | ||
| 1623 | switch (err_msg) { | ||
| 1624 | .src => |src| { | ||
| 1625 | print("{s}:{d}:{d}: error: {s}\n{s}\n", .{ | ||
| 1626 | src.src_path, src.line + 1, src.column + 1, src.msg, hr, | ||
| 1627 | }); | ||
| 1628 | }, | ||
| 1629 | .plain => |plain| { | ||
| 1630 | print("error: {s}\n{s}\n", .{ plain.msg, hr }); | ||
| 1631 | }, | ||
| 1632 | } | ||
| 1633 | } | ||
| 1634 | // TODO print generated C code | 1619 | // TODO print generated C code |
| 1635 | return error.UnexpectedCompileErrors; | 1620 | return error.UnexpectedCompileErrors; |
| 1636 | } | 1621 | } |