From 2e939b617e8e20652e25067b041595441ff6b380 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 26 Nov 2024 15:10:29 -0800 Subject: [PATCH] config: clone should copy diagnostics Fixes #2800 --- src/cli/diagnostics.zig | 55 +++++++++++++++++++++++++++++++++++++++++ src/config/Config.zig | 3 +++ 2 files changed, 58 insertions(+) diff --git a/src/cli/diagnostics.zig b/src/cli/diagnostics.zig index e4d390c03..8090684fd 100644 --- a/src/cli/diagnostics.zig +++ b/src/cli/diagnostics.zig @@ -34,6 +34,14 @@ pub const Diagnostic = struct { try writer.print("{s}", .{self.message}); } + + pub fn clone(self: *const Diagnostic, alloc: Allocator) Allocator.Error!Diagnostic { + return .{ + .location = try self.location.clone(alloc), + .key = try alloc.dupeZ(u8, self.key), + .message = try alloc.dupeZ(u8, self.message), + }; + } }; /// The possible locations for a diagnostic message. This is used @@ -61,6 +69,19 @@ pub const Location = union(enum) { if (!@hasDecl(Iter, "location")) return .none; return iter.location() orelse .none; } + + pub fn clone(self: *const Location, alloc: Allocator) Allocator.Error!Location { + return switch (self.*) { + .none, + .cli, + => self.*, + + .file => |v| .{ .file = .{ + .path = try alloc.dupe(u8, v.path), + .line = v.line, + } }, + }; + } }; /// A list of diagnostics. The "_diagnostics" field must be this type @@ -88,11 +109,45 @@ pub const DiagnosticList = struct { // We specifically want precompute for libghostty. .lib => true, }; + const Precompute = if (precompute_enabled) struct { messages: std.ArrayListUnmanaged([:0]const u8) = .{}, + + pub fn clone( + self: *const Precompute, + alloc: Allocator, + ) Allocator.Error!Precompute { + var result: Precompute = .{}; + try result.messages.ensureTotalCapacity(alloc, self.messages.items.len); + for (self.messages.items) |msg| { + result.messages.appendAssumeCapacity( + try alloc.dupeZ(u8, msg), + ); + } + return result; + } } else void; + const precompute_init: Precompute = if (precompute_enabled) .{} else {}; + pub fn clone( + self: *const DiagnosticList, + alloc: Allocator, + ) Allocator.Error!DiagnosticList { + var result: DiagnosticList = .{}; + + try result.list.ensureTotalCapacity(alloc, self.list.items.len); + for (self.list.items) |*diag| result.list.appendAssumeCapacity( + try diag.clone(alloc), + ); + + if (comptime precompute_enabled) { + result.precompute = try self.precompute.clone(alloc); + } + + return result; + } + pub fn append( self: *DiagnosticList, alloc: Allocator, diff --git a/src/config/Config.zig b/src/config/Config.zig index bf29994c3..2dc732752 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -3063,6 +3063,9 @@ pub fn clone( ); } + // Copy our diagnostics + result._diagnostics = try self._diagnostics.clone(alloc_arena); + // Preserve our replay steps. We copy them exactly to also preserve // the exact conditionals required for some steps. try result._replay_steps.ensureTotalCapacity(