authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-02 14:58:27-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-02 14:58:27-07:00
log0611aa39858e6d7613cda3b3da981ff6b208a5e8
tree271d5fa44237d19d7fb4b09d21b84c939658b9ca
parent4dd724d06a99d7b82b1b1758d28aa5559550f5bb

stage2: test decls encode that they are tests in ZIR

This allows Sema to namespace them separately from function decls with the same name. Ran into this in std.math.order conflicting with a test with the same name.

4 files changed, 40 insertions(+), 7 deletions(-)

BRANCH_TODO+3
......@@ -1,3 +1,6 @@
1 * running build-exe with cached ZIR crashes
2 * implement lazy struct field resolution; don't resolve struct fields until
3 they are needed.
14 * decouple AstGen from Module, Compilation
25 * AstGen threadlocal
36 * extern "foo" for vars and for functions
src/AstGen.zig+12-1
......@@ -3197,7 +3197,7 @@ fn testDecl(
31973197 const test_token = main_tokens[node];
31983198 const str_lit_token = test_token + 1;
31993199 if (token_tags[str_lit_token] == .string_literal) {
3200 break :blk (try astgen.strLitAsString(str_lit_token)).index;
3200 break :blk try astgen.testNameString(str_lit_token);
32013201 }
32023202 // String table index 1 has a special meaning here of test decl with no name.
32033203 break :blk 1;
......@@ -7806,3 +7806,14 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !IndexSlice {
78067806 };
78077807 }
78087808}
7809
7810fn testNameString(astgen: *AstGen, str_lit_token: ast.TokenIndex) !u32 {
7811 const gpa = astgen.gpa;
7812 const string_bytes = &astgen.string_bytes;
7813 const str_index = @intCast(u32, string_bytes.items.len);
7814 const token_bytes = astgen.file.tree.tokenSlice(str_lit_token);
7815 try string_bytes.append(gpa, 0); // Indicates this is a test.
7816 try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0);
7817 try string_bytes.append(gpa, 0);
7818 return str_index;
7819}
src/Module.zig+7-2
......@@ -3817,7 +3817,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo
38173817 const decl_node = iter.parent_decl.relativeToNodeIndex(decl_block_inst_data.src_node);
38183818
38193819 // Every Decl needs a name.
3820 const decl_name: [:0]const u8 = switch (decl_name_index) {
3820 const raw_decl_name: [:0]const u8 = switch (decl_name_index) {
38213821 0 => name: {
38223822 if (is_exported) {
38233823 const i = iter.usingnamespace_index;
......@@ -3836,6 +3836,10 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo
38363836 },
38373837 else => zir.nullTerminatedString(decl_name_index),
38383838 };
3839 const decl_name = if (raw_decl_name.len != 0) raw_decl_name else name: {
3840 const test_name = zir.nullTerminatedString(decl_name_index + 1);
3841 break :name try std.fmt.allocPrintZ(gpa, "test.{s}", .{test_name});
3842 };
38393843 log.debug("scan decl {s} is_pub={}", .{ decl_name, is_pub });
38403844
38413845 // We create a Decl for it regardless of analysis status.
......@@ -3847,10 +3851,11 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo
38473851 gop.entry.value = new_decl;
38483852 // Exported decls, comptime decls, usingnamespace decls, and
38493853 // test decls if in test mode, get analyzed.
3854 const is_named_test = raw_decl_name.len == 0;
38503855 const want_analysis = is_exported or switch (decl_name_index) {
38513856 0 => true, // comptime decl
38523857 1 => mod.comp.bin_file.options.is_test, // test decl
3853 else => false, // TODO set to true for named tests when testing
3858 else => is_named_test and mod.comp.bin_file.options.is_test,
38543859 };
38553860 if (want_analysis) {
38563861 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });
src/Zir.zig+18-4
......@@ -2421,6 +2421,8 @@ pub const Inst = struct {
24212421 /// - 0 means comptime or usingnamespace decl.
24222422 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
24232423 /// - 1 means test decl with no name.
2424 /// - if there is a 0 byte at the position `name` indexes, it indicates
2425 /// this is a test decl, and the name starts at `name+1`.
24242426 /// value: Index,
24252427 /// align: Ref, // if corresponding bit is set
24262428 /// link_section: Ref, // if corresponding bit is set
......@@ -2459,6 +2461,8 @@ pub const Inst = struct {
24592461 /// - 0 means comptime or usingnamespace decl.
24602462 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
24612463 /// - 1 means test decl with no name.
2464 /// - if there is a 0 byte at the position `name` indexes, it indicates
2465 /// this is a test decl, and the name starts at `name+1`.
24622466 /// value: Index,
24632467 /// align: Ref, // if corresponding bit is set
24642468 /// link_section: Ref, // if corresponding bit is set
......@@ -2492,6 +2496,8 @@ pub const Inst = struct {
24922496 /// - 0 means comptime or usingnamespace decl.
24932497 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
24942498 /// - 1 means test decl with no name.
2499 /// - if there is a 0 byte at the position `name` indexes, it indicates
2500 /// this is a test decl, and the name starts at `name+1`.
24952501 /// value: Index,
24962502 /// align: Ref, // if corresponding bit is set
24972503 /// link_section: Ref, // if corresponding bit is set
......@@ -2535,8 +2541,9 @@ pub const Inst = struct {
25352541 /// - 0 means comptime or usingnamespace decl.
25362542 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
25372543 /// - 1 means test decl with no name.
2544 /// - if there is a 0 byte at the position `name` indexes, it indicates
2545 /// this is a test decl, and the name starts at `name+1`.
25382546 /// value: Index,
2539 /// - one of: block_inline
25402547 /// align: Ref, // if corresponding bit is set
25412548 /// link_section: Ref, // if corresponding bit is set
25422549 /// }
......@@ -3631,7 +3638,6 @@ const Writer = struct {
36313638 const line = self.code.extra[extra_index];
36323639 extra_index += 1;
36333640 const decl_name_index = self.code.extra[extra_index];
3634 const decl_name = self.code.nullTerminatedString(decl_name_index);
36353641 extra_index += 1;
36363642 const decl_index = self.code.extra[extra_index];
36373643 extra_index += 1;
......@@ -3653,10 +3659,18 @@ const Writer = struct {
36533659 const name = if (is_exported) "usingnamespace" else "comptime";
36543660 try stream.writeAll(pub_str);
36553661 try stream.writeAll(name);
3662 } else if (decl_name_index == 1) {
3663 try stream.writeAll("test");
36563664 } else {
3665 const raw_decl_name = self.code.nullTerminatedString(decl_name_index);
3666 const decl_name = if (raw_decl_name.len == 0)
3667 self.code.nullTerminatedString(decl_name_index + 1)
3668 else
3669 raw_decl_name;
3670 const test_str = if (raw_decl_name.len == 0) "test " else "";
36573671 const export_str = if (is_exported) "export " else "";
3658 try stream.print("{s}{s}{}", .{
3659 pub_str, export_str, std.zig.fmtId(decl_name),
3672 try stream.print("{s}{s}{s}{}", .{
3673 pub_str, test_str, export_str, std.zig.fmtId(decl_name),
36603674 });
36613675 if (align_inst != .none) {
36623676 try stream.writeAll(" align(");