| author | |
| committer | |
| log | fc1e7a56441aea4a9394c4e8c0142110891b4a1a |
| tree | 8d7fc370a62874bcfe779df04a67fdd8fa17e0a4 |
| parent | 802c82b0720ff2b7c59ba96effbdd1eed7491df4 |
3 files changed, 112 insertions(+), 26 deletions(-)
lib/std/zig/render.zig+17-1| ... | @@ -26,6 +26,9 @@ pub const Fixups = struct { | ... | @@ -26,6 +26,9 @@ pub const Fixups = struct { |
| 26 | omit_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, | 26 | omit_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, void) = .{}, |
| 27 | /// These expressions will be replaced with the string value. | 27 | /// These expressions will be replaced with the string value. |
| 28 | replace_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, []const u8) = .{}, | 28 | replace_nodes: std.AutoHashMapUnmanaged(Ast.Node.Index, []const u8) = .{}, |
| 29 | /// Change all identifier names matching the key to be value instead. | ||
| 30 | rename_identifiers: std.StringArrayHashMapUnmanaged([]const u8) = .{}, | ||
| 31 | |||
| 29 | /// All `@import` builtin calls which refer to a file path will be prefixed | 32 | /// All `@import` builtin calls which refer to a file path will be prefixed |
| 30 | /// with this path. | 33 | /// with this path. |
| 31 | rebase_imported_paths: ?[]const u8 = null, | 34 | rebase_imported_paths: ?[]const u8 = null, |
| ... | @@ -34,7 +37,9 @@ pub const Fixups = struct { | ... | @@ -34,7 +37,9 @@ pub const Fixups = struct { |
| 34 | return f.unused_var_decls.count() + | 37 | return f.unused_var_decls.count() + |
| 35 | f.gut_functions.count() + | 38 | f.gut_functions.count() + |
| 36 | f.omit_nodes.count() + | 39 | f.omit_nodes.count() + |
| 37 | f.replace_nodes.count(); | 40 | f.replace_nodes.count() + |
| 41 | f.rename_identifiers.count() + | ||
| 42 | @intFromBool(f.rebase_imported_paths != null); | ||
| 38 | } | 43 | } |
| 39 | 44 | ||
| 40 | pub fn clearRetainingCapacity(f: *Fixups) void { | 45 | pub fn clearRetainingCapacity(f: *Fixups) void { |
| ... | @@ -42,6 +47,9 @@ pub const Fixups = struct { | ... | @@ -42,6 +47,9 @@ pub const Fixups = struct { |
| 42 | f.gut_functions.clearRetainingCapacity(); | 47 | f.gut_functions.clearRetainingCapacity(); |
| 43 | f.omit_nodes.clearRetainingCapacity(); | 48 | f.omit_nodes.clearRetainingCapacity(); |
| 44 | f.replace_nodes.clearRetainingCapacity(); | 49 | f.replace_nodes.clearRetainingCapacity(); |
| 50 | f.rename_identifiers.clearRetainingCapacity(); | ||
| 51 | |||
| 52 | f.rebase_imported_paths = null; | ||
| 45 | } | 53 | } |
| 46 | 54 | ||
| 47 | pub fn deinit(f: *Fixups, gpa: Allocator) void { | 55 | pub fn deinit(f: *Fixups, gpa: Allocator) void { |
| ... | @@ -49,6 +57,7 @@ pub const Fixups = struct { | ... | @@ -49,6 +57,7 @@ pub const Fixups = struct { |
| 49 | f.gut_functions.deinit(gpa); | 57 | f.gut_functions.deinit(gpa); |
| 50 | f.omit_nodes.deinit(gpa); | 58 | f.omit_nodes.deinit(gpa); |
| 51 | f.replace_nodes.deinit(gpa); | 59 | f.replace_nodes.deinit(gpa); |
| 60 | f.rename_identifiers.deinit(gpa); | ||
| 52 | f.* = undefined; | 61 | f.* = undefined; |
| 53 | } | 62 | } |
| 54 | }; | 63 | }; |
| ... | @@ -2833,6 +2842,13 @@ fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote | ... | @@ -2833,6 +2842,13 @@ fn renderIdentifier(r: *Render, token_index: Ast.TokenIndex, space: Space, quote |
| 2833 | const token_tags = tree.tokens.items(.tag); | 2842 | const token_tags = tree.tokens.items(.tag); |
| 2834 | assert(token_tags[token_index] == .identifier); | 2843 | assert(token_tags[token_index] == .identifier); |
| 2835 | const lexeme = tokenSliceForRender(tree, token_index); | 2844 | const lexeme = tokenSliceForRender(tree, token_index); |
| 2845 | |||
| 2846 | if (r.fixups.rename_identifiers.get(lexeme)) |mangled| { | ||
| 2847 | try r.ais.writer().writeAll(mangled); | ||
| 2848 | try renderSpace(r, token_index, lexeme.len, space); | ||
| 2849 | return; | ||
| 2850 | } | ||
| 2851 | |||
| 2836 | if (lexeme[0] != '@') { | 2852 | if (lexeme[0] != '@') { |
| 2837 | return renderToken(r, token_index, space); | 2853 | return renderToken(r, token_index, space); |
| 2838 | } | 2854 | } |
src/reduce.zig+34-8| ... | @@ -148,7 +148,7 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -148,7 +148,7 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 148 | 148 | ||
| 149 | var transformations = std.ArrayList(Walk.Transformation).init(gpa); | 149 | var transformations = std.ArrayList(Walk.Transformation).init(gpa); |
| 150 | defer transformations.deinit(); | 150 | defer transformations.deinit(); |
| 151 | try Walk.findTransformations(&tree, &transformations); | 151 | try Walk.findTransformations(arena, &tree, &transformations); |
| 152 | sortTransformations(transformations.items, rng.random()); | 152 | sortTransformations(transformations.items, rng.random()); |
| 153 | 153 | ||
| 154 | fresh: while (transformations.items.len > 0) { | 154 | fresh: while (transformations.items.len > 0) { |
| ... | @@ -162,12 +162,19 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -162,12 +162,19 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 162 | subset_size = @max(1, subset_size / 2); | 162 | subset_size = @max(1, subset_size / 2); |
| 163 | 163 | ||
| 164 | const this_set = transformations.items[start_index..][0..subset_size]; | 164 | const this_set = transformations.items[start_index..][0..subset_size]; |
| 165 | std.debug.print("trying {d} random transformations: ", .{subset_size}); | ||
| 166 | for (this_set[0..@min(this_set.len, 20)]) |t| { | ||
| 167 | std.debug.print("{s} ", .{@tagName(t)}); | ||
| 168 | } | ||
| 169 | std.debug.print("\n", .{}); | ||
| 165 | try transformationsToFixups(gpa, arena, root_source_file_path, this_set, &fixups); | 170 | try transformationsToFixups(gpa, arena, root_source_file_path, this_set, &fixups); |
| 166 | 171 | ||
| 167 | rendered.clearRetainingCapacity(); | 172 | rendered.clearRetainingCapacity(); |
| 168 | try tree.renderToArrayList(&rendered, fixups); | 173 | try tree.renderToArrayList(&rendered, fixups); |
| 169 | try std.fs.cwd().writeFile(root_source_file_path, rendered.items); | 174 | try std.fs.cwd().writeFile(root_source_file_path, rendered.items); |
| 170 | 175 | ||
| 176 | //std.debug.print("trying this code:\n{s}\n", .{rendered.items}); | ||
| 177 | |||
| 171 | const interestingness = try runCheck(arena, interestingness_argv.items); | 178 | const interestingness = try runCheck(arena, interestingness_argv.items); |
| 172 | std.debug.print("{d} random transformations: {s}. {d} remaining\n", .{ | 179 | std.debug.print("{d} random transformations: {s}. {d} remaining\n", .{ |
| 173 | subset_size, @tagName(interestingness), transformations.items.len - start_index, | 180 | subset_size, @tagName(interestingness), transformations.items.len - start_index, |
| ... | @@ -179,7 +186,7 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -179,7 +186,7 @@ pub fn main(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 179 | tree.deinit(gpa); | 186 | tree.deinit(gpa); |
| 180 | tree = new_tree; | 187 | tree = new_tree; |
| 181 | 188 | ||
| 182 | try Walk.findTransformations(&tree, &transformations); | 189 | try Walk.findTransformations(arena, &tree, &transformations); |
| 183 | // Resetting based on the seed again means we will get the same | 190 | // Resetting based on the seed again means we will get the same |
| 184 | // results if restarting the reduction process from this new point. | 191 | // results if restarting the reduction process from this new point. |
| 185 | rng = std.rand.DefaultPrng.init(seed); | 192 | rng = std.rand.DefaultPrng.init(seed); |
| ... | @@ -263,7 +270,6 @@ fn transformationsToFixups( | ... | @@ -263,7 +270,6 @@ fn transformationsToFixups( |
| 263 | try fixups.replace_nodes.put(gpa, node, "undefined"); | 270 | try fixups.replace_nodes.put(gpa, node, "undefined"); |
| 264 | }, | 271 | }, |
| 265 | .inline_imported_file => |inline_imported_file| { | 272 | .inline_imported_file => |inline_imported_file| { |
| 266 | defer gpa.free(inline_imported_file.imported_string); | ||
| 267 | const full_imported_path = try std.fs.path.join(gpa, &.{ | 273 | const full_imported_path = try std.fs.path.join(gpa, &.{ |
| 268 | std.fs.path.dirname(root_source_file_path) orelse ".", | 274 | std.fs.path.dirname(root_source_file_path) orelse ".", |
| 269 | inline_imported_file.imported_string, | 275 | inline_imported_file.imported_string, |
| ... | @@ -274,14 +280,34 @@ fn transformationsToFixups( | ... | @@ -274,14 +280,34 @@ fn transformationsToFixups( |
| 274 | gpa.free(other_file_ast.source); | 280 | gpa.free(other_file_ast.source); |
| 275 | other_file_ast.deinit(gpa); | 281 | other_file_ast.deinit(gpa); |
| 276 | } | 282 | } |
| 277 | var other_source = std.ArrayList(u8).init(gpa); | 283 | |
| 278 | defer other_source.deinit(); | ||
| 279 | var inlined_fixups: Ast.Fixups = .{}; | 284 | var inlined_fixups: Ast.Fixups = .{}; |
| 280 | defer inlined_fixups.deinit(gpa); | 285 | defer inlined_fixups.deinit(gpa); |
| 286 | if (std.fs.path.dirname(inline_imported_file.imported_string)) |dirname| { | ||
| 287 | inlined_fixups.rebase_imported_paths = dirname; | ||
| 288 | } | ||
| 289 | for (inline_imported_file.in_scope_names.keys()) |name| { | ||
| 290 | // This name needs to be mangled in order to not cause an | ||
| 291 | // ambiguous reference error. | ||
| 292 | var i: u32 = 2; | ||
| 293 | const mangled = while (true) : (i += 1) { | ||
| 294 | const mangled = try std.fmt.allocPrint(gpa, "{s}{d}", .{ name, i }); | ||
| 295 | if (!inline_imported_file.in_scope_names.contains(mangled)) | ||
| 296 | break mangled; | ||
| 297 | gpa.free(mangled); | ||
| 298 | }; | ||
| 299 | try inlined_fixups.rename_identifiers.put(gpa, name, mangled); | ||
| 300 | } | ||
| 301 | defer { | ||
| 302 | for (inlined_fixups.rename_identifiers.values()) |v| { | ||
| 303 | gpa.free(v); | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | var other_source = std.ArrayList(u8).init(gpa); | ||
| 308 | defer other_source.deinit(); | ||
| 281 | try other_source.appendSlice("struct {\n"); | 309 | try other_source.appendSlice("struct {\n"); |
| 282 | try other_file_ast.renderToArrayList(&other_source, .{ | 310 | try other_file_ast.renderToArrayList(&other_source, inlined_fixups); |
| 283 | .rebase_imported_paths = std.fs.path.dirname(inline_imported_file.imported_string), | ||
| 284 | }); | ||
| 285 | try other_source.appendSlice("}"); | 311 | try other_source.appendSlice("}"); |
| 286 | 312 | ||
| 287 | try fixups.replace_nodes.put( | 313 | try fixups.replace_nodes.put( |
src/reduce/Walk.zig+61-17| ... | @@ -7,7 +7,9 @@ const BuiltinFn = @import("../BuiltinFn.zig"); | ... | @@ -7,7 +7,9 @@ const BuiltinFn = @import("../BuiltinFn.zig"); |
| 7 | ast: *const Ast, | 7 | ast: *const Ast, |
| 8 | transformations: *std.ArrayList(Transformation), | 8 | transformations: *std.ArrayList(Transformation), |
| 9 | unreferenced_globals: std.StringArrayHashMapUnmanaged(Ast.Node.Index), | 9 | unreferenced_globals: std.StringArrayHashMapUnmanaged(Ast.Node.Index), |
| 10 | in_scope_names: std.StringArrayHashMapUnmanaged(u32), | ||
| 10 | gpa: std.mem.Allocator, | 11 | gpa: std.mem.Allocator, |
| 12 | arena: std.mem.Allocator, | ||
| 11 | 13 | ||
| 12 | pub const Transformation = union(enum) { | 14 | pub const Transformation = union(enum) { |
| 13 | /// Replace the fn decl AST Node with one whose body is only `@trap()` with | 15 | /// Replace the fn decl AST Node with one whose body is only `@trap()` with |
| ... | @@ -18,25 +20,39 @@ pub const Transformation = union(enum) { | ... | @@ -18,25 +20,39 @@ pub const Transformation = union(enum) { |
| 18 | /// Replace an expression with `undefined`. | 20 | /// Replace an expression with `undefined`. |
| 19 | replace_with_undef: Ast.Node.Index, | 21 | replace_with_undef: Ast.Node.Index, |
| 20 | /// Replace an `@import` with the imported file contents wrapped in a struct. | 22 | /// Replace an `@import` with the imported file contents wrapped in a struct. |
| 21 | inline_imported_file: struct { | 23 | inline_imported_file: InlineImportedFile, |
| 24 | |||
| 25 | pub const InlineImportedFile = struct { | ||
| 22 | builtin_call_node: Ast.Node.Index, | 26 | builtin_call_node: Ast.Node.Index, |
| 23 | imported_string: []const u8, | 27 | imported_string: []const u8, |
| 24 | }, | 28 | /// Identifier names that must be renamed in the inlined code or else |
| 29 | /// will cause ambiguous reference errors. | ||
| 30 | in_scope_names: std.StringArrayHashMapUnmanaged(void), | ||
| 31 | }; | ||
| 25 | }; | 32 | }; |
| 26 | 33 | ||
| 27 | pub const Error = error{OutOfMemory}; | 34 | pub const Error = error{OutOfMemory}; |
| 28 | 35 | ||
| 29 | /// The result will be priority shuffled. | 36 | /// The result will be priority shuffled. |
| 30 | pub fn findTransformations(ast: *const Ast, transformations: *std.ArrayList(Transformation)) !void { | 37 | pub fn findTransformations( |
| 38 | arena: std.mem.Allocator, | ||
| 39 | ast: *const Ast, | ||
| 40 | transformations: *std.ArrayList(Transformation), | ||
| 41 | ) !void { | ||
| 31 | transformations.clearRetainingCapacity(); | 42 | transformations.clearRetainingCapacity(); |
| 32 | 43 | ||
| 33 | var walk: Walk = .{ | 44 | var walk: Walk = .{ |
| 34 | .ast = ast, | 45 | .ast = ast, |
| 35 | .transformations = transformations, | 46 | .transformations = transformations, |
| 36 | .gpa = transformations.allocator, | 47 | .gpa = transformations.allocator, |
| 48 | .arena = arena, | ||
| 37 | .unreferenced_globals = .{}, | 49 | .unreferenced_globals = .{}, |
| 50 | .in_scope_names = .{}, | ||
| 38 | }; | 51 | }; |
| 39 | defer walk.unreferenced_globals.deinit(walk.gpa); | 52 | defer { |
| 53 | walk.unreferenced_globals.deinit(walk.gpa); | ||
| 54 | walk.in_scope_names.deinit(walk.gpa); | ||
| 55 | } | ||
| 40 | 56 | ||
| 41 | try walkMembers(&walk, walk.ast.rootDecls()); | 57 | try walkMembers(&walk, walk.ast.rootDecls()); |
| 42 | 58 | ||
| ... | @@ -49,14 +65,18 @@ pub fn findTransformations(ast: *const Ast, transformations: *std.ArrayList(Tran | ... | @@ -49,14 +65,18 @@ pub fn findTransformations(ast: *const Ast, transformations: *std.ArrayList(Tran |
| 49 | 65 | ||
| 50 | fn walkMembers(w: *Walk, members: []const Ast.Node.Index) Error!void { | 66 | fn walkMembers(w: *Walk, members: []const Ast.Node.Index) Error!void { |
| 51 | // First we scan for globals so that we can delete them while walking. | 67 | // First we scan for globals so that we can delete them while walking. |
| 52 | try scanDecls(w, members); | 68 | try scanDecls(w, members, .add); |
| 53 | 69 | ||
| 54 | for (members) |member| { | 70 | for (members) |member| { |
| 55 | try walkMember(w, member); | 71 | try walkMember(w, member); |
| 56 | } | 72 | } |
| 73 | |||
| 74 | try scanDecls(w, members, .remove); | ||
| 57 | } | 75 | } |
| 58 | 76 | ||
| 59 | fn scanDecls(w: *Walk, members: []const Ast.Node.Index) Error!void { | 77 | const ScanDeclsAction = enum { add, remove }; |
| 78 | |||
| 79 | fn scanDecls(w: *Walk, members: []const Ast.Node.Index, action: ScanDeclsAction) Error!void { | ||
| 60 | const ast = w.ast; | 80 | const ast = w.ast; |
| 61 | const gpa = w.gpa; | 81 | const gpa = w.gpa; |
| 62 | const node_tags = ast.nodes.items(.tag); | 82 | const node_tags = ast.nodes.items(.tag); |
| ... | @@ -80,9 +100,27 @@ fn scanDecls(w: *Walk, members: []const Ast.Node.Index) Error!void { | ... | @@ -80,9 +100,27 @@ fn scanDecls(w: *Walk, members: []const Ast.Node.Index) Error!void { |
| 80 | 100 | ||
| 81 | else => continue, | 101 | else => continue, |
| 82 | }; | 102 | }; |
| 103 | |||
| 83 | assert(token_tags[name_token] == .identifier); | 104 | assert(token_tags[name_token] == .identifier); |
| 84 | const name_bytes = ast.tokenSlice(name_token); | 105 | const name_bytes = ast.tokenSlice(name_token); |
| 85 | try w.unreferenced_globals.put(gpa, name_bytes, member_node); | 106 | |
| 107 | switch (action) { | ||
| 108 | .add => { | ||
| 109 | try w.unreferenced_globals.put(gpa, name_bytes, member_node); | ||
| 110 | |||
| 111 | const gop = try w.in_scope_names.getOrPut(gpa, name_bytes); | ||
| 112 | if (!gop.found_existing) gop.value_ptr.* = 0; | ||
| 113 | gop.value_ptr.* += 1; | ||
| 114 | }, | ||
| 115 | .remove => { | ||
| 116 | const entry = w.in_scope_names.getEntry(name_bytes).?; | ||
| 117 | if (entry.value_ptr.* <= 1) { | ||
| 118 | assert(w.in_scope_names.swapRemove(name_bytes)); | ||
| 119 | } else { | ||
| 120 | entry.value_ptr.* -= 1; | ||
| 121 | } | ||
| 122 | }, | ||
| 123 | } | ||
| 86 | } | 124 | } |
| 87 | } | 125 | } |
| 88 | 126 | ||
| ... | @@ -567,12 +605,12 @@ fn walkLocalVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { | ... | @@ -567,12 +605,12 @@ fn walkLocalVarDecl(w: *Walk, var_decl: Ast.full.VarDecl) Error!void { |
| 567 | try walkExpression(w, var_decl.ast.section_node); | 605 | try walkExpression(w, var_decl.ast.section_node); |
| 568 | } | 606 | } |
| 569 | 607 | ||
| 570 | assert(var_decl.ast.init_node != 0); | 608 | if (var_decl.ast.init_node != 0) { |
| 571 | if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) { | 609 | if (!isUndefinedIdent(w.ast, var_decl.ast.init_node)) { |
| 572 | try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node }); | 610 | try w.transformations.append(.{ .replace_with_undef = var_decl.ast.init_node }); |
| 611 | } | ||
| 612 | try walkExpression(w, var_decl.ast.init_node); | ||
| 573 | } | 613 | } |
| 574 | |||
| 575 | return walkExpression(w, var_decl.ast.init_node); | ||
| 576 | } | 614 | } |
| 577 | 615 | ||
| 578 | fn walkContainerField(w: *Walk, field: Ast.full.ContainerField) Error!void { | 616 | fn walkContainerField(w: *Walk, field: Ast.full.ContainerField) Error!void { |
| ... | @@ -582,7 +620,9 @@ fn walkContainerField(w: *Walk, field: Ast.full.ContainerField) Error!void { | ... | @@ -582,7 +620,9 @@ fn walkContainerField(w: *Walk, field: Ast.full.ContainerField) Error!void { |
| 582 | if (field.ast.align_expr != 0) { | 620 | if (field.ast.align_expr != 0) { |
| 583 | try walkExpression(w, field.ast.align_expr); // alignment | 621 | try walkExpression(w, field.ast.align_expr); // alignment |
| 584 | } | 622 | } |
| 585 | try walkExpression(w, field.ast.value_expr); // value | 623 | if (field.ast.value_expr != 0) { |
| 624 | try walkExpression(w, field.ast.value_expr); // value | ||
| 625 | } | ||
| 586 | } | 626 | } |
| 587 | 627 | ||
| 588 | fn walkBlock( | 628 | fn walkBlock( |
| ... | @@ -690,7 +730,6 @@ fn walkBuiltinCall( | ... | @@ -690,7 +730,6 @@ fn walkBuiltinCall( |
| 690 | params: []const Ast.Node.Index, | 730 | params: []const Ast.Node.Index, |
| 691 | ) Error!void { | 731 | ) Error!void { |
| 692 | const ast = w.ast; | 732 | const ast = w.ast; |
| 693 | const gpa = w.gpa; | ||
| 694 | const main_tokens = ast.nodes.items(.main_token); | 733 | const main_tokens = ast.nodes.items(.main_token); |
| 695 | const builtin_token = main_tokens[call_node]; | 734 | const builtin_token = main_tokens[call_node]; |
| 696 | const builtin_name = ast.tokenSlice(builtin_token); | 735 | const builtin_name = ast.tokenSlice(builtin_token); |
| ... | @@ -700,12 +739,17 @@ fn walkBuiltinCall( | ... | @@ -700,12 +739,17 @@ fn walkBuiltinCall( |
| 700 | const operand_node = params[0]; | 739 | const operand_node = params[0]; |
| 701 | const str_lit_token = main_tokens[operand_node]; | 740 | const str_lit_token = main_tokens[operand_node]; |
| 702 | const token_bytes = ast.tokenSlice(str_lit_token); | 741 | const token_bytes = ast.tokenSlice(str_lit_token); |
| 703 | const imported_string = std.zig.string_literal.parseAlloc(gpa, token_bytes) catch | 742 | if (std.mem.endsWith(u8, token_bytes, ".zig\"")) { |
| 704 | unreachable; | 743 | const imported_string = std.zig.string_literal.parseAlloc(w.arena, token_bytes) catch |
| 705 | if (std.mem.endsWith(u8, imported_string, ".zig")) { | 744 | unreachable; |
| 706 | try w.transformations.append(.{ .inline_imported_file = .{ | 745 | try w.transformations.append(.{ .inline_imported_file = .{ |
| 707 | .builtin_call_node = call_node, | 746 | .builtin_call_node = call_node, |
| 708 | .imported_string = imported_string, | 747 | .imported_string = imported_string, |
| 748 | .in_scope_names = try std.StringArrayHashMapUnmanaged(void).init( | ||
| 749 | w.arena, | ||
| 750 | w.in_scope_names.keys(), | ||
| 751 | &.{}, | ||
| 752 | ), | ||
| 709 | } }); | 753 | } }); |
| 710 | } | 754 | } |
| 711 | }, | 755 | }, |