| author | |
| committer | |
| log | b9e508c410cd077d704a73418281f6d7839df241 |
| tree | 1ec79de1aebed48460a5e87170a7cbbce99c0dcd |
| parent | a483e38df62f73dc0cdadee6faf3e083094210d4 |
Reverting most of the code from the previous commits in this branch.
Will pull in the code with modifications bit by bit.7 files changed, 73 insertions(+), 158 deletions(-)
src/AstGen.zig+6-4| ... | ... | @@ -4149,12 +4149,14 @@ fn builtinCall( |
| 4149 | 4149 | }, |
| 4150 | 4150 | |
| 4151 | 4151 | .@"export" => { |
| 4152 | const target_fn = try expr(gz, scope, .none, params[0]); | |
| 4153 | // FIXME: When structs work in stage2, actually implement this correctly! | |
| 4154 | // Currently the name is always signifies Strong linkage. | |
| 4152 | // TODO: @export is supposed to be able to export things other than functions. | |
| 4153 | // Instead of `comptimeExpr` here we need `decl_ref`. | |
| 4154 | const fn_to_export = try comptimeExpr(gz, scope, .none, params[0]); | |
| 4155 | // TODO: the second parameter here is supposed to be | |
| 4156 | // `std.builtin.ExportOptions`, not a string. | |
| 4155 | 4157 | const export_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]); |
| 4156 | 4158 | _ = try gz.addPlNode(.@"export", node, zir.Inst.Bin{ |
| 4157 | .lhs = target_fn, | |
| 4159 | .lhs = fn_to_export, | |
| 4158 | 4160 | .rhs = export_name, |
| 4159 | 4161 | }); |
| 4160 | 4162 | return rvalue(gz, scope, rl, .void_value, node); |
src/Compilation.zig+35-75| ... | ... | @@ -510,11 +510,11 @@ pub const InitOptions = struct { |
| 510 | 510 | fn addPackageTableToCacheHash( |
| 511 | 511 | hash: *Cache.HashHelper, |
| 512 | 512 | arena: *std.heap.ArenaAllocator, |
| 513 | package: *Package, | |
| 513 | pkg_table: Package.Table, | |
| 514 | 514 | hash_type: union(enum) { path_bytes, files: *Cache.Manifest }, |
| 515 | 515 | ) (error{OutOfMemory} || std.os.GetCwdError)!void { |
| 516 | 516 | const allocator = &arena.allocator; |
| 517 | const pkg_table = package.table; | |
| 517 | ||
| 518 | 518 | const packages = try allocator.alloc(Package.Table.Entry, pkg_table.count()); |
| 519 | 519 | { |
| 520 | 520 | // Copy over the hashmap entries to our slice |
| ... | ... | @@ -547,8 +547,7 @@ fn addPackageTableToCacheHash( |
| 547 | 547 | }, |
| 548 | 548 | } |
| 549 | 549 | // Recurse to handle the package's dependencies |
| 550 | if (package != pkg.value) | |
| 551 | try addPackageTableToCacheHash(hash, arena, pkg.value, hash_type); | |
| 550 | try addPackageTableToCacheHash(hash, arena, pkg.value.table, hash_type); | |
| 552 | 551 | } |
| 553 | 552 | } |
| 554 | 553 | |
| ... | ... | @@ -886,7 +885,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 886 | 885 | { |
| 887 | 886 | var local_arena = std.heap.ArenaAllocator.init(gpa); |
| 888 | 887 | defer local_arena.deinit(); |
| 889 | try addPackageTableToCacheHash(&hash, &local_arena, root_pkg, .path_bytes); | |
| 888 | try addPackageTableToCacheHash(&hash, &local_arena, root_pkg.table, .path_bytes); | |
| 890 | 889 | } |
| 891 | 890 | hash.add(valgrind); |
| 892 | 891 | hash.add(single_threaded); |
| ... | ... | @@ -907,46 +906,38 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 907 | 906 | artifact_sub_dir, |
| 908 | 907 | }; |
| 909 | 908 | |
| 910 | const builtin_pkg = try Package.create(gpa, zig_cache_artifact_directory.path.?, "builtin2.zig"); | |
| 911 | ||
| 912 | const std_dir_path = try options.zig_lib_directory.join(gpa, &[_][]const u8{"std"}); | |
| 913 | defer gpa.free(std_dir_path); | |
| 914 | const start_pkg = try Package.create(gpa, std_dir_path, "start2.zig"); | |
| 915 | ||
| 916 | try root_pkg.add(gpa, "builtin", builtin_pkg); | |
| 917 | try root_pkg.add(gpa, "root", root_pkg); | |
| 918 | ||
| 919 | try start_pkg.add(gpa, "builtin", builtin_pkg); | |
| 920 | try start_pkg.add(gpa, "root", root_pkg); | |
| 921 | ||
| 922 | 909 | // TODO when we implement serialization and deserialization of incremental compilation metadata, |
| 923 | 910 | // this is where we would load it. We have open a handle to the directory where |
| 924 | 911 | // the output either already is, or will be. |
| 925 | 912 | // However we currently do not have serialization of such metadata, so for now |
| 926 | 913 | // we set up an empty Module that does the entire compilation fresh. |
| 927 | 914 | |
| 928 | if (mem.endsWith(u8, root_pkg.root_src_path, ".zir")) return error.ZirFilesUnsupported; | |
| 929 | ||
| 930 | const start_scope = ss: { | |
| 931 | const start_scope = try gpa.create(Module.Scope.File); | |
| 932 | const struct_ty = try Type.Tag.empty_struct.create( | |
| 933 | gpa, | |
| 934 | &start_scope.root_container, | |
| 935 | ); | |
| 936 | start_scope.* = .{ | |
| 937 | // TODO this is duped so it can be freed in Container.deinit | |
| 938 | .sub_file_path = try gpa.dupe(u8, start_pkg.root_src_path), | |
| 939 | .source = .{ .unloaded = {} }, | |
| 940 | .tree = undefined, | |
| 941 | .status = .never_loaded, | |
| 942 | .pkg = start_pkg, | |
| 943 | .root_container = .{ | |
| 944 | .file_scope = start_scope, | |
| 945 | .decls = .{}, | |
| 946 | .ty = struct_ty, | |
| 947 | }, | |
| 948 | }; | |
| 949 | break :ss start_scope; | |
| 915 | const root_scope = rs: { | |
| 916 | if (mem.endsWith(u8, root_pkg.root_src_path, ".zig")) { | |
| 917 | const root_scope = try gpa.create(Module.Scope.File); | |
| 918 | const struct_ty = try Type.Tag.empty_struct.create( | |
| 919 | gpa, | |
| 920 | &root_scope.root_container, | |
| 921 | ); | |
| 922 | root_scope.* = .{ | |
| 923 | // TODO this is duped so it can be freed in Container.deinit | |
| 924 | .sub_file_path = try gpa.dupe(u8, root_pkg.root_src_path), | |
| 925 | .source = .{ .unloaded = {} }, | |
| 926 | .tree = undefined, | |
| 927 | .status = .never_loaded, | |
| 928 | .pkg = root_pkg, | |
| 929 | .root_container = .{ | |
| 930 | .file_scope = root_scope, | |
| 931 | .decls = .{}, | |
| 932 | .ty = struct_ty, | |
| 933 | }, | |
| 934 | }; | |
| 935 | break :rs root_scope; | |
| 936 | } else if (mem.endsWith(u8, root_pkg.root_src_path, ".zir")) { | |
| 937 | return error.ZirFilesUnsupported; | |
| 938 | } else { | |
| 939 | unreachable; | |
| 940 | } | |
| 950 | 941 | }; |
| 951 | 942 | |
| 952 | 943 | const module = try arena.create(Module); |
| ... | ... | @@ -955,9 +946,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 955 | 946 | .gpa = gpa, |
| 956 | 947 | .comp = comp, |
| 957 | 948 | .root_pkg = root_pkg, |
| 958 | .root_scope = null, | |
| 959 | .start_pkg = start_pkg, | |
| 960 | .start_scope = start_scope, | |
| 949 | .root_scope = root_scope, | |
| 961 | 950 | .zig_cache_artifact_directory = zig_cache_artifact_directory, |
| 962 | 951 | .emit_h = options.emit_h, |
| 963 | 952 | .error_name_list = try std.ArrayListUnmanaged([]const u8).initCapacity(gpa, 1), |
| ... | ... | @@ -1359,9 +1348,9 @@ pub fn update(self: *Compilation) !void { |
| 1359 | 1348 | // TODO Detect which source files changed. |
| 1360 | 1349 | // Until then we simulate a full cache miss. Source files could have been loaded |
| 1361 | 1350 | // for any reason; to force a refresh we unload now. |
| 1362 | module.unloadFile(module.start_scope); | |
| 1351 | module.unloadFile(module.root_scope); | |
| 1363 | 1352 | module.failed_root_src_file = null; |
| 1364 | module.analyzeContainer(&module.start_scope.root_container) catch |err| switch (err) { | |
| 1353 | module.analyzeContainer(&module.root_scope.root_container) catch |err| switch (err) { | |
| 1365 | 1354 | error.AnalysisFail => { |
| 1366 | 1355 | assert(self.totalErrorCount() != 0); |
| 1367 | 1356 | }, |
| ... | ... | @@ -1422,7 +1411,7 @@ pub fn update(self: *Compilation) !void { |
| 1422 | 1411 | // to report error messages. Otherwise we unload all source files to save memory. |
| 1423 | 1412 | if (self.totalErrorCount() == 0 and !self.keep_source_files_loaded) { |
| 1424 | 1413 | if (self.bin_file.options.module) |module| { |
| 1425 | module.start_scope.unload(self.gpa); | |
| 1414 | module.root_scope.unload(self.gpa); | |
| 1426 | 1415 | } |
| 1427 | 1416 | } |
| 1428 | 1417 | } |
| ... | ... | @@ -2833,11 +2822,6 @@ fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) !void { |
| 2833 | 2822 | const source = try comp.generateBuiltinZigSource(comp.gpa); |
| 2834 | 2823 | defer comp.gpa.free(source); |
| 2835 | 2824 | try mod.zig_cache_artifact_directory.handle.writeFile("builtin.zig", source); |
| 2836 | ||
| 2837 | // FIXME: Remove builtin2.zig when stage2 can correctly generate code for builtin.zig! | |
| 2838 | const source2 = try comp.generateBuiltin2ZigSource(comp.gpa); | |
| 2839 | defer comp.gpa.free(source2); | |
| 2840 | try mod.zig_cache_artifact_directory.handle.writeFile("builtin2.zig", source2); | |
| 2841 | 2825 | } |
| 2842 | 2826 | |
| 2843 | 2827 | pub fn dump_argv(argv: []const []const u8) void { |
| ... | ... | @@ -2847,30 +2831,6 @@ pub fn dump_argv(argv: []const []const u8) void { |
| 2847 | 2831 | std.debug.print("{s}\n", .{argv[argv.len - 1]}); |
| 2848 | 2832 | } |
| 2849 | 2833 | |
| 2850 | fn generateBuiltin2ZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 { | |
| 2851 | var buffer = std.ArrayList(u8).init(allocator); | |
| 2852 | defer buffer.deinit(); | |
| 2853 | ||
| 2854 | const target = comp.getTarget(); | |
| 2855 | ||
| 2856 | try buffer.writer().print( | |
| 2857 | \\pub const link_libc = {}; | |
| 2858 | \\pub const arch = {}; | |
| 2859 | \\pub const os = {}; | |
| 2860 | \\pub const output_mode = {}; | |
| 2861 | \\pub const object_format = {}; | |
| 2862 | \\ | |
| 2863 | , .{ | |
| 2864 | comp.bin_file.options.link_libc, | |
| 2865 | @enumToInt(target.cpu.arch), | |
| 2866 | @enumToInt(target.os.tag), | |
| 2867 | @enumToInt(comp.bin_file.options.output_mode), | |
| 2868 | @enumToInt(comp.bin_file.options.object_format), | |
| 2869 | }); | |
| 2870 | ||
| 2871 | return buffer.toOwnedSlice(); | |
| 2872 | } | |
| 2873 | ||
| 2874 | 2834 | pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 { |
| 2875 | 2835 | const tracy = trace(@src()); |
| 2876 | 2836 | defer tracy.end(); |
| ... | ... | @@ -3215,7 +3175,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node |
| 3215 | 3175 | { |
| 3216 | 3176 | var local_arena = std.heap.ArenaAllocator.init(comp.gpa); |
| 3217 | 3177 | defer local_arena.deinit(); |
| 3218 | try addPackageTableToCacheHash(&man.hash, &local_arena, mod.root_pkg, .{ .files = &man }); | |
| 3178 | try addPackageTableToCacheHash(&man.hash, &local_arena, mod.root_pkg.table, .{ .files = &man }); | |
| 3219 | 3179 | } |
| 3220 | 3180 | man.hash.add(comp.bin_file.options.valgrind); |
| 3221 | 3181 | man.hash.add(comp.bin_file.options.single_threaded); |
src/Module.zig+4-11| ... | ... | @@ -35,11 +35,8 @@ comp: *Compilation, |
| 35 | 35 | zig_cache_artifact_directory: Compilation.Directory, |
| 36 | 36 | /// Pointer to externally managed resource. `null` if there is no zig file being compiled. |
| 37 | 37 | root_pkg: *Package, |
| 38 | /// This is populated when `@import("root")` is analysed. | |
| 39 | root_scope: ?*Scope.File, | |
| 40 | start_pkg: *Package, | |
| 41 | 38 | /// Module owns this resource. |
| 42 | start_scope: *Scope.File, | |
| 39 | root_scope: *Scope.File, | |
| 43 | 40 | /// It's rare for a decl to be exported, so we save memory by having a sparse map of |
| 44 | 41 | /// Decl pointers to details about them being exported. |
| 45 | 42 | /// The Export memory is owned by the `export_owners` table; the slice itself is owned by this table. |
| ... | ... | @@ -2344,9 +2341,7 @@ pub fn deinit(mod: *Module) void { |
| 2344 | 2341 | mod.export_owners.deinit(gpa); |
| 2345 | 2342 | |
| 2346 | 2343 | mod.symbol_exports.deinit(gpa); |
| 2347 | ||
| 2348 | mod.start_scope.destroy(gpa); | |
| 2349 | mod.start_pkg.destroy(gpa); | |
| 2344 | mod.root_scope.destroy(gpa); | |
| 2350 | 2345 | |
| 2351 | 2346 | var it = mod.global_error_set.iterator(); |
| 2352 | 2347 | while (it.next()) |entry| { |
| ... | ... | @@ -2518,7 +2513,6 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool { |
| 2518 | 2513 | |
| 2519 | 2514 | const block_expr = node_datas[decl_node].lhs; |
| 2520 | 2515 | _ = try AstGen.comptimeExpr(&gen_scope, &gen_scope.base, .none, block_expr); |
| 2521 | _ = try gen_scope.addBreak(.break_inline, gen_scope.break_block, .void_value); | |
| 2522 | 2516 | |
| 2523 | 2517 | const code = try gen_scope.finish(); |
| 2524 | 2518 | if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { |
| ... | ... | @@ -2863,9 +2857,8 @@ fn astgenAndSemaFn( |
| 2863 | 2857 | |
| 2864 | 2858 | _ = try AstGen.expr(&gen_scope, params_scope, .none, body_node); |
| 2865 | 2859 | |
| 2866 | const inst_tags = astgen.instructions.items(.tag); | |
| 2867 | if (inst_tags.len == 0 or | |
| 2868 | !inst_tags[inst_tags.len - 1] | |
| 2860 | if (gen_scope.instructions.items.len == 0 or | |
| 2861 | !astgen.instructions.items(.tag)[gen_scope.instructions.items.len - 1] | |
| 2869 | 2862 | .isNoReturn()) |
| 2870 | 2863 | { |
| 2871 | 2864 | // astgen uses result location semantics to coerce return operands. |
src/Package.zig+1-28| ... | ... | @@ -15,9 +15,6 @@ root_src_path: []const u8, |
| 15 | 15 | table: Table = .{}, |
| 16 | 16 | parent: ?*Package = null, |
| 17 | 17 | |
| 18 | // Used when freeing packages | |
| 19 | seen: bool = false, | |
| 20 | ||
| 21 | 18 | /// Allocate a Package. No references to the slices passed are kept. |
| 22 | 19 | pub fn create( |
| 23 | 20 | gpa: *Allocator, |
| ... | ... | @@ -58,20 +55,10 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void { |
| 58 | 55 | pkg.root_src_directory.handle.close(); |
| 59 | 56 | } |
| 60 | 57 | |
| 61 | // First we recurse into all the packages and remove packages from the tables | |
| 62 | // once we have seen it before. We do this to make sure that that | |
| 63 | // a package can only be found once in the whole tree. | |
| 64 | if (!pkg.seen) { | |
| 65 | pkg.seen = true; | |
| 66 | pkg.markSeen(gpa); | |
| 67 | } | |
| 68 | ||
| 69 | 58 | { |
| 70 | 59 | var it = pkg.table.iterator(); |
| 71 | 60 | while (it.next()) |kv| { |
| 72 | if (pkg != kv.value) { | |
| 73 | kv.value.destroy(gpa); | |
| 74 | } | |
| 61 | kv.value.destroy(gpa); | |
| 75 | 62 | gpa.free(kv.key); |
| 76 | 63 | } |
| 77 | 64 | } |
| ... | ... | @@ -80,20 +67,6 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void { |
| 80 | 67 | gpa.destroy(pkg); |
| 81 | 68 | } |
| 82 | 69 | |
| 83 | fn markSeen(pkg: *Package, gpa: *Allocator) void { | |
| 84 | var it = pkg.table.iterator(); | |
| 85 | while (it.next()) |kv| { | |
| 86 | if (pkg != kv.value) { | |
| 87 | if (kv.value.seen) { | |
| 88 | pkg.table.removeAssertDiscard(kv.key); | |
| 89 | } else { | |
| 90 | kv.value.seen = true; | |
| 91 | kv.value.markSeen(gpa); | |
| 92 | } | |
| 93 | } | |
| 94 | } | |
| 95 | } | |
| 96 | ||
| 97 | 70 | pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void { |
| 98 | 71 | try pkg.table.ensureCapacity(gpa, pkg.table.count() + 1); |
| 99 | 72 | const name_dupe = try mem.dupe(gpa, u8, name); |
src/Sema.zig+24-35| ... | ... | @@ -1345,21 +1345,18 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError! |
| 1345 | 1345 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 1346 | 1346 | const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data; |
| 1347 | 1347 | const src = inst_data.src(); |
| 1348 | const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | |
| 1349 | const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | |
| 1348 | 1350 | |
| 1349 | const target_fn = try sema.resolveInst(extra.lhs); | |
| 1350 | const target_fn_val = try sema.resolveConstValue( | |
| 1351 | block, | |
| 1352 | .{ .node_offset_builtin_call_arg0 = inst_data.src_node }, | |
| 1353 | target_fn, | |
| 1354 | ); | |
| 1355 | ||
| 1356 | const export_name = try sema.resolveConstString( | |
| 1357 | block, | |
| 1358 | .{ .node_offset_builtin_call_arg1 = inst_data.src_node }, | |
| 1359 | extra.rhs, | |
| 1360 | ); | |
| 1351 | // TODO (see corresponding TODO in AstGen) this is supposed to be a `decl_ref` | |
| 1352 | // instruction, which could reference any decl, which is then supposed to get | |
| 1353 | // exported, regardless of whether or not it is a function. | |
| 1354 | const target_fn = try sema.resolveInstConst(block, lhs_src, extra.lhs); | |
| 1355 | // TODO (see corresponding TODO in AstGen) this is supposed to be | |
| 1356 | // `std.builtin.ExportOptions`, not a string. | |
| 1357 | const export_name = try sema.resolveConstString(block, rhs_src, extra.rhs); | |
| 1361 | 1358 | |
| 1362 | const actual_fn = target_fn_val.castTag(.function).?.data; | |
| 1359 | const actual_fn = target_fn.val.castTag(.function).?.data; | |
| 1363 | 1360 | try sema.mod.analyzeExport(&block.base, src, export_name, actual_fn.owner_decl); |
| 1364 | 1361 | } |
| 1365 | 1362 | |
| ... | ... | @@ -3636,26 +3633,21 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError |
| 3636 | 3633 | const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 3637 | 3634 | const container_type = try sema.resolveType(block, lhs_src, extra.lhs); |
| 3638 | 3635 | const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs); |
| 3636 | const mod = sema.mod; | |
| 3637 | const arena = sema.arena; | |
| 3639 | 3638 | |
| 3640 | const maybe_scope = container_type.getContainerScope(); | |
| 3641 | if (maybe_scope == null) { | |
| 3642 | return sema.mod.fail( | |
| 3643 | &block.base, | |
| 3644 | src, | |
| 3645 | "expected container (struct, enum, or union), found '{}'", | |
| 3646 | .{container_type}, | |
| 3647 | ); | |
| 3639 | const container_scope = container_type.getContainerScope() orelse return mod.fail( | |
| 3640 | &block.base, | |
| 3641 | lhs_src, | |
| 3642 | "expected struct, enum, union, or opaque, found '{}'", | |
| 3643 | .{container_type}, | |
| 3644 | ); | |
| 3645 | if (mod.lookupDeclName(&container_scope.base, decl_name)) |decl| { | |
| 3646 | // TODO if !decl.is_pub and inDifferentFiles() return false | |
| 3647 | return mod.constBool(arena, src, true); | |
| 3648 | } else { | |
| 3649 | return mod.constBool(arena, src, false); | |
| 3648 | 3650 | } |
| 3649 | ||
| 3650 | const found = blk: { | |
| 3651 | for (maybe_scope.?.decls.items()) |kv| { | |
| 3652 | if (mem.eql(u8, mem.spanZ(kv.key.name), decl_name)) | |
| 3653 | break :blk true; | |
| 3654 | } | |
| 3655 | break :blk false; | |
| 3656 | }; | |
| 3657 | ||
| 3658 | return sema.mod.constBool(sema.arena, src, found); | |
| 3659 | 3651 | } |
| 3660 | 3652 | |
| 3661 | 3653 | fn zirImport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { |
| ... | ... | @@ -4699,7 +4691,7 @@ fn namedFieldPtr( |
| 4699 | 4691 | } |
| 4700 | 4692 | |
| 4701 | 4693 | // TODO this will give false positives for structs inside the root file |
| 4702 | if (container_scope.file_scope == mod.root_scope.?) { | |
| 4694 | if (container_scope.file_scope == mod.root_scope) { | |
| 4703 | 4695 | return mod.fail( |
| 4704 | 4696 | &block.base, |
| 4705 | 4697 | src, |
| ... | ... | @@ -5338,9 +5330,6 @@ fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_strin |
| 5338 | 5330 | .ty = struct_ty, |
| 5339 | 5331 | }, |
| 5340 | 5332 | }; |
| 5341 | if (mem.eql(u8, target_string, "root")) { | |
| 5342 | sema.mod.root_scope = file_scope; | |
| 5343 | } | |
| 5344 | 5333 | sema.mod.analyzeContainer(&file_scope.root_container) catch |err| switch (err) { |
| 5345 | 5334 | error.AnalysisFail => { |
| 5346 | 5335 | assert(sema.mod.comp.totalErrorCount() != 0); |
src/main.zig+1-2| ... | ... | @@ -1732,8 +1732,6 @@ fn buildOutputType( |
| 1732 | 1732 | }, |
| 1733 | 1733 | } |
| 1734 | 1734 | |
| 1735 | // This gets cleaned up, because root_pkg becomes part of the | |
| 1736 | // package table of the start_pkg. | |
| 1737 | 1735 | const root_pkg: ?*Package = if (root_src_file) |src_path| blk: { |
| 1738 | 1736 | if (main_pkg_path) |p| { |
| 1739 | 1737 | const rel_src_path = try fs.path.relative(gpa, p, src_path); |
| ... | ... | @@ -1743,6 +1741,7 @@ fn buildOutputType( |
| 1743 | 1741 | break :blk try Package.create(gpa, fs.path.dirname(src_path), fs.path.basename(src_path)); |
| 1744 | 1742 | } |
| 1745 | 1743 | } else null; |
| 1744 | defer if (root_pkg) |p| p.destroy(gpa); | |
| 1746 | 1745 | |
| 1747 | 1746 | // Transfer packages added with --pkg-begin/--pkg-end to the root package |
| 1748 | 1747 | if (root_pkg) |pkg| { |
src/zir.zig+2-3| ... | ... | @@ -328,8 +328,7 @@ pub const Inst = struct { |
| 328 | 328 | error_union_type, |
| 329 | 329 | /// `error.Foo` syntax. Uses the `str_tok` field of the Data union. |
| 330 | 330 | error_value, |
| 331 | /// Exports a function with a specified name. This can be used at comptime | |
| 332 | /// to export a function conditionally. | |
| 331 | /// Implements the `@export` builtin function. | |
| 333 | 332 | /// Uses the `pl_node` union field. Payload is `Bin`. |
| 334 | 333 | @"export", |
| 335 | 334 | /// Given a pointer to a struct or object that contains virtual fields, returns a pointer |
| ... | ... | @@ -364,7 +363,7 @@ pub const Inst = struct { |
| 364 | 363 | fn_type_cc, |
| 365 | 364 | /// Same as `fn_type_cc` but the function is variadic. |
| 366 | 365 | fn_type_cc_var_args, |
| 367 | /// Determines whether a container has a declaration matching name. | |
| 366 | /// Implements the `@hasDecl` builtin. | |
| 368 | 367 | /// Uses the `pl_node` union field. Payload is `Bin`. |
| 369 | 368 | has_decl, |
| 370 | 369 | /// `@import(operand)`. |