| ... | @@ -2,11 +2,21 @@ | ... | @@ -2,11 +2,21 @@ |
| 2 | //! so that they can be created and destroyed appropriately. This structure | 2 | //! so that they can be created and destroyed appropriately. This structure |
| 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 | //! |
| | 6 | //! There is one special encoding for this data structure. If both arrays are |
| | 7 | //! empty, it means there are no errors. This special encoding exists so that |
| | 8 | //! heap allocation is not needed in the common case of no errors. |
| 5 | | 9 | |
| 6 | string_bytes: []const u8, | 10 | string_bytes: []const u8, |
| 7 | /// The first thing in this array is an `ErrorMessageList`. | 11 | /// The first thing in this array is an `ErrorMessageList`. |
| 8 | extra: []const u32, | 12 | extra: []const u32, |
| 9 | | 13 | |
| | 14 | /// Special encoding when there are no errors. |
| | 15 | pub const empty: ErrorBundle = .{ |
| | 16 | .string_bytes = &.{}, |
| | 17 | .extra = &.{}, |
| | 18 | }; |
| | 19 | |
| 10 | // An index into `extra` pointing at an `ErrorMessage`. | 20 | // An index into `extra` pointing at an `ErrorMessage`. |
| 11 | pub const MessageIndex = enum(u32) { | 21 | pub const MessageIndex = enum(u32) { |
| 12 | _, | 22 | _, |
| ... | @@ -72,6 +82,7 @@ pub fn deinit(eb: *ErrorBundle, gpa: Allocator) void { | ... | @@ -72,6 +82,7 @@ pub fn deinit(eb: *ErrorBundle, gpa: Allocator) void { |
| 72 | } | 82 | } |
| 73 | | 83 | |
| 74 | pub fn errorMessageCount(eb: ErrorBundle) u32 { | 84 | pub fn errorMessageCount(eb: ErrorBundle) u32 { |
| | 85 | if (eb.extra.len == 0) return 0; |
| 75 | return eb.getErrorMessageList().len; | 86 | return eb.getErrorMessageList().len; |
| 76 | } | 87 | } |
| 77 | | 88 | |
| ... | @@ -313,6 +324,17 @@ pub const Wip = struct { | ... | @@ -313,6 +324,17 @@ pub const Wip = struct { |
| 313 | | 324 | |
| 314 | pub fn toOwnedBundle(wip: *Wip) !ErrorBundle { | 325 | pub fn toOwnedBundle(wip: *Wip) !ErrorBundle { |
| 315 | const gpa = wip.gpa; | 326 | const gpa = wip.gpa; |
| | 327 | if (wip.root_list.items.len == 0) { |
| | 328 | // Special encoding when there are no errors. |
| | 329 | wip.deinit(); |
| | 330 | wip.* = .{ |
| | 331 | .gpa = gpa, |
| | 332 | .string_bytes = .{}, |
| | 333 | .extra = .{}, |
| | 334 | .root_list = .{}, |
| | 335 | }; |
| | 336 | return empty; |
| | 337 | } |
| 316 | wip.setExtra(0, ErrorMessageList{ | 338 | wip.setExtra(0, ErrorMessageList{ |
| 317 | .len = @intCast(u32, wip.root_list.items.len), | 339 | .len = @intCast(u32, wip.root_list.items.len), |
| 318 | .start = @intCast(u32, wip.extra.items.len), | 340 | .start = @intCast(u32, wip.extra.items.len), |