| author | |
| committer | |
| log | 220020599cc11764eb9ed32025dd506f2affedda |
| tree | 4467fe3ff1f919eec89bafac7435fe58cf9a876a |
| parent | d395127552ab6f04b7b044b2a309e0d1e8977775 |
| parent | 5f9186d0ce78ce1eb7db9634849b38d2e90d071e |
| signature |
AstGen: detect and error on files included in multiple packages6 files changed, 172 insertions(+), 56 deletions(-)
src/Compilation.zig+71-14| ... | ... | @@ -639,14 +639,6 @@ pub const AllErrors = struct { |
| 639 | 639 | note_i += 1; |
| 640 | 640 | } |
| 641 | 641 | } |
| 642 | if (module_err_msg.src_loc.lazy == .entire_file) { | |
| 643 | try errors.append(.{ | |
| 644 | .plain = .{ | |
| 645 | .msg = try allocator.dupe(u8, module_err_msg.msg), | |
| 646 | }, | |
| 647 | }); | |
| 648 | return; | |
| 649 | } | |
| 650 | 642 | |
| 651 | 643 | const reference_trace = try allocator.alloc(Message, module_err_msg.reference_trace.len); |
| 652 | 644 | for (reference_trace) |*reference, i| { |
| ... | ... | @@ -683,7 +675,7 @@ pub const AllErrors = struct { |
| 683 | 675 | .column = @intCast(u32, err_loc.column), |
| 684 | 676 | .notes = notes_buf[0..note_i], |
| 685 | 677 | .reference_trace = reference_trace, |
| 686 | .source_line = try allocator.dupe(u8, err_loc.source_line), | |
| 678 | .source_line = if (module_err_msg.src_loc.lazy == .entire_file) null else try allocator.dupe(u8, err_loc.source_line), | |
| 687 | 679 | }, |
| 688 | 680 | }); |
| 689 | 681 | } |
| ... | ... | @@ -1610,6 +1602,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1610 | 1602 | |
| 1611 | 1603 | const builtin_pkg = try Package.createWithDir( |
| 1612 | 1604 | gpa, |
| 1605 | "builtin", | |
| 1613 | 1606 | zig_cache_artifact_directory, |
| 1614 | 1607 | null, |
| 1615 | 1608 | "builtin.zig", |
| ... | ... | @@ -1618,6 +1611,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1618 | 1611 | |
| 1619 | 1612 | const std_pkg = try Package.createWithDir( |
| 1620 | 1613 | gpa, |
| 1614 | "std", | |
| 1621 | 1615 | options.zig_lib_directory, |
| 1622 | 1616 | "std", |
| 1623 | 1617 | "std.zig", |
| ... | ... | @@ -1625,11 +1619,14 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1625 | 1619 | errdefer std_pkg.destroy(gpa); |
| 1626 | 1620 | |
| 1627 | 1621 | const root_pkg = if (options.is_test) root_pkg: { |
| 1622 | // TODO: we currently have two packages named 'root' here, which is weird. This | |
| 1623 | // should be changed as part of the resolution of #12201 | |
| 1628 | 1624 | const test_pkg = if (options.test_runner_path) |test_runner| |
| 1629 | try Package.create(gpa, null, test_runner) | |
| 1625 | try Package.create(gpa, "root", null, test_runner) | |
| 1630 | 1626 | else |
| 1631 | 1627 | try Package.createWithDir( |
| 1632 | 1628 | gpa, |
| 1629 | "root", | |
| 1633 | 1630 | options.zig_lib_directory, |
| 1634 | 1631 | null, |
| 1635 | 1632 | "test_runner.zig", |
| ... | ... | @@ -1640,9 +1637,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1640 | 1637 | } else main_pkg; |
| 1641 | 1638 | errdefer if (options.is_test) root_pkg.destroy(gpa); |
| 1642 | 1639 | |
| 1643 | try main_pkg.addAndAdopt(gpa, "builtin", builtin_pkg); | |
| 1644 | try main_pkg.add(gpa, "root", root_pkg); | |
| 1645 | try main_pkg.addAndAdopt(gpa, "std", std_pkg); | |
| 1640 | try main_pkg.addAndAdopt(gpa, builtin_pkg); | |
| 1641 | try main_pkg.add(gpa, root_pkg); | |
| 1642 | try main_pkg.addAndAdopt(gpa, std_pkg); | |
| 1646 | 1643 | |
| 1647 | 1644 | const main_pkg_is_std = m: { |
| 1648 | 1645 | const std_path = try std.fs.path.resolve(arena, &[_][]const u8{ |
| ... | ... | @@ -3075,6 +3072,57 @@ pub fn performAllTheWork( |
| 3075 | 3072 | } |
| 3076 | 3073 | } |
| 3077 | 3074 | |
| 3075 | if (comp.bin_file.options.module) |mod| { | |
| 3076 | for (mod.import_table.values()) |file| { | |
| 3077 | if (!file.multi_pkg) continue; | |
| 3078 | const err = err_blk: { | |
| 3079 | const notes = try mod.gpa.alloc(Module.ErrorMsg, file.references.items.len); | |
| 3080 | errdefer mod.gpa.free(notes); | |
| 3081 | ||
| 3082 | for (notes) |*note, i| { | |
| 3083 | errdefer for (notes[0..i]) |*n| n.deinit(mod.gpa); | |
| 3084 | note.* = switch (file.references.items[i]) { | |
| 3085 | .import => |loc| try Module.ErrorMsg.init( | |
| 3086 | mod.gpa, | |
| 3087 | loc, | |
| 3088 | "imported from package {s}", | |
| 3089 | .{loc.file_scope.pkg.name}, | |
| 3090 | ), | |
| 3091 | .root => |pkg| try Module.ErrorMsg.init( | |
| 3092 | mod.gpa, | |
| 3093 | .{ .file_scope = file, .parent_decl_node = 0, .lazy = .entire_file }, | |
| 3094 | "root of package {s}", | |
| 3095 | .{pkg.name}, | |
| 3096 | ), | |
| 3097 | }; | |
| 3098 | } | |
| 3099 | errdefer for (notes) |*n| n.deinit(mod.gpa); | |
| 3100 | ||
| 3101 | const err = try Module.ErrorMsg.create( | |
| 3102 | mod.gpa, | |
| 3103 | .{ .file_scope = file, .parent_decl_node = 0, .lazy = .entire_file }, | |
| 3104 | "file exists in multiple packages", | |
| 3105 | .{}, | |
| 3106 | ); | |
| 3107 | err.notes = notes; | |
| 3108 | break :err_blk err; | |
| 3109 | }; | |
| 3110 | errdefer err.destroy(mod.gpa); | |
| 3111 | try mod.failed_files.putNoClobber(mod.gpa, file, err); | |
| 3112 | } | |
| 3113 | ||
| 3114 | // Now that we've reported the errors, we need to deal with | |
| 3115 | // dependencies. Any file referenced by a multi_pkg file should also be | |
| 3116 | // marked multi_pkg and have its status set to astgen_failure, as it's | |
| 3117 | // ambiguous which package they should be analyzed as a part of. We need | |
| 3118 | // to add this flag after reporting the errors however, as otherwise | |
| 3119 | // we'd get an error for every single downstream file, which wouldn't be | |
| 3120 | // very useful. | |
| 3121 | for (mod.import_table.values()) |file| { | |
| 3122 | if (file.multi_pkg) file.recursiveMarkMultiPkg(mod); | |
| 3123 | } | |
| 3124 | } | |
| 3125 | ||
| 3078 | 3126 | { |
| 3079 | 3127 | const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls"); |
| 3080 | 3128 | defer outdated_and_deleted_decls_frame.end(); |
| ... | ... | @@ -3499,7 +3547,15 @@ fn workerAstGenFile( |
| 3499 | 3547 | comp.mutex.lock(); |
| 3500 | 3548 | defer comp.mutex.unlock(); |
| 3501 | 3549 | |
| 3502 | break :blk mod.importFile(file, import_path) catch continue; | |
| 3550 | const res = mod.importFile(file, import_path) catch continue; | |
| 3551 | if (!res.is_pkg) { | |
| 3552 | res.file.addReference(mod.*, .{ .import = .{ | |
| 3553 | .file_scope = file, | |
| 3554 | .parent_decl_node = 0, | |
| 3555 | .lazy = .{ .token_abs = item.data.token }, | |
| 3556 | } }) catch continue; | |
| 3557 | } | |
| 3558 | break :blk res; | |
| 3503 | 3559 | }; |
| 3504 | 3560 | if (import_result.is_new) { |
| 3505 | 3561 | log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{ |
| ... | ... | @@ -5327,6 +5383,7 @@ fn buildOutputFromZig( |
| 5327 | 5383 | var main_pkg: Package = .{ |
| 5328 | 5384 | .root_src_directory = comp.zig_lib_directory, |
| 5329 | 5385 | .root_src_path = src_basename, |
| 5386 | .name = "root", | |
| 5330 | 5387 | }; |
| 5331 | 5388 | defer main_pkg.deinitTable(comp.gpa); |
| 5332 | 5389 | const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len]; |
src/Module.zig+57-5| ... | ... | @@ -1943,6 +1943,10 @@ pub const File = struct { |
| 1943 | 1943 | zir: Zir, |
| 1944 | 1944 | /// Package that this file is a part of, managed externally. |
| 1945 | 1945 | pkg: *Package, |
| 1946 | /// Whether this file is a part of multiple packages. This is an error condition which will be reported after AstGen. | |
| 1947 | multi_pkg: bool = false, | |
| 1948 | /// List of references to this file, used for multi-package errors. | |
| 1949 | references: std.ArrayListUnmanaged(Reference) = .{}, | |
| 1946 | 1950 | |
| 1947 | 1951 | /// Used by change detection algorithm, after astgen, contains the |
| 1948 | 1952 | /// set of decls that existed in the previous ZIR but not in the new one. |
| ... | ... | @@ -1958,6 +1962,14 @@ pub const File = struct { |
| 1958 | 1962 | /// successful, this field is unloaded. |
| 1959 | 1963 | prev_zir: ?*Zir = null, |
| 1960 | 1964 | |
| 1965 | /// A single reference to a file. | |
| 1966 | const Reference = union(enum) { | |
| 1967 | /// The file is imported directly (i.e. not as a package) with @import. | |
| 1968 | import: SrcLoc, | |
| 1969 | /// The file is the root of a package. | |
| 1970 | root: *Package, | |
| 1971 | }; | |
| 1972 | ||
| 1961 | 1973 | pub fn unload(file: *File, gpa: Allocator) void { |
| 1962 | 1974 | file.unloadTree(gpa); |
| 1963 | 1975 | file.unloadSource(gpa); |
| ... | ... | @@ -1990,6 +2002,7 @@ pub const File = struct { |
| 1990 | 2002 | log.debug("deinit File {s}", .{file.sub_file_path}); |
| 1991 | 2003 | file.deleted_decls.deinit(gpa); |
| 1992 | 2004 | file.outdated_decls.deinit(gpa); |
| 2005 | file.references.deinit(gpa); | |
| 1993 | 2006 | if (file.root_decl.unwrap()) |root_decl| { |
| 1994 | 2007 | mod.destroyDecl(root_decl); |
| 1995 | 2008 | } |
| ... | ... | @@ -2110,6 +2123,44 @@ pub const File = struct { |
| 2110 | 2123 | else => true, |
| 2111 | 2124 | }; |
| 2112 | 2125 | } |
| 2126 | ||
| 2127 | /// Add a reference to this file during AstGen. | |
| 2128 | pub fn addReference(file: *File, mod: Module, ref: Reference) !void { | |
| 2129 | try file.references.append(mod.gpa, ref); | |
| 2130 | ||
| 2131 | const pkg = switch (ref) { | |
| 2132 | .import => |loc| loc.file_scope.pkg, | |
| 2133 | .root => |pkg| pkg, | |
| 2134 | }; | |
| 2135 | if (pkg != file.pkg) file.multi_pkg = true; | |
| 2136 | } | |
| 2137 | ||
| 2138 | /// Mark this file and every file referenced by it as multi_pkg and report an | |
| 2139 | /// astgen_failure error for them. AstGen must have completed in its entirety. | |
| 2140 | pub fn recursiveMarkMultiPkg(file: *File, mod: *Module) void { | |
| 2141 | file.multi_pkg = true; | |
| 2142 | file.status = .astgen_failure; | |
| 2143 | ||
| 2144 | std.debug.assert(file.zir_loaded); | |
| 2145 | const imports_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.imports)]; | |
| 2146 | if (imports_index == 0) return; | |
| 2147 | const extra = file.zir.extraData(Zir.Inst.Imports, imports_index); | |
| 2148 | ||
| 2149 | var import_i: u32 = 0; | |
| 2150 | var extra_index = extra.end; | |
| 2151 | while (import_i < extra.data.imports_len) : (import_i += 1) { | |
| 2152 | const item = file.zir.extraData(Zir.Inst.Imports.Item, extra_index); | |
| 2153 | extra_index = item.end; | |
| 2154 | ||
| 2155 | const import_path = file.zir.nullTerminatedString(item.data.name); | |
| 2156 | if (mem.eql(u8, import_path, "builtin")) continue; | |
| 2157 | ||
| 2158 | const res = mod.importFile(file, import_path) catch continue; | |
| 2159 | if (!res.is_pkg and !res.file.multi_pkg) { | |
| 2160 | res.file.recursiveMarkMultiPkg(mod); | |
| 2161 | } | |
| 2162 | } | |
| 2163 | } | |
| 2113 | 2164 | }; |
| 2114 | 2165 | |
| 2115 | 2166 | /// Represents the contents of a file loaded with `@embedFile`. |
| ... | ... | @@ -3220,16 +3271,11 @@ pub fn deinit(mod: *Module) void { |
| 3220 | 3271 | // The callsite of `Compilation.create` owns the `main_pkg`, however |
| 3221 | 3272 | // Module owns the builtin and std packages that it adds. |
| 3222 | 3273 | if (mod.main_pkg.table.fetchRemove("builtin")) |kv| { |
| 3223 | gpa.free(kv.key); | |
| 3224 | 3274 | kv.value.destroy(gpa); |
| 3225 | 3275 | } |
| 3226 | 3276 | if (mod.main_pkg.table.fetchRemove("std")) |kv| { |
| 3227 | gpa.free(kv.key); | |
| 3228 | 3277 | kv.value.destroy(gpa); |
| 3229 | 3278 | } |
| 3230 | if (mod.main_pkg.table.fetchRemove("root")) |kv| { | |
| 3231 | gpa.free(kv.key); | |
| 3232 | } | |
| 3233 | 3279 | if (mod.root_pkg != mod.main_pkg) { |
| 3234 | 3280 | mod.root_pkg.destroy(gpa); |
| 3235 | 3281 | } |
| ... | ... | @@ -4695,6 +4741,7 @@ pub fn declareDeclDependency(mod: *Module, depender_index: Decl.Index, dependee_ |
| 4695 | 4741 | pub const ImportFileResult = struct { |
| 4696 | 4742 | file: *File, |
| 4697 | 4743 | is_new: bool, |
| 4744 | is_pkg: bool, | |
| 4698 | 4745 | }; |
| 4699 | 4746 | |
| 4700 | 4747 | pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult { |
| ... | ... | @@ -4714,6 +4761,7 @@ pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult { |
| 4714 | 4761 | if (gop.found_existing) return ImportFileResult{ |
| 4715 | 4762 | .file = gop.value_ptr.*, |
| 4716 | 4763 | .is_new = false, |
| 4764 | .is_pkg = true, | |
| 4717 | 4765 | }; |
| 4718 | 4766 | |
| 4719 | 4767 | const sub_file_path = try gpa.dupe(u8, pkg.root_src_path); |
| ... | ... | @@ -4737,9 +4785,11 @@ pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult { |
| 4737 | 4785 | .pkg = pkg, |
| 4738 | 4786 | .root_decl = .none, |
| 4739 | 4787 | }; |
| 4788 | try new_file.addReference(mod.*, .{ .root = pkg }); | |
| 4740 | 4789 | return ImportFileResult{ |
| 4741 | 4790 | .file = new_file, |
| 4742 | 4791 | .is_new = true, |
| 4792 | .is_pkg = true, | |
| 4743 | 4793 | }; |
| 4744 | 4794 | } |
| 4745 | 4795 | |
| ... | ... | @@ -4780,6 +4830,7 @@ pub fn importFile( |
| 4780 | 4830 | if (gop.found_existing) return ImportFileResult{ |
| 4781 | 4831 | .file = gop.value_ptr.*, |
| 4782 | 4832 | .is_new = false, |
| 4833 | .is_pkg = false, | |
| 4783 | 4834 | }; |
| 4784 | 4835 | |
| 4785 | 4836 | const new_file = try gpa.create(File); |
| ... | ... | @@ -4825,6 +4876,7 @@ pub fn importFile( |
| 4825 | 4876 | return ImportFileResult{ |
| 4826 | 4877 | .file = new_file, |
| 4827 | 4878 | .is_new = true, |
| 4879 | .is_pkg = false, | |
| 4828 | 4880 | }; |
| 4829 | 4881 | } |
| 4830 | 4882 |
src/Package.zig+26-13| ... | ... | @@ -24,10 +24,13 @@ table: Table = .{}, |
| 24 | 24 | parent: ?*Package = null, |
| 25 | 25 | /// Whether to free `root_src_directory` on `destroy`. |
| 26 | 26 | root_src_directory_owned: bool = false, |
| 27 | /// This information can be recovered from 'table', but it's more convenient to store on the package. | |
| 28 | name: []const u8, | |
| 27 | 29 | |
| 28 | 30 | /// Allocate a Package. No references to the slices passed are kept. |
| 29 | 31 | pub fn create( |
| 30 | 32 | gpa: Allocator, |
| 33 | name: []const u8, | |
| 31 | 34 | /// Null indicates the current working directory |
| 32 | 35 | root_src_dir_path: ?[]const u8, |
| 33 | 36 | /// Relative to root_src_dir_path |
| ... | ... | @@ -42,6 +45,9 @@ pub fn create( |
| 42 | 45 | const owned_src_path = try gpa.dupe(u8, root_src_path); |
| 43 | 46 | errdefer gpa.free(owned_src_path); |
| 44 | 47 | |
| 48 | const owned_name = try gpa.dupe(u8, name); | |
| 49 | errdefer gpa.free(owned_name); | |
| 50 | ||
| 45 | 51 | ptr.* = .{ |
| 46 | 52 | .root_src_directory = .{ |
| 47 | 53 | .path = owned_dir_path, |
| ... | ... | @@ -49,6 +55,7 @@ pub fn create( |
| 49 | 55 | }, |
| 50 | 56 | .root_src_path = owned_src_path, |
| 51 | 57 | .root_src_directory_owned = true, |
| 58 | .name = owned_name, | |
| 52 | 59 | }; |
| 53 | 60 | |
| 54 | 61 | return ptr; |
| ... | ... | @@ -56,6 +63,7 @@ pub fn create( |
| 56 | 63 | |
| 57 | 64 | pub fn createWithDir( |
| 58 | 65 | gpa: Allocator, |
| 66 | name: []const u8, | |
| 59 | 67 | directory: Compilation.Directory, |
| 60 | 68 | /// Relative to `directory`. If null, means `directory` is the root src dir |
| 61 | 69 | /// and is owned externally. |
| ... | ... | @@ -69,6 +77,9 @@ pub fn createWithDir( |
| 69 | 77 | const owned_src_path = try gpa.dupe(u8, root_src_path); |
| 70 | 78 | errdefer gpa.free(owned_src_path); |
| 71 | 79 | |
| 80 | const owned_name = try gpa.dupe(u8, name); | |
| 81 | errdefer gpa.free(owned_name); | |
| 82 | ||
| 72 | 83 | if (root_src_dir_path) |p| { |
| 73 | 84 | const owned_dir_path = try directory.join(gpa, &[1][]const u8{p}); |
| 74 | 85 | errdefer gpa.free(owned_dir_path); |
| ... | ... | @@ -80,12 +91,14 @@ pub fn createWithDir( |
| 80 | 91 | }, |
| 81 | 92 | .root_src_directory_owned = true, |
| 82 | 93 | .root_src_path = owned_src_path, |
| 94 | .name = owned_name, | |
| 83 | 95 | }; |
| 84 | 96 | } else { |
| 85 | 97 | ptr.* = .{ |
| 86 | 98 | .root_src_directory = directory, |
| 87 | 99 | .root_src_directory_owned = false, |
| 88 | 100 | .root_src_path = owned_src_path, |
| 101 | .name = owned_name, | |
| 89 | 102 | }; |
| 90 | 103 | } |
| 91 | 104 | return ptr; |
| ... | ... | @@ -95,6 +108,7 @@ pub fn createWithDir( |
| 95 | 108 | /// inside its table; the caller is responsible for calling destroy() on them. |
| 96 | 109 | pub fn destroy(pkg: *Package, gpa: Allocator) void { |
| 97 | 110 | gpa.free(pkg.root_src_path); |
| 111 | gpa.free(pkg.name); | |
| 98 | 112 | |
| 99 | 113 | if (pkg.root_src_directory_owned) { |
| 100 | 114 | // If root_src_directory.path is null then the handle is the cwd() |
| ... | ... | @@ -111,24 +125,18 @@ pub fn destroy(pkg: *Package, gpa: Allocator) void { |
| 111 | 125 | |
| 112 | 126 | /// Only frees memory associated with the table. |
| 113 | 127 | pub fn deinitTable(pkg: *Package, gpa: Allocator) void { |
| 114 | var it = pkg.table.keyIterator(); | |
| 115 | while (it.next()) |key| { | |
| 116 | gpa.free(key.*); | |
| 117 | } | |
| 118 | ||
| 119 | 128 | pkg.table.deinit(gpa); |
| 120 | 129 | } |
| 121 | 130 | |
| 122 | pub fn add(pkg: *Package, gpa: Allocator, name: []const u8, package: *Package) !void { | |
| 131 | pub fn add(pkg: *Package, gpa: Allocator, package: *Package) !void { | |
| 123 | 132 | try pkg.table.ensureUnusedCapacity(gpa, 1); |
| 124 | const name_dupe = try gpa.dupe(u8, name); | |
| 125 | pkg.table.putAssumeCapacityNoClobber(name_dupe, package); | |
| 133 | pkg.table.putAssumeCapacityNoClobber(package.name, package); | |
| 126 | 134 | } |
| 127 | 135 | |
| 128 | pub fn addAndAdopt(parent: *Package, gpa: Allocator, name: []const u8, child: *Package) !void { | |
| 136 | pub fn addAndAdopt(parent: *Package, gpa: Allocator, child: *Package) !void { | |
| 129 | 137 | assert(child.parent == null); // make up your mind, who is the parent?? |
| 130 | 138 | child.parent = parent; |
| 131 | return parent.add(gpa, name, child); | |
| 139 | return parent.add(gpa, child); | |
| 132 | 140 | } |
| 133 | 141 | |
| 134 | 142 | pub const build_zig_basename = "build.zig"; |
| ... | ... | @@ -237,7 +245,7 @@ pub fn fetchAndAddDependencies( |
| 237 | 245 | sub_prefix, |
| 238 | 246 | ); |
| 239 | 247 | |
| 240 | try addAndAdopt(pkg, gpa, fqn, sub_pkg); | |
| 248 | try addAndAdopt(pkg, gpa, sub_pkg); | |
| 241 | 249 | |
| 242 | 250 | try dependencies_source.writer().print(" pub const {s} = @import(\"{}\");\n", .{ |
| 243 | 251 | std.zig.fmtId(fqn), std.zig.fmtEscapes(fqn), |
| ... | ... | @@ -249,6 +257,7 @@ pub fn fetchAndAddDependencies( |
| 249 | 257 | |
| 250 | 258 | pub fn createFilePkg( |
| 251 | 259 | gpa: Allocator, |
| 260 | name: []const u8, | |
| 252 | 261 | cache_directory: Compilation.Directory, |
| 253 | 262 | basename: []const u8, |
| 254 | 263 | contents: []const u8, |
| ... | ... | @@ -269,7 +278,7 @@ pub fn createFilePkg( |
| 269 | 278 | const o_dir_sub_path = "o" ++ fs.path.sep_str ++ hex_digest; |
| 270 | 279 | try renameTmpIntoCache(cache_directory.handle, tmp_dir_sub_path, o_dir_sub_path); |
| 271 | 280 | |
| 272 | return createWithDir(gpa, cache_directory, o_dir_sub_path, basename); | |
| 281 | return createWithDir(gpa, name, cache_directory, o_dir_sub_path, basename); | |
| 273 | 282 | } |
| 274 | 283 | |
| 275 | 284 | fn fetchAndUnpack( |
| ... | ... | @@ -312,6 +321,9 @@ fn fetchAndUnpack( |
| 312 | 321 | const owned_src_path = try gpa.dupe(u8, build_zig_basename); |
| 313 | 322 | errdefer gpa.free(owned_src_path); |
| 314 | 323 | |
| 324 | const owned_name = try gpa.dupe(u8, fqn); | |
| 325 | errdefer gpa.free(owned_name); | |
| 326 | ||
| 315 | 327 | const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path}); |
| 316 | 328 | errdefer gpa.free(build_root); |
| 317 | 329 | |
| ... | ... | @@ -326,6 +338,7 @@ fn fetchAndUnpack( |
| 326 | 338 | }, |
| 327 | 339 | .root_src_directory_owned = true, |
| 328 | 340 | .root_src_path = owned_src_path, |
| 341 | .name = owned_name, | |
| 329 | 342 | }; |
| 330 | 343 | |
| 331 | 344 | return ptr; |
| ... | ... | @@ -414,7 +427,7 @@ fn fetchAndUnpack( |
| 414 | 427 | std.zig.fmtId(fqn), std.zig.fmtEscapes(build_root), |
| 415 | 428 | }); |
| 416 | 429 | |
| 417 | return createWithDir(gpa, global_cache_directory, pkg_dir_sub_path, build_zig_basename); | |
| 430 | return createWithDir(gpa, fqn, global_cache_directory, pkg_dir_sub_path, build_zig_basename); | |
| 418 | 431 | } |
| 419 | 432 | |
| 420 | 433 | fn reportError( |
src/Sema.zig+2-14| ... | ... | @@ -5211,6 +5211,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5211 | 5211 | } |
| 5212 | 5212 | const c_import_pkg = Package.create( |
| 5213 | 5213 | sema.gpa, |
| 5214 | "c_import", // TODO: should we make this unique? | |
| 5214 | 5215 | null, |
| 5215 | 5216 | c_import_res.out_zig_path, |
| 5216 | 5217 | ) catch |err| switch (err) { |
| ... | ... | @@ -11663,20 +11664,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 11663 | 11664 | }, |
| 11664 | 11665 | error.PackageNotFound => { |
| 11665 | 11666 | const cur_pkg = block.getFileScope().pkg; |
| 11666 | const parent = if (cur_pkg == sema.mod.main_pkg or cur_pkg == sema.mod.root_pkg) | |
| 11667 | "root" | |
| 11668 | else if (cur_pkg.parent) |parent| blk: { | |
| 11669 | var it = parent.table.iterator(); | |
| 11670 | while (it.next()) |pkg| { | |
| 11671 | if (pkg.value_ptr.* == cur_pkg) { | |
| 11672 | break :blk pkg.key_ptr.*; | |
| 11673 | } | |
| 11674 | } | |
| 11675 | unreachable; | |
| 11676 | } else { | |
| 11677 | return sema.fail(block, operand_src, "no package named '{s}' available", .{operand}); | |
| 11678 | }; | |
| 11679 | return sema.fail(block, operand_src, "no package named '{s}' available within package '{s}'", .{ operand, parent }); | |
| 11667 | return sema.fail(block, operand_src, "no package named '{s}' available within package '{s}'", .{ operand, cur_pkg.name }); | |
| 11680 | 11668 | }, |
| 11681 | 11669 | else => { |
| 11682 | 11670 | // TODO: these errors are file system errors; make sure an update() will |
src/main.zig+15-10| ... | ... | @@ -857,6 +857,7 @@ fn buildOutputType( |
| 857 | 857 | var pkg_tree_root: Package = .{ |
| 858 | 858 | .root_src_directory = .{ .path = null, .handle = fs.cwd() }, |
| 859 | 859 | .root_src_path = &[0]u8{}, |
| 860 | .name = &[0]u8{}, | |
| 860 | 861 | }; |
| 861 | 862 | defer freePkgTree(gpa, &pkg_tree_root, false); |
| 862 | 863 | var cur_pkg: *Package = &pkg_tree_root; |
| ... | ... | @@ -947,6 +948,7 @@ fn buildOutputType( |
| 947 | 948 | |
| 948 | 949 | const new_cur_pkg = Package.create( |
| 949 | 950 | gpa, |
| 951 | pkg_name, | |
| 950 | 952 | fs.path.dirname(pkg_path), |
| 951 | 953 | fs.path.basename(pkg_path), |
| 952 | 954 | ) catch |err| { |
| ... | ... | @@ -958,7 +960,7 @@ fn buildOutputType( |
| 958 | 960 | } else if (cur_pkg.table.get(pkg_name)) |prev| { |
| 959 | 961 | fatal("unable to add package '{s}' -> '{s}': already exists as '{s}", .{ pkg_name, pkg_path, prev.root_src_path }); |
| 960 | 962 | } |
| 961 | try cur_pkg.addAndAdopt(gpa, pkg_name, new_cur_pkg); | |
| 963 | try cur_pkg.addAndAdopt(gpa, new_cur_pkg); | |
| 962 | 964 | cur_pkg = new_cur_pkg; |
| 963 | 965 | } else if (mem.eql(u8, arg, "--pkg-end")) { |
| 964 | 966 | cur_pkg = cur_pkg.parent orelse |
| ... | ... | @@ -2841,14 +2843,14 @@ fn buildOutputType( |
| 2841 | 2843 | if (main_pkg_path) |unresolved_main_pkg_path| { |
| 2842 | 2844 | const p = try introspect.resolvePath(arena, unresolved_main_pkg_path); |
| 2843 | 2845 | if (p.len == 0) { |
| 2844 | break :blk try Package.create(gpa, null, src_path); | |
| 2846 | break :blk try Package.create(gpa, "root", null, src_path); | |
| 2845 | 2847 | } else { |
| 2846 | 2848 | const rel_src_path = try fs.path.relative(arena, p, src_path); |
| 2847 | break :blk try Package.create(gpa, p, rel_src_path); | |
| 2849 | break :blk try Package.create(gpa, "root", p, rel_src_path); | |
| 2848 | 2850 | } |
| 2849 | 2851 | } else { |
| 2850 | 2852 | const root_src_dir_path = fs.path.dirname(src_path); |
| 2851 | break :blk Package.create(gpa, root_src_dir_path, fs.path.basename(src_path)) catch |err| { | |
| 2853 | break :blk Package.create(gpa, "root", root_src_dir_path, fs.path.basename(src_path)) catch |err| { | |
| 2852 | 2854 | if (root_src_dir_path) |p| { |
| 2853 | 2855 | fatal("unable to open '{s}': {s}", .{ p, @errorName(err) }); |
| 2854 | 2856 | } else { |
| ... | ... | @@ -4093,6 +4095,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 4093 | 4095 | var main_pkg: Package = .{ |
| 4094 | 4096 | .root_src_directory = zig_lib_directory, |
| 4095 | 4097 | .root_src_path = "build_runner.zig", |
| 4098 | .name = "root", | |
| 4096 | 4099 | }; |
| 4097 | 4100 | |
| 4098 | 4101 | if (!build_options.omit_pkg_fetching_code) { |
| ... | ... | @@ -4133,20 +4136,22 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 4133 | 4136 | |
| 4134 | 4137 | const deps_pkg = try Package.createFilePkg( |
| 4135 | 4138 | gpa, |
| 4139 | "@dependencies", | |
| 4136 | 4140 | local_cache_directory, |
| 4137 | 4141 | "dependencies.zig", |
| 4138 | 4142 | dependencies_source.items, |
| 4139 | 4143 | ); |
| 4140 | 4144 | |
| 4141 | 4145 | mem.swap(Package.Table, &main_pkg.table, &deps_pkg.table); |
| 4142 | try main_pkg.addAndAdopt(gpa, "@dependencies", deps_pkg); | |
| 4146 | try main_pkg.addAndAdopt(gpa, deps_pkg); | |
| 4143 | 4147 | } |
| 4144 | 4148 | |
| 4145 | 4149 | var build_pkg: Package = .{ |
| 4146 | 4150 | .root_src_directory = build_directory, |
| 4147 | 4151 | .root_src_path = build_zig_basename, |
| 4152 | .name = "@build", | |
| 4148 | 4153 | }; |
| 4149 | try main_pkg.addAndAdopt(gpa, "@build", &build_pkg); | |
| 4154 | try main_pkg.addAndAdopt(gpa, &build_pkg); | |
| 4150 | 4155 | |
| 4151 | 4156 | const comp = Compilation.create(gpa, .{ |
| 4152 | 4157 | .zig_lib_directory = zig_lib_directory, |
| ... | ... | @@ -4381,7 +4386,7 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void |
| 4381 | 4386 | .root_decl = .none, |
| 4382 | 4387 | }; |
| 4383 | 4388 | |
| 4384 | file.pkg = try Package.create(gpa, null, file.sub_file_path); | |
| 4389 | file.pkg = try Package.create(gpa, "root", null, file.sub_file_path); | |
| 4385 | 4390 | defer file.pkg.destroy(gpa); |
| 4386 | 4391 | |
| 4387 | 4392 | file.zir = try AstGen.generate(gpa, file.tree); |
| ... | ... | @@ -4592,7 +4597,7 @@ fn fmtPathFile( |
| 4592 | 4597 | .root_decl = .none, |
| 4593 | 4598 | }; |
| 4594 | 4599 | |
| 4595 | file.pkg = try Package.create(fmt.gpa, null, file.sub_file_path); | |
| 4600 | file.pkg = try Package.create(fmt.gpa, "root", null, file.sub_file_path); | |
| 4596 | 4601 | defer file.pkg.destroy(fmt.gpa); |
| 4597 | 4602 | |
| 4598 | 4603 | if (stat.size > max_src_size) |
| ... | ... | @@ -5304,7 +5309,7 @@ pub fn cmdAstCheck( |
| 5304 | 5309 | file.stat.size = source.len; |
| 5305 | 5310 | } |
| 5306 | 5311 | |
| 5307 | file.pkg = try Package.create(gpa, null, file.sub_file_path); | |
| 5312 | file.pkg = try Package.create(gpa, "root", null, file.sub_file_path); | |
| 5308 | 5313 | defer file.pkg.destroy(gpa); |
| 5309 | 5314 | |
| 5310 | 5315 | file.tree = try std.zig.parse(gpa, file.source); |
| ... | ... | @@ -5423,7 +5428,7 @@ pub fn cmdChangelist( |
| 5423 | 5428 | .root_decl = .none, |
| 5424 | 5429 | }; |
| 5425 | 5430 | |
| 5426 | file.pkg = try Package.create(gpa, null, file.sub_file_path); | |
| 5431 | file.pkg = try Package.create(gpa, "root", null, file.sub_file_path); | |
| 5427 | 5432 | defer file.pkg.destroy(gpa); |
| 5428 | 5433 | |
| 5429 | 5434 | const source = try arena.allocSentinel(u8, @intCast(usize, stat.size), 0); |
src/test.zig+1| ... | ... | @@ -1497,6 +1497,7 @@ pub const TestContext = struct { |
| 1497 | 1497 | var main_pkg: Package = .{ |
| 1498 | 1498 | .root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir }, |
| 1499 | 1499 | .root_src_path = tmp_src_path, |
| 1500 | .name = "root", | |
| 1500 | 1501 | }; |
| 1501 | 1502 | defer main_pkg.table.deinit(allocator); |
| 1502 | 1503 |