authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-08 11:29:31-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-08 11:29:31-07:00
logb9e508c410cd077d704a73418281f6d7839df241
tree1ec79de1aebed48460a5e87170a7cbbce99c0dcd
parenta483e38df62f73dc0cdadee6faf3e083094210d4

stage2: revert to only has_decl and export ZIR support

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,12 +4149,14 @@ fn builtinCall(
4149 },4149 },
41504150
4151 .@"export" => {4151 .@"export" => {
4152 const target_fn = try expr(gz, scope, .none, params[0]);4152 // TODO: @export is supposed to be able to export things other than functions.
4153 // FIXME: When structs work in stage2, actually implement this correctly!4153 // Instead of `comptimeExpr` here we need `decl_ref`.
4154 // Currently the name is always signifies Strong linkage.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 const export_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);4157 const export_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]);
4156 _ = try gz.addPlNode(.@"export", node, zir.Inst.Bin{4158 _ = try gz.addPlNode(.@"export", node, zir.Inst.Bin{
4157 .lhs = target_fn,4159 .lhs = fn_to_export,
4158 .rhs = export_name,4160 .rhs = export_name,
4159 });4161 });
4160 return rvalue(gz, scope, rl, .void_value, node);4162 return rvalue(gz, scope, rl, .void_value, node);
src/Compilation.zig+35-75
...@@ -510,11 +510,11 @@ pub const InitOptions = struct {...@@ -510,11 +510,11 @@ pub const InitOptions = struct {
510fn addPackageTableToCacheHash(510fn addPackageTableToCacheHash(
511 hash: *Cache.HashHelper,511 hash: *Cache.HashHelper,
512 arena: *std.heap.ArenaAllocator,512 arena: *std.heap.ArenaAllocator,
513 package: *Package,513 pkg_table: Package.Table,
514 hash_type: union(enum) { path_bytes, files: *Cache.Manifest },514 hash_type: union(enum) { path_bytes, files: *Cache.Manifest },
515) (error{OutOfMemory} || std.os.GetCwdError)!void {515) (error{OutOfMemory} || std.os.GetCwdError)!void {
516 const allocator = &arena.allocator;516 const allocator = &arena.allocator;
517 const pkg_table = package.table;517
518 const packages = try allocator.alloc(Package.Table.Entry, pkg_table.count());518 const packages = try allocator.alloc(Package.Table.Entry, pkg_table.count());
519 {519 {
520 // Copy over the hashmap entries to our slice520 // Copy over the hashmap entries to our slice
...@@ -547,8 +547,7 @@ fn addPackageTableToCacheHash(...@@ -547,8 +547,7 @@ fn addPackageTableToCacheHash(
547 },547 },
548 }548 }
549 // Recurse to handle the package's dependencies549 // Recurse to handle the package's dependencies
550 if (package != pkg.value)550 try addPackageTableToCacheHash(hash, arena, pkg.value.table, hash_type);
551 try addPackageTableToCacheHash(hash, arena, pkg.value, hash_type);
552 }551 }
553}552}
554553
...@@ -886,7 +885,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -886,7 +885,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
886 {885 {
887 var local_arena = std.heap.ArenaAllocator.init(gpa);886 var local_arena = std.heap.ArenaAllocator.init(gpa);
888 defer local_arena.deinit();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 hash.add(valgrind);890 hash.add(valgrind);
892 hash.add(single_threaded);891 hash.add(single_threaded);
...@@ -907,46 +906,38 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -907,46 +906,38 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
907 artifact_sub_dir,906 artifact_sub_dir,
908 };907 };
909908
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 // TODO when we implement serialization and deserialization of incremental compilation metadata,909 // TODO when we implement serialization and deserialization of incremental compilation metadata,
923 // this is where we would load it. We have open a handle to the directory where910 // this is where we would load it. We have open a handle to the directory where
924 // the output either already is, or will be.911 // the output either already is, or will be.
925 // However we currently do not have serialization of such metadata, so for now912 // However we currently do not have serialization of such metadata, so for now
926 // we set up an empty Module that does the entire compilation fresh.913 // we set up an empty Module that does the entire compilation fresh.
927914
928 if (mem.endsWith(u8, root_pkg.root_src_path, ".zir")) return error.ZirFilesUnsupported;915 const root_scope = rs: {
929916 if (mem.endsWith(u8, root_pkg.root_src_path, ".zig")) {
930 const start_scope = ss: {917 const root_scope = try gpa.create(Module.Scope.File);
931 const start_scope = try gpa.create(Module.Scope.File);918 const struct_ty = try Type.Tag.empty_struct.create(
932 const struct_ty = try Type.Tag.empty_struct.create(919 gpa,
933 gpa,920 &root_scope.root_container,
934 &start_scope.root_container,921 );
935 );922 root_scope.* = .{
936 start_scope.* = .{923 // TODO this is duped so it can be freed in Container.deinit
937 // TODO this is duped so it can be freed in Container.deinit924 .sub_file_path = try gpa.dupe(u8, root_pkg.root_src_path),
938 .sub_file_path = try gpa.dupe(u8, start_pkg.root_src_path),925 .source = .{ .unloaded = {} },
939 .source = .{ .unloaded = {} },926 .tree = undefined,
940 .tree = undefined,927 .status = .never_loaded,
941 .status = .never_loaded,928 .pkg = root_pkg,
942 .pkg = start_pkg,929 .root_container = .{
943 .root_container = .{930 .file_scope = root_scope,
944 .file_scope = start_scope,931 .decls = .{},
945 .decls = .{},932 .ty = struct_ty,
946 .ty = struct_ty,933 },
947 },934 };
948 };935 break :rs root_scope;
949 break :ss start_scope;936 } else if (mem.endsWith(u8, root_pkg.root_src_path, ".zir")) {
937 return error.ZirFilesUnsupported;
938 } else {
939 unreachable;
940 }
950 };941 };
951942
952 const module = try arena.create(Module);943 const module = try arena.create(Module);
...@@ -955,9 +946,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -955,9 +946,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
955 .gpa = gpa,946 .gpa = gpa,
956 .comp = comp,947 .comp = comp,
957 .root_pkg = root_pkg,948 .root_pkg = root_pkg,
958 .root_scope = null,949 .root_scope = root_scope,
959 .start_pkg = start_pkg,
960 .start_scope = start_scope,
961 .zig_cache_artifact_directory = zig_cache_artifact_directory,950 .zig_cache_artifact_directory = zig_cache_artifact_directory,
962 .emit_h = options.emit_h,951 .emit_h = options.emit_h,
963 .error_name_list = try std.ArrayListUnmanaged([]const u8).initCapacity(gpa, 1),952 .error_name_list = try std.ArrayListUnmanaged([]const u8).initCapacity(gpa, 1),
...@@ -1359,9 +1348,9 @@ pub fn update(self: *Compilation) !void {...@@ -1359,9 +1348,9 @@ pub fn update(self: *Compilation) !void {
1359 // TODO Detect which source files changed.1348 // TODO Detect which source files changed.
1360 // Until then we simulate a full cache miss. Source files could have been loaded1349 // Until then we simulate a full cache miss. Source files could have been loaded
1361 // for any reason; to force a refresh we unload now.1350 // for any reason; to force a refresh we unload now.
1362 module.unloadFile(module.start_scope);1351 module.unloadFile(module.root_scope);
1363 module.failed_root_src_file = null;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 error.AnalysisFail => {1354 error.AnalysisFail => {
1366 assert(self.totalErrorCount() != 0);1355 assert(self.totalErrorCount() != 0);
1367 },1356 },
...@@ -1422,7 +1411,7 @@ pub fn update(self: *Compilation) !void {...@@ -1422,7 +1411,7 @@ pub fn update(self: *Compilation) !void {
1422 // to report error messages. Otherwise we unload all source files to save memory.1411 // to report error messages. Otherwise we unload all source files to save memory.
1423 if (self.totalErrorCount() == 0 and !self.keep_source_files_loaded) {1412 if (self.totalErrorCount() == 0 and !self.keep_source_files_loaded) {
1424 if (self.bin_file.options.module) |module| {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,11 +2822,6 @@ fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) !void {
2833 const source = try comp.generateBuiltinZigSource(comp.gpa);2822 const source = try comp.generateBuiltinZigSource(comp.gpa);
2834 defer comp.gpa.free(source);2823 defer comp.gpa.free(source);
2835 try mod.zig_cache_artifact_directory.handle.writeFile("builtin.zig", source);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}
28422826
2843pub fn dump_argv(argv: []const []const u8) void {2827pub fn dump_argv(argv: []const []const u8) void {
...@@ -2847,30 +2831,6 @@ pub fn dump_argv(argv: []const []const u8) void {...@@ -2847,30 +2831,6 @@ pub fn dump_argv(argv: []const []const u8) void {
2847 std.debug.print("{s}\n", .{argv[argv.len - 1]});2831 std.debug.print("{s}\n", .{argv[argv.len - 1]});
2848}2832}
28492833
2850fn 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
2874pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 {2834pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) ![]u8 {
2875 const tracy = trace(@src());2835 const tracy = trace(@src());
2876 defer tracy.end();2836 defer tracy.end();
...@@ -3215,7 +3175,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node...@@ -3215,7 +3175,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
3215 {3175 {
3216 var local_arena = std.heap.ArenaAllocator.init(comp.gpa);3176 var local_arena = std.heap.ArenaAllocator.init(comp.gpa);
3217 defer local_arena.deinit();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 man.hash.add(comp.bin_file.options.valgrind);3180 man.hash.add(comp.bin_file.options.valgrind);
3221 man.hash.add(comp.bin_file.options.single_threaded);3181 man.hash.add(comp.bin_file.options.single_threaded);
src/Module.zig+4-11
...@@ -35,11 +35,8 @@ comp: *Compilation,...@@ -35,11 +35,8 @@ comp: *Compilation,
35zig_cache_artifact_directory: Compilation.Directory,35zig_cache_artifact_directory: Compilation.Directory,
36/// Pointer to externally managed resource. `null` if there is no zig file being compiled.36/// Pointer to externally managed resource. `null` if there is no zig file being compiled.
37root_pkg: *Package,37root_pkg: *Package,
38/// This is populated when `@import("root")` is analysed.
39root_scope: ?*Scope.File,
40start_pkg: *Package,
41/// Module owns this resource.38/// Module owns this resource.
42start_scope: *Scope.File,39root_scope: *Scope.File,
43/// It's rare for a decl to be exported, so we save memory by having a sparse map of40/// It's rare for a decl to be exported, so we save memory by having a sparse map of
44/// Decl pointers to details about them being exported.41/// Decl pointers to details about them being exported.
45/// The Export memory is owned by the `export_owners` table; the slice itself is owned by this table.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,9 +2341,7 @@ pub fn deinit(mod: *Module) void {
2344 mod.export_owners.deinit(gpa);2341 mod.export_owners.deinit(gpa);
23452342
2346 mod.symbol_exports.deinit(gpa);2343 mod.symbol_exports.deinit(gpa);
23472344 mod.root_scope.destroy(gpa);
2348 mod.start_scope.destroy(gpa);
2349 mod.start_pkg.destroy(gpa);
23502345
2351 var it = mod.global_error_set.iterator();2346 var it = mod.global_error_set.iterator();
2352 while (it.next()) |entry| {2347 while (it.next()) |entry| {
...@@ -2518,7 +2513,6 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {...@@ -2518,7 +2513,6 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
25182513
2519 const block_expr = node_datas[decl_node].lhs;2514 const block_expr = node_datas[decl_node].lhs;
2520 _ = try AstGen.comptimeExpr(&gen_scope, &gen_scope.base, .none, block_expr);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);
25222516
2523 const code = try gen_scope.finish();2517 const code = try gen_scope.finish();
2524 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {2518 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
...@@ -2863,9 +2857,8 @@ fn astgenAndSemaFn(...@@ -2863,9 +2857,8 @@ fn astgenAndSemaFn(
28632857
2864 _ = try AstGen.expr(&gen_scope, params_scope, .none, body_node);2858 _ = try AstGen.expr(&gen_scope, params_scope, .none, body_node);
28652859
2866 const inst_tags = astgen.instructions.items(.tag);2860 if (gen_scope.instructions.items.len == 0 or
2867 if (inst_tags.len == 0 or2861 !astgen.instructions.items(.tag)[gen_scope.instructions.items.len - 1]
2868 !inst_tags[inst_tags.len - 1]
2869 .isNoReturn())2862 .isNoReturn())
2870 {2863 {
2871 // astgen uses result location semantics to coerce return operands.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,9 +15,6 @@ root_src_path: []const u8,
15table: Table = .{},15table: Table = .{},
16parent: ?*Package = null,16parent: ?*Package = null,
1717
18// Used when freeing packages
19seen: bool = false,
20
21/// Allocate a Package. No references to the slices passed are kept.18/// Allocate a Package. No references to the slices passed are kept.
22pub fn create(19pub fn create(
23 gpa: *Allocator,20 gpa: *Allocator,
...@@ -58,20 +55,10 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {...@@ -58,20 +55,10 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {
58 pkg.root_src_directory.handle.close();55 pkg.root_src_directory.handle.close();
59 }56 }
6057
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 var it = pkg.table.iterator();59 var it = pkg.table.iterator();
71 while (it.next()) |kv| {60 while (it.next()) |kv| {
72 if (pkg != kv.value) {61 kv.value.destroy(gpa);
73 kv.value.destroy(gpa);
74 }
75 gpa.free(kv.key);62 gpa.free(kv.key);
76 }63 }
77 }64 }
...@@ -80,20 +67,6 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {...@@ -80,20 +67,6 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void {
80 gpa.destroy(pkg);67 gpa.destroy(pkg);
81}68}
8269
83fn 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
97pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void {70pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void {
98 try pkg.table.ensureCapacity(gpa, pkg.table.count() + 1);71 try pkg.table.ensureCapacity(gpa, pkg.table.count() + 1);
99 const name_dupe = try mem.dupe(gpa, u8, name);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,21 +1345,18 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!
1345 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;1345 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1346 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;1346 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
1347 const src = inst_data.src();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 };
13481350
1349 const target_fn = try sema.resolveInst(extra.lhs);1351 // TODO (see corresponding TODO in AstGen) this is supposed to be a `decl_ref`
1350 const target_fn_val = try sema.resolveConstValue(1352 // instruction, which could reference any decl, which is then supposed to get
1351 block,1353 // exported, regardless of whether or not it is a function.
1352 .{ .node_offset_builtin_call_arg0 = inst_data.src_node },1354 const target_fn = try sema.resolveInstConst(block, lhs_src, extra.lhs);
1353 target_fn,1355 // TODO (see corresponding TODO in AstGen) this is supposed to be
1354 );1356 // `std.builtin.ExportOptions`, not a string.
13551357 const export_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
1356 const export_name = try sema.resolveConstString(
1357 block,
1358 .{ .node_offset_builtin_call_arg1 = inst_data.src_node },
1359 extra.rhs,
1360 );
13611358
1362 const actual_fn = target_fn_val.castTag(.function).?.data;1359 const actual_fn = target_fn.val.castTag(.function).?.data;
1363 try sema.mod.analyzeExport(&block.base, src, export_name, actual_fn.owner_decl);1360 try sema.mod.analyzeExport(&block.base, src, export_name, actual_fn.owner_decl);
1364}1361}
13651362
...@@ -3636,26 +3633,21 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -3636,26 +3633,21 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
3636 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };3633 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
3637 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);3634 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
3638 const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs);3635 const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs);
3636 const mod = sema.mod;
3637 const arena = sema.arena;
36393638
3640 const maybe_scope = container_type.getContainerScope();3639 const container_scope = container_type.getContainerScope() orelse return mod.fail(
3641 if (maybe_scope == null) {3640 &block.base,
3642 return sema.mod.fail(3641 lhs_src,
3643 &block.base,3642 "expected struct, enum, union, or opaque, found '{}'",
3644 src,3643 .{container_type},
3645 "expected container (struct, enum, or union), found '{}'",3644 );
3646 .{container_type},3645 if (mod.lookupDeclName(&container_scope.base, decl_name)) |decl| {
3647 );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}
36603652
3661fn zirImport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {3653fn zirImport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
...@@ -4699,7 +4691,7 @@ fn namedFieldPtr(...@@ -4699,7 +4691,7 @@ fn namedFieldPtr(
4699 }4691 }
47004692
4701 // TODO this will give false positives for structs inside the root file4693 // 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 return mod.fail(4695 return mod.fail(
4704 &block.base,4696 &block.base,
4705 src,4697 src,
...@@ -5338,9 +5330,6 @@ fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_strin...@@ -5338,9 +5330,6 @@ fn analyzeImport(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, target_strin
5338 .ty = struct_ty,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 sema.mod.analyzeContainer(&file_scope.root_container) catch |err| switch (err) {5333 sema.mod.analyzeContainer(&file_scope.root_container) catch |err| switch (err) {
5345 error.AnalysisFail => {5334 error.AnalysisFail => {
5346 assert(sema.mod.comp.totalErrorCount() != 0);5335 assert(sema.mod.comp.totalErrorCount() != 0);
src/main.zig+1-2
...@@ -1732,8 +1732,6 @@ fn buildOutputType(...@@ -1732,8 +1732,6 @@ fn buildOutputType(
1732 },1732 },
1733 }1733 }
17341734
1735 // This gets cleaned up, because root_pkg becomes part of the
1736 // package table of the start_pkg.
1737 const root_pkg: ?*Package = if (root_src_file) |src_path| blk: {1735 const root_pkg: ?*Package = if (root_src_file) |src_path| blk: {
1738 if (main_pkg_path) |p| {1736 if (main_pkg_path) |p| {
1739 const rel_src_path = try fs.path.relative(gpa, p, src_path);1737 const rel_src_path = try fs.path.relative(gpa, p, src_path);
...@@ -1743,6 +1741,7 @@ fn buildOutputType(...@@ -1743,6 +1741,7 @@ fn buildOutputType(
1743 break :blk try Package.create(gpa, fs.path.dirname(src_path), fs.path.basename(src_path));1741 break :blk try Package.create(gpa, fs.path.dirname(src_path), fs.path.basename(src_path));
1744 }1742 }
1745 } else null;1743 } else null;
1744 defer if (root_pkg) |p| p.destroy(gpa);
17461745
1747 // Transfer packages added with --pkg-begin/--pkg-end to the root package1746 // Transfer packages added with --pkg-begin/--pkg-end to the root package
1748 if (root_pkg) |pkg| {1747 if (root_pkg) |pkg| {
src/zir.zig+2-3
...@@ -328,8 +328,7 @@ pub const Inst = struct {...@@ -328,8 +328,7 @@ pub const Inst = struct {
328 error_union_type,328 error_union_type,
329 /// `error.Foo` syntax. Uses the `str_tok` field of the Data union.329 /// `error.Foo` syntax. Uses the `str_tok` field of the Data union.
330 error_value,330 error_value,
331 /// Exports a function with a specified name. This can be used at comptime331 /// Implements the `@export` builtin function.
332 /// to export a function conditionally.
333 /// Uses the `pl_node` union field. Payload is `Bin`.332 /// Uses the `pl_node` union field. Payload is `Bin`.
334 @"export",333 @"export",
335 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer334 /// Given a pointer to a struct or object that contains virtual fields, returns a pointer
...@@ -364,7 +363,7 @@ pub const Inst = struct {...@@ -364,7 +363,7 @@ pub const Inst = struct {
364 fn_type_cc,363 fn_type_cc,
365 /// Same as `fn_type_cc` but the function is variadic.364 /// Same as `fn_type_cc` but the function is variadic.
366 fn_type_cc_var_args,365 fn_type_cc_var_args,
367 /// Determines whether a container has a declaration matching name.366 /// Implements the `@hasDecl` builtin.
368 /// Uses the `pl_node` union field. Payload is `Bin`.367 /// Uses the `pl_node` union field. Payload is `Bin`.
369 has_decl,368 has_decl,
370 /// `@import(operand)`.369 /// `@import(operand)`.