| ... | ... | @@ -5,8 +5,8 @@ |
| 5 | 5 | //! |
| 6 | 6 | //! Across the compiler, `Report.Builder`s' `.err` and `.warn` methods |
| 7 | 7 | //! can add messages by ID. |
| 8 | | errors: []Item, |
| 9 | | warnings: []Item, |
| 8 | errors: []Item(Err), |
| 9 | warnings: []Item(Warn), |
| 10 | 10 | string_bytes: []u8, |
| 11 | 11 | |
| 12 | 12 | pub const empty: Report = .{ |
| ... | ... | @@ -18,23 +18,20 @@ pub const empty: Report = .{ |
| 18 | 18 | pub var debug_show_report_trace: if (builtin.mode == .Debug) bool else void = |
| 19 | 19 | if (builtin.mode == .Debug) false; |
| 20 | 20 | |
| 21 | | pub const Item = struct { |
| 22 | | /// What is this diagnostic |
| 23 | | data: union { @"error": Err, warn: Warn }, |
| 24 | | |
| 25 | | debug_stack_trace: DebugStoredTrace = .empty, |
| 26 | | |
| 27 | | /// Type is never stored, inferred from which list it is in. |
| 28 | | pub const Type = enum { @"error", warn }; |
| 29 | | }; |
| 21 | pub fn Item(T: type) type { |
| 22 | return struct { |
| 23 | data: T, |
| 24 | debug_stack_trace: DebugStoredTrace = .empty, |
| 25 | }; |
| 26 | } |
| 30 | 27 | |
| 31 | 28 | pub const Err = union(enum) { |
| 32 | 29 | pub const FieldEnum = core.FieldEnum(Err); |
| 33 | 30 | |
| 34 | 31 | /// Constructs a `Report` with just a single error. |
| 35 | 32 | pub fn toReport(err: Err, alloc: Allocator, trace: DebugStoredTrace) !Report { |
| 36 | | const errors = try alloc.dupe(Item, &.{.{ |
| 37 | | .data = .{ .@"error" = err }, |
| 33 | const errors = try alloc.dupe(Item(Err), &.{.{ |
| 34 | .data = err, |
| 38 | 35 | .debug_stack_trace = trace, |
| 39 | 36 | }}); |
| 40 | 37 | return .{ .errors = errors, .warnings = &.{}, .string_bytes = &.{} }; |
| ... | ... | @@ -641,7 +638,7 @@ pub fn dump(report: Report, ctx: DumpContext, out: core.OutStream) !void { |
| 641 | 638 | const ast: *const Ast = switch (ctx) { |
| 642 | 639 | .comp => |comp_ctx| |
| 643 | 640 | // Ast cannot be queried if the error is in computing the Ast |
| 644 | | if (report.errors.len > 0 and report.errors[0].data.@"error" == .ast) fake_ast: { |
| 641 | if (report.errors.len > 0 and report.errors[0].data == .ast) fake_ast: { |
| 645 | 642 | fake_ast_data = .{ |
| 646 | 643 | .utf8_source = (comp_ctx.file.getSource(comp_ctx.comp.gpa) catch { |
| 647 | 644 | @panic("TODO"); |
| ... | ... | @@ -695,18 +692,18 @@ pub fn dump(report: Report, ctx: DumpContext, out: core.OutStream) !void { |
| 695 | 692 | }; |
| 696 | 693 | |
| 697 | 694 | for (report.errors) |item| { |
| 698 | | try formatItem(item, .@"error", arena.allocator(), url, msg_ctx, out); |
| 695 | try formatItem(Err, item, arena.allocator(), url, msg_ctx, out); |
| 699 | 696 | _ = arena.reset(.retain_capacity); |
| 700 | 697 | } |
| 701 | 698 | for (report.warnings) |item| { |
| 702 | | try formatItem(item, .warn, arena.allocator(), url, msg_ctx, out); |
| 699 | try formatItem(Warn, item, arena.allocator(), url, msg_ctx, out); |
| 703 | 700 | _ = arena.reset(.retain_capacity); |
| 704 | 701 | } |
| 705 | 702 | } |
| 706 | 703 | |
| 707 | 704 | fn formatItem( |
| 708 | | item: Item, |
| 709 | | item_type: Item.Type, |
| 705 | comptime T: type, |
| 706 | item: Item(T), |
| 710 | 707 | arena: Allocator, |
| 711 | 708 | url: []const u8, |
| 712 | 709 | ctx_init: MsgContext, |
| ... | ... | @@ -720,10 +717,8 @@ fn formatItem( |
| 720 | 717 | ctx.components = ArrayListUnmanaged(Component).initCapacity(alloc, 16) catch |
| 721 | 718 | unreachable; // stack-fallback allocator has enough space. |
| 722 | 719 | |
| 723 | | switch (item_type) { |
| 724 | | inline else => |tag| switch (@field(item.data, @tagName(tag))) { |
| 725 | | inline else => |payload| try payload.build(&ctx), |
| 726 | | }, |
| 720 | switch (item.data) { |
| 721 | inline else => |payload| try payload.build(&ctx), |
| 727 | 722 | } |
| 728 | 723 | |
| 729 | 724 | assert(ctx.components.items.len > 0); |
| ... | ... | @@ -744,8 +739,10 @@ fn formatItem( |
| 744 | 739 | |
| 745 | 740 | for (ctx.components.items, 1..) |component, i| { |
| 746 | 741 | const prefix: Prefix = if (i == 1) |
| 747 | | switch (item_type) { |
| 748 | | inline else => |tag| @field(Prefix, @tagName(tag)), |
| 742 | switch (T) { |
| 743 | Err => .@"error", |
| 744 | Warn => .warn, |
| 745 | else => @compileError(unreachable), |
| 749 | 746 | } |
| 750 | 747 | else |
| 751 | 748 | .note; |
| ... | ... | @@ -862,8 +859,8 @@ fn formatItem( |
| 862 | 859 | |
| 863 | 860 | pub const Builder = struct { |
| 864 | 861 | gpa: Allocator, |
| 865 | | errors: ArrayListUnmanaged(Item), |
| 866 | | warnings: ArrayListUnmanaged(Item), |
| 862 | errors: ArrayListUnmanaged(Item(Err)), |
| 863 | warnings: ArrayListUnmanaged(Item(Warn)), |
| 867 | 864 | string_bytes: ArrayListUnmanaged(u8), |
| 868 | 865 | |
| 869 | 866 | pub fn init(gpa: Allocator) Builder { |
| ... | ... | @@ -890,7 +887,7 @@ pub const Builder = struct { |
| 890 | 887 | return_address: usize, |
| 891 | 888 | ) !void { |
| 892 | 889 | try b.errors.append(b.gpa, .{ |
| 893 | | .data = .{ .@"error" = @unionInit(Err, @tagName(kind), data) }, |
| 890 | .data = @unionInit(Err, @tagName(kind), data), |
| 894 | 891 | .debug_stack_trace = DebugStoredTrace.capture(return_address), |
| 895 | 892 | }); |
| 896 | 893 | } |
| ... | ... | @@ -902,7 +899,7 @@ pub const Builder = struct { |
| 902 | 899 | return_address: usize, |
| 903 | 900 | ) !void { |
| 904 | 901 | try b.warnings.append(b.gpa, .{ |
| 905 | | .data = .{ .warn = @unionInit(Warn, @tagName(kind), data) }, |
| 902 | .data = @unionInit(Warn, @tagName(kind), data), |
| 906 | 903 | .debug_stack_trace = DebugStoredTrace.capture(return_address), |
| 907 | 904 | }); |
| 908 | 905 | } |