diff --git a/src/AstGen.zig b/src/AstGen.zig index 06afe48a75..3941f5a378 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -46,7 +46,7 @@ fn_block: ?*GenZir = null, fn_var_args: bool = false, /// Maps string table indexes to the first `@import` ZIR instruction /// that uses this string as the operand. -imports: std.AutoArrayHashMapUnmanaged(u32, Ast.TokenIndex) = .{}, +imports: std.AutoArrayHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .{}, /// Used for temporary storage when building payloads. scratch: std.ArrayListUnmanaged(u32) = .{}, /// Whenever a `ref` instruction is needed, it is created and saved in this @@ -86,6 +86,7 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void { Zir.Inst.Ref, Zir.Inst.Index, + Zir.NullTerminatedString, => @intFromEnum(@field(extra, field.name)), i32, @@ -1301,12 +1302,12 @@ fn fnProtoExpr( } } else false; - const param_name: u32 = if (param.name_token) |name_token| blk: { + const param_name = if (param.name_token) |name_token| blk: { if (mem.eql(u8, "_", tree.tokenSlice(name_token))) - break :blk 0; + break :blk .empty; break :blk try astgen.identAsString(name_token); - } else 0; + } else .empty; if (is_anytype) { const name_token = param.name_token orelse param.anytype_ellipsis3.?; @@ -1379,7 +1380,7 @@ fn fnProtoExpr( .param_block = block_inst, .body_gz = null, - .lib_name = 0, + .lib_name = .empty, .is_var_args = is_var_args, .is_inferred_error = false, .is_test = false, @@ -1725,7 +1726,7 @@ fn structInitExpr( var sfba = std.heap.stackFallback(256, astgen.arena); const sfba_allocator = sfba.get(); - var duplicate_names = std.AutoArrayHashMap(u32, ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator); + var duplicate_names = std.AutoArrayHashMap(Zir.NullTerminatedString, ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator); defer duplicate_names.deinit(); try duplicate_names.ensureTotalCapacity(@intCast(struct_init.ast.fields.len)); @@ -4068,10 +4069,10 @@ fn fnDecl( } } else false; - const param_name: u32 = if (param.name_token) |name_token| blk: { + const param_name: Zir.NullTerminatedString = if (param.name_token) |name_token| blk: { const name_bytes = tree.tokenSlice(name_token); if (mem.eql(u8, "_", name_bytes)) - break :blk 0; + break :blk .empty; const param_name = try astgen.identAsString(name_token); if (!is_extern) { @@ -4107,7 +4108,7 @@ fn fnDecl( } return astgen.failNode(param.type_expr, "missing parameter name", .{}); } - } else 0; + } else .empty; const param_inst = if (is_anytype) param: { const name_token = param.name_token orelse param.anytype_ellipsis3.?; @@ -4133,7 +4134,7 @@ fn fnDecl( break :param param_inst.toRef(); }; - if (param_name == 0 or is_extern) continue; + if (param_name == .empty or is_extern) continue; const sub_scope = try astgen.arena.create(Scope.LocalVal); sub_scope.* = .{ @@ -4149,16 +4150,16 @@ fn fnDecl( break :is_var_args false; }; - const lib_name: u32 = if (fn_proto.lib_name) |lib_name_token| blk: { + const lib_name = if (fn_proto.lib_name) |lib_name_token| blk: { const lib_name_str = try astgen.strLitAsString(lib_name_token); - const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len]; + const lib_name_slice = astgen.string_bytes.items[@intFromEnum(lib_name_str.index)..][0..lib_name_str.len]; if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) { return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{}); } else if (lib_name_str.len == 0) { return astgen.failTok(lib_name_token, "library name cannot be empty", .{}); } break :blk lib_name_str.index; - } else 0; + } else .empty; const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; const is_inferred_error = token_tags[maybe_bang] == .bang; @@ -4343,9 +4344,9 @@ fn fnDecl( const line_delta = decl_gz.decl_line - gz.decl_line; wip_members.appendToDecl(line_delta); } - wip_members.appendToDecl(fn_name_str_index); + wip_members.appendToDecl(@intFromEnum(fn_name_str_index)); wip_members.appendToDecl(@intFromEnum(block_inst)); - wip_members.appendToDecl(doc_comment_index); + wip_members.appendToDecl(@intFromEnum(doc_comment_index)); } fn globalVarDecl( @@ -4408,16 +4409,16 @@ fn globalVarDecl( break :blk true; } else false; - const lib_name: u32 = if (var_decl.lib_name) |lib_name_token| blk: { + const lib_name = if (var_decl.lib_name) |lib_name_token| blk: { const lib_name_str = try astgen.strLitAsString(lib_name_token); - const lib_name_slice = astgen.string_bytes.items[lib_name_str.index..][0..lib_name_str.len]; + const lib_name_slice = astgen.string_bytes.items[@intFromEnum(lib_name_str.index)..][0..lib_name_str.len]; if (mem.indexOfScalar(u8, lib_name_slice, 0) != null) { return astgen.failTok(lib_name_token, "library name cannot contain null bytes", .{}); } else if (lib_name_str.len == 0) { return astgen.failTok(lib_name_token, "library name cannot be empty", .{}); } break :blk lib_name_str.index; - } else 0; + } else .empty; const doc_comment_index = try astgen.docCommentAsString(var_decl.firstToken()); @@ -4452,7 +4453,7 @@ fn globalVarDecl( if (is_mutable) { const var_inst = try block_scope.addVar(.{ .var_type = type_inst, - .lib_name = 0, + .lib_name = .empty, .align_inst = .none, // passed via the decls data .init = init_inst, .is_extern = false, @@ -4495,9 +4496,9 @@ fn globalVarDecl( const line_delta = block_scope.decl_line - gz.decl_line; wip_members.appendToDecl(line_delta); } - wip_members.appendToDecl(name_str_index); + wip_members.appendToDecl(@intFromEnum(name_str_index)); wip_members.appendToDecl(@intFromEnum(block_inst)); - wip_members.appendToDecl(doc_comment_index); // doc_comment wip + wip_members.appendToDecl(@intFromEnum(doc_comment_index)); // doc_comment wip if (align_inst != .none) { wip_members.appendToDecl(@intFromEnum(align_inst)); } @@ -4640,7 +4641,7 @@ fn testDecl( const test_name_token = test_token + 1; const test_name_token_tag = token_tags[test_name_token]; const is_decltest = test_name_token_tag == .identifier; - const test_name: u32 = blk: { + const test_name: Zir.NullTerminatedString = blk: { if (test_name_token_tag == .string_literal) { break :blk try astgen.testNameString(test_name_token); } else if (test_name_token_tag == .identifier) { @@ -4716,7 +4717,7 @@ fn testDecl( break :blk name_str_index; } // String table index 1 has a special meaning here of test decl with no name. - break :blk 1; + break :blk .unnamed_test_decl; }; var fn_block: GenZir = .{ @@ -4766,7 +4767,7 @@ fn testDecl( .lbrace_column = lbrace_column, .param_block = block_inst, .body_gz = &fn_block, - .lib_name = 0, + .lib_name = .empty, .is_var_args = false, .is_inferred_error = false, .is_test = true, @@ -4789,10 +4790,10 @@ fn testDecl( if (is_decltest) wip_members.appendToDecl(2) // 2 here means that it is a decltest, look at doc comment for name else - wip_members.appendToDecl(test_name); + wip_members.appendToDecl(@intFromEnum(test_name)); wip_members.appendToDecl(@intFromEnum(block_inst)); if (is_decltest) - wip_members.appendToDecl(test_name) // the doc comment on a decltest represents it's name + wip_members.appendToDecl(@intFromEnum(test_name)) // the doc comment on a decltest represents it's name else wip_members.appendToDecl(0); // no doc comments on test decls } @@ -4945,7 +4946,7 @@ fn structDeclInner( var sfba = std.heap.stackFallback(256, astgen.arena); const sfba_allocator = sfba.get(); - var duplicate_names = std.AutoArrayHashMap(u32, std.ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator); + var duplicate_names = std.AutoArrayHashMap(Zir.NullTerminatedString, std.ArrayListUnmanaged(Ast.TokenIndex)).init(sfba_allocator); try duplicate_names.ensureTotalCapacity(field_count); // When there aren't errors, use this to avoid a second iteration. @@ -4968,7 +4969,7 @@ fn structDeclInner( member.convertToNonTupleLike(astgen.tree.nodes); assert(!member.ast.tuple_like); - wip_members.appendToField(field_name); + wip_members.appendToField(@intFromEnum(field_name)); const gop = try duplicate_names.getOrPut(field_name); @@ -4984,7 +4985,7 @@ fn structDeclInner( } const doc_comment_index = try astgen.docCommentAsString(member.firstToken()); - wip_members.appendToField(doc_comment_index); + wip_members.appendToField(@intFromEnum(doc_comment_index)); if (member.ast.type_expr == 0) { return astgen.failTok(member.ast.main_token, "struct field missing type", .{}); @@ -5196,10 +5197,10 @@ fn unionDeclInner( } const field_name = try astgen.identAsString(member.ast.main_token); - wip_members.appendToField(field_name); + wip_members.appendToField(@intFromEnum(field_name)); const doc_comment_index = try astgen.docCommentAsString(member.firstToken()); - wip_members.appendToField(doc_comment_index); + wip_members.appendToField(@intFromEnum(doc_comment_index)); const have_type = member.ast.type_expr != 0; const have_align = member.ast.align_expr != 0; @@ -5475,10 +5476,10 @@ fn containerDecl( assert(member.ast.align_expr == 0); const field_name = try astgen.identAsString(member.ast.main_token); - wip_members.appendToField(field_name); + wip_members.appendToField(@intFromEnum(field_name)); const doc_comment_index = try astgen.docCommentAsString(member.firstToken()); - wip_members.appendToField(doc_comment_index); + wip_members.appendToField(@intFromEnum(doc_comment_index)); const have_value = member.ast.value_expr != 0; wip_members.nextField(bits_per_field, .{have_value}); @@ -5665,7 +5666,7 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len); var fields_len: usize = 0; { - var idents: std.AutoHashMapUnmanaged(u32, Ast.TokenIndex) = .{}; + var idents: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .{}; defer idents.deinit(gpa); const error_token = main_tokens[node]; @@ -5695,9 +5696,9 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi gop.value_ptr.* = tok_i; try astgen.extra.ensureUnusedCapacity(gpa, 2); - astgen.extra.appendAssumeCapacity(str_index); + astgen.extra.appendAssumeCapacity(@intFromEnum(str_index)); const doc_comment_index = try astgen.docCommentAsString(tok_i); - astgen.extra.appendAssumeCapacity(doc_comment_index); + astgen.extra.appendAssumeCapacity(@intFromEnum(doc_comment_index)); fields_len += 1; }, .r_brace => break, @@ -6372,7 +6373,7 @@ fn whileExpr( then_scope.instructions_top = GenZir.unstacked_top; defer then_scope.unstack(); - var dbg_var_name: ?u32 = null; + var dbg_var_name: Zir.NullTerminatedString = .empty; var dbg_var_inst: Zir.Inst.Ref = undefined; var opt_payload_inst: Zir.Inst.OptionalIndex = .none; var payload_val_scope: Scope.LocalVal = undefined; @@ -6464,7 +6465,7 @@ fn whileExpr( if (opt_payload_inst.unwrap()) |payload_inst| { try then_scope.instructions.append(astgen.gpa, payload_inst); } - if (dbg_var_name) |name| try then_scope.addDbgVar(.dbg_var_val, name, dbg_var_inst); + if (dbg_var_name != .empty) try then_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst); try then_scope.instructions.append(astgen.gpa, continue_block); // This code could be improved to avoid emitting the continue expr when there // are no jumps to it. This happens when the last statement of a while body is noreturn @@ -7069,9 +7070,9 @@ fn switchExpr( const is_multi_case = case.ast.values.len > 1 or (case.ast.values.len == 1 and node_tags[case.ast.values[0]] == .switch_range); - var dbg_var_name: ?u32 = null; + var dbg_var_name: Zir.NullTerminatedString = .empty; var dbg_var_inst: Zir.Inst.Ref = undefined; - var dbg_var_tag_name: ?u32 = null; + var dbg_var_tag_name: Zir.NullTerminatedString = .empty; var dbg_var_tag_inst: Zir.Inst.Ref = undefined; var has_tag_capture = false; var capture_val_scope: Scope.LocalVal = undefined; @@ -7193,11 +7194,11 @@ fn switchExpr( defer case_scope.unstack(); try case_scope.addDbgBlockBegin(); - if (dbg_var_name) |some| { - try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst); + if (dbg_var_name != .empty) { + try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst); } - if (dbg_var_tag_name) |some| { - try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst); + if (dbg_var_tag_name != .empty) { + try case_scope.addDbgVar(.dbg_var_val, dbg_var_tag_name, dbg_var_tag_inst); } const target_expr_node = case.ast.target_expr; const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node); @@ -7858,7 +7859,7 @@ fn asmExpr( const node_tags = tree.nodes.items(.tag); const token_tags = tree.tokens.items(.tag); - const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: u32 }; + const TagAndTmpl = struct { tag: Zir.Inst.Extended, tmpl: Zir.NullTerminatedString }; const tag_and_tmpl: TagAndTmpl = switch (node_tags[full.ast.template]) { .string_literal => .{ .tag = .@"asm", @@ -7870,7 +7871,7 @@ fn asmExpr( }, else => .{ .tag = .asm_expr, - .tmpl = @intFromEnum(try comptimeExpr(gz, scope, .{ .rl = .none }, full.ast.template)), + .tmpl = @enumFromInt(@intFromEnum(try comptimeExpr(gz, scope, .{ .rl = .none }, full.ast.template))), }, }; @@ -7956,7 +7957,7 @@ fn asmExpr( if (clobber_i >= clobbers_buffer.len) { return astgen.failTok(tok_i, "too many asm clobbers", .{}); } - clobbers_buffer[clobber_i] = (try astgen.strLitAsString(tok_i)).index; + clobbers_buffer[clobber_i] = @intFromEnum((try astgen.strLitAsString(tok_i)).index); clobber_i += 1; tok_i += 1; switch (token_tags[tok_i]) { @@ -8290,7 +8291,7 @@ fn builtinCall( } const str_lit_token = main_tokens[operand_node]; const str = try astgen.strLitAsString(str_lit_token); - const str_slice = astgen.string_bytes.items[str.index..][0..str.len]; + const str_slice = astgen.string_bytes.items[@intFromEnum(str.index)..][0..str.len]; if (mem.indexOfScalar(u8, str_slice, 0) != null) { return astgen.failTok(str_lit_token, "import path cannot contain null bytes", .{}); } else if (str.len == 0) { @@ -8346,7 +8347,7 @@ fn builtinCall( // This function causes a Decl to be exported. The first parameter is not an expression, // but an identifier of the Decl to be exported. var namespace: Zir.Inst.Ref = .none; - var decl_name: u32 = 0; + var decl_name: Zir.NullTerminatedString = .empty; switch (node_tags[params[0]]) { .identifier => { const ident_token = main_tokens[params[0]]; @@ -9263,7 +9264,7 @@ const Callee = union(enum) { /// promote the lvalue to an address if the first parameter requires it. obj_ptr: Zir.Inst.Ref, /// Offset into `string_bytes`. - field_name_start: u32, + field_name_start: Zir.NullTerminatedString, }, direct: Zir.Inst.Ref, }; @@ -10529,7 +10530,7 @@ fn appendErrorNodeNotes( ) Allocator.Error!void { @setCold(true); const string_bytes = &astgen.string_bytes; - const msg: u32 = @intCast(string_bytes.items.len); + const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len); try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); const notes_index: u32 = if (notes.len != 0) blk: { const notes_start = astgen.extra.items.len; @@ -10621,7 +10622,7 @@ fn appendErrorTokNotesOff( @setCold(true); const gpa = astgen.gpa; const string_bytes = &astgen.string_bytes; - const msg: u32 = @intCast(string_bytes.items.len); + const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len); try string_bytes.writer(gpa).print(format ++ "\x00", args); const notes_index: u32 = if (notes.len != 0) blk: { const notes_start = astgen.extra.items.len; @@ -10657,7 +10658,7 @@ fn errNoteTokOff( ) Allocator.Error!u32 { @setCold(true); const string_bytes = &astgen.string_bytes; - const msg: u32 = @intCast(string_bytes.items.len); + const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len); try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); return astgen.addExtra(Zir.Inst.CompileErrors.Item{ .msg = msg, @@ -10676,7 +10677,7 @@ fn errNoteNode( ) Allocator.Error!u32 { @setCold(true); const string_bytes = &astgen.string_bytes; - const msg: u32 = @intCast(string_bytes.items.len); + const msg: Zir.NullTerminatedString = @enumFromInt(string_bytes.items.len); try string_bytes.writer(astgen.gpa).print(format ++ "\x00", args); return astgen.addExtra(Zir.Inst.CompileErrors.Item{ .msg = msg, @@ -10687,7 +10688,7 @@ fn errNoteNode( }); } -fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 { +fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !Zir.NullTerminatedString { const gpa = astgen.gpa; const string_bytes = &astgen.string_bytes; const str_index: u32 = @intCast(string_bytes.items.len); @@ -10700,19 +10701,19 @@ fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 { }); if (gop.found_existing) { string_bytes.shrinkRetainingCapacity(str_index); - return gop.key_ptr.*; + return @enumFromInt(gop.key_ptr.*); } else { gop.key_ptr.* = str_index; try string_bytes.append(gpa, 0); - return str_index; + return @enumFromInt(str_index); } } /// Adds a doc comment block to `string_bytes` by walking backwards from `end_token`. /// `end_token` must point at the first token after the last doc coment line. /// Returns 0 if no doc comment is present. -fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 { - if (end_token == 0) return 0; +fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !Zir.NullTerminatedString { + if (end_token == 0) return .empty; const token_tags = astgen.tree.tokens.items(.tag); @@ -10723,6 +10724,7 @@ fn docCommentAsString(astgen: *AstGen, end_token: Ast.TokenIndex) !u32 { } else { tok += 1; } + return docCommentAsStringFromFirst(astgen, end_token, tok); } @@ -10731,8 +10733,8 @@ fn docCommentAsStringFromFirst( astgen: *AstGen, end_token: Ast.TokenIndex, start_token: Ast.TokenIndex, -) !u32 { - if (start_token == end_token) return 0; +) !Zir.NullTerminatedString { + if (start_token == end_token) return .empty; const gpa = astgen.gpa; const string_bytes = &astgen.string_bytes; @@ -10766,15 +10768,15 @@ fn docCommentAsStringFromFirst( if (gop.found_existing) { string_bytes.shrinkRetainingCapacity(str_index); - return gop.key_ptr.*; + return @enumFromInt(gop.key_ptr.*); } else { gop.key_ptr.* = str_index; try string_bytes.append(gpa, 0); - return str_index; + return @enumFromInt(str_index); } } -const IndexSlice = struct { index: u32, len: u32 }; +const IndexSlice = struct { index: Zir.NullTerminatedString, len: u32 }; fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { const gpa = astgen.gpa; @@ -10791,7 +10793,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { if (gop.found_existing) { string_bytes.shrinkRetainingCapacity(str_index); return IndexSlice{ - .index = gop.key_ptr.*, + .index = @enumFromInt(gop.key_ptr.*), .len = @intCast(key.len), }; } else { @@ -10801,7 +10803,7 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { // be null terminated for that to work. try string_bytes.append(gpa, 0); return IndexSlice{ - .index = str_index, + .index = @enumFromInt(str_index), .len = @intCast(key.len), }; } @@ -10839,12 +10841,12 @@ fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice { const len = string_bytes.items.len - str_index; try string_bytes.append(gpa, 0); return IndexSlice{ - .index = @intCast(str_index), + .index = @enumFromInt(str_index), .len = @intCast(len), }; } -fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 { +fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !Zir.NullTerminatedString { const gpa = astgen.gpa; const string_bytes = &astgen.string_bytes; const str_index: u32 = @intCast(string_bytes.items.len); @@ -10858,7 +10860,7 @@ fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !u32 { return astgen.failTok(str_lit_token, "empty test name must be omitted", .{}); } try string_bytes.append(gpa, 0); - return str_index; + return @enumFromInt(str_index); } const Scope = struct { @@ -10933,7 +10935,7 @@ const Scope = struct { /// 0 means never discarded. discarded: Ast.TokenIndex = 0, /// String table index. - name: u32, + name: Zir.NullTerminatedString, id_cat: IdCat, }; @@ -10959,7 +10961,7 @@ const Scope = struct { /// If not, we know it can be `const`, so will emit a compile error if it is `var`. used_as_lvalue: bool = false, /// String table index. - name: u32, + name: Zir.NullTerminatedString, id_cat: IdCat, /// true means we find out during Sema whether the value is comptime. /// false means it is already known at AstGen the value is runtime-known. @@ -10985,7 +10987,7 @@ const Scope = struct { parent: *Scope, /// Maps string table index to the source location of declaration, /// for the purposes of reporting name shadowing compile errors. - decls: std.AutoHashMapUnmanaged(u32, Ast.Node.Index) = .{}, + decls: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.Node.Index) = .{}, node: Ast.Node.Index, inst: Zir.Inst.Index, @@ -11250,7 +11252,7 @@ const GenZir = struct { cc_ref: Zir.Inst.Ref, ret_ref: Zir.Inst.Ref, - lib_name: u32, + lib_name: Zir.NullTerminatedString, noalias_bits: u32, is_var_args: bool, is_inferred_error: bool, @@ -11298,7 +11300,7 @@ const GenZir = struct { } const body_len = astgen.countBodyLenAfterFixups(body); - if (args.cc_ref != .none or args.lib_name != 0 or args.is_var_args or args.is_test or + if (args.cc_ref != .none or args.lib_name != .empty or args.is_var_args or args.is_test or args.is_extern or args.align_ref != .none or args.section_ref != .none or args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline) { @@ -11322,7 +11324,7 @@ const GenZir = struct { fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) + fancyFnExprExtraLen(astgen, ret_body, ret_ref) + body_len + src_locs.len + - @intFromBool(args.lib_name != 0) + + @intFromBool(args.lib_name != .empty) + @intFromBool(args.noalias_bits != 0), ); const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.FuncFancy{ @@ -11334,7 +11336,7 @@ const GenZir = struct { .is_test = args.is_test, .is_extern = args.is_extern, .is_noinline = args.is_noinline, - .has_lib_name = args.lib_name != 0, + .has_lib_name = args.lib_name != .empty, .has_any_noalias = args.noalias_bits != 0, .has_align_ref = args.align_ref != .none, @@ -11350,8 +11352,8 @@ const GenZir = struct { .has_ret_ty_body = ret_body.len != 0, }, }); - if (args.lib_name != 0) { - astgen.extra.appendAssumeCapacity(args.lib_name); + if (args.lib_name != .empty) { + astgen.extra.appendAssumeCapacity(@intFromEnum(args.lib_name)); } const zir_datas = astgen.instructions.items(.data); @@ -11493,7 +11495,7 @@ const GenZir = struct { fn addVar(gz: *GenZir, args: struct { align_inst: Zir.Inst.Ref, - lib_name: u32, + lib_name: Zir.NullTerminatedString, var_type: Zir.Inst.Ref, init: Zir.Inst.Ref, is_extern: bool, @@ -11509,15 +11511,15 @@ const GenZir = struct { try astgen.extra.ensureUnusedCapacity( gpa, @typeInfo(Zir.Inst.ExtendedVar).Struct.fields.len + - @intFromBool(args.lib_name != 0) + + @intFromBool(args.lib_name != .empty) + @intFromBool(args.align_inst != .none) + @intFromBool(args.init != .none), ); const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedVar{ .var_type = args.var_type, }); - if (args.lib_name != 0) { - astgen.extra.appendAssumeCapacity(args.lib_name); + if (args.lib_name != .empty) { + astgen.extra.appendAssumeCapacity(@intFromEnum(args.lib_name)); } if (args.align_inst != .none) { astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_inst)); @@ -11532,7 +11534,7 @@ const GenZir = struct { .data = .{ .extended = .{ .opcode = .variable, .small = @bitCast(Zir.Inst.ExtendedVar.Small{ - .has_lib_name = args.lib_name != 0, + .has_lib_name = args.lib_name != .empty, .has_align = args.align_inst != .none, .has_init = args.init != .none, .is_extern = args.is_extern, @@ -11588,7 +11590,7 @@ const GenZir = struct { astgen.instructions.appendAssumeCapacity(.{ .tag = .int_big, .data = .{ .str = .{ - .start = @intCast(astgen.string_bytes.items.len), + .start = @enumFromInt(astgen.string_bytes.items.len), .len = @intCast(limbs.len), } }, }); @@ -11687,7 +11689,7 @@ const GenZir = struct { tag: Zir.Inst.Tag, /// Absolute token index. This function does the conversion to Decl offset. abs_tok_index: Ast.TokenIndex, - name: u32, + name: Zir.NullTerminatedString, first_doc_comment: ?Ast.TokenIndex, ) !Zir.Inst.Index { const gpa = gz.astgen.gpa; @@ -11699,7 +11701,7 @@ const GenZir = struct { const doc_comment_index = if (first_doc_comment) |first| try gz.astgen.docCommentAsStringFromFirst(abs_tok_index, first) else - 0; + .empty; const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Param{ .name = name, @@ -11847,7 +11849,7 @@ const GenZir = struct { fn addStrTok( gz: *GenZir, tag: Zir.Inst.Tag, - str_index: u32, + str_index: Zir.NullTerminatedString, /// Absolute token index. This function does the conversion to Decl offset. abs_tok_index: Ast.TokenIndex, ) !Zir.Inst.Ref { @@ -12122,7 +12124,7 @@ const GenZir = struct { tag: Zir.Inst.Extended, /// Absolute node index. This function does the conversion to offset from Decl. node: Ast.Node.Index, - asm_source: u32, + asm_source: Zir.NullTerminatedString, output_type_bits: u32, is_volatile: bool, outputs: []const Zir.Inst.Asm.Output, @@ -12441,7 +12443,7 @@ const GenZir = struct { } } - fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: u32, inst: Zir.Inst.Ref) !void { + fn addDbgVar(gz: *GenZir, tag: Zir.Inst.Tag, name: Zir.NullTerminatedString, inst: Zir.Inst.Ref) !void { if (gz.is_comptime) return; _ = try gz.add(.{ .tag = tag, .data = .{ @@ -12478,15 +12480,15 @@ const GenZir = struct { /// This can only be for short-lived references; the memory becomes invalidated /// when another string is added. -fn nullTerminatedString(astgen: AstGen, index: usize) [*:0]const u8 { - return @ptrCast(astgen.string_bytes.items[index..]); +fn nullTerminatedString(astgen: AstGen, index: Zir.NullTerminatedString) [*:0]const u8 { + return @ptrCast(astgen.string_bytes.items[@intFromEnum(index)..]); } /// Local variables shadowing detection, including function parameters. fn detectLocalShadowing( astgen: *AstGen, scope: *Scope, - ident_name: u32, + ident_name: Zir.NullTerminatedString, name_token: Ast.TokenIndex, token_bytes: []const u8, id_cat: Scope.IdCat, diff --git a/src/Autodoc.zig b/src/Autodoc.zig index 8d87b4eeff..fa6d6146eb 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -447,7 +447,7 @@ fn generateZirData(self: *Autodoc, output_dir: std.fs.Dir) !void { const Scope = struct { parent: ?*Scope, map: std.AutoHashMapUnmanaged( - u32, // index into the current file's string table (decl name) + Zir.NullTerminatedString, // index into the current file's string table (decl name) *DeclStatus, ) = .{}, @@ -464,7 +464,7 @@ const Scope = struct { /// Another reason is that in some places we use the pointer to uniquely /// refer to a decl, as we wait for it to be analyzed. This means that /// those pointers must stay stable. - pub fn resolveDeclName(self: Scope, string_table_idx: u32, file: *File, inst: Zir.Inst.OptionalIndex) *DeclStatus { + pub fn resolveDeclName(self: Scope, string_table_idx: Zir.NullTerminatedString, file: *File, inst: Zir.Inst.OptionalIndex) *DeclStatus { var cur: ?*const Scope = &self; return while (cur) |s| : (cur = s.parent) { break s.map.get(string_table_idx) orelse continue; @@ -482,7 +482,7 @@ const Scope = struct { pub fn insertDeclRef( self: *Scope, arena: std.mem.Allocator, - decl_name_index: u32, // index into the current file's string table + decl_name_index: Zir.NullTerminatedString, // index into the current file's string table decl_status: DeclStatus, ) !void { const decl_status_ptr = try arena.create(DeclStatus); @@ -1250,7 +1250,7 @@ fn walkInstruction( // @check const str = data[@intFromEnum(inst)].str; //.get(file.zir); const byte_count = str.len * @sizeOf(std.math.big.Limb); - const limb_bytes = file.zir.string_bytes[str.start..][0..byte_count]; + const limb_bytes = file.zir.string_bytes[@intFromEnum(str.start)..][0..byte_count]; const limbs = try self.arena.alloc(std.math.big.Limb, str.len); @memcpy(std.mem.sliceAsBytes(limbs)[0..limb_bytes.len], limb_bytes); @@ -2167,7 +2167,7 @@ fn walkInstruction( // present in json var sentinel: ?DocData.Expr = null; if (ptr.flags.has_sentinel) { - const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); const ref_result = try self.walkRef( file, parent_scope, @@ -2182,7 +2182,7 @@ fn walkInstruction( var @"align": ?DocData.Expr = null; if (ptr.flags.has_align) { - const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); const ref_result = try self.walkRef( file, parent_scope, @@ -2196,7 +2196,7 @@ fn walkInstruction( } var address_space: ?DocData.Expr = null; if (ptr.flags.has_addrspace) { - const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); const ref_result = try self.walkRef( file, parent_scope, @@ -2210,7 +2210,7 @@ fn walkInstruction( } const bit_start: ?DocData.Expr = null; if (ptr.flags.has_bit_range) { - const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); const ref_result = try self.walkRef( file, parent_scope, @@ -2225,7 +2225,7 @@ fn walkInstruction( var host_size: ?DocData.Expr = null; if (ptr.flags.has_bit_range) { - const ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); const ref_result = try self.walkRef( file, parent_scope, @@ -3041,10 +3041,10 @@ fn walkInstruction( ); var idx = extra.end; for (fields) |*f| { - const name = file.zir.nullTerminatedString(file.zir.extra[idx]); + const name = file.zir.nullTerminatedString(@enumFromInt(file.zir.extra[idx])); idx += 1; - const docs = file.zir.nullTerminatedString(file.zir.extra[idx]); + const docs = file.zir.nullTerminatedString(@enumFromInt(file.zir.extra[idx])); idx += 1; f.* = .{ @@ -3706,10 +3706,10 @@ fn walkInstruction( const has_value = @as(u1, @truncate(cur_bit_bag)) != 0; cur_bit_bag >>= 1; - const field_name_index = file.zir.extra[extra_index]; + const field_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; - const doc_comment_index = file.zir.extra[extra_index]; + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; const value_expr: ?DocData.Expr = if (has_value) blk: { @@ -3730,7 +3730,7 @@ fn walkInstruction( const field_name = file.zir.nullTerminatedString(field_name_index); try field_name_indexes.append(self.arena, self.ast_nodes.items.len); - const doc_comment: ?[]const u8 = if (doc_comment_index != 0) + const doc_comment: ?[]const u8 = if (doc_comment_index != .empty) file.zir.nullTerminatedString(doc_comment_index) else null; @@ -4085,10 +4085,13 @@ fn analyzeAllDecls( { var it = original_it; while (it.next()) |d| { - const decl_name_index = file.zir.extra[@intFromEnum(d.sub_index) + 5]; + const decl_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 5]); switch (decl_name_index) { - 0, 1, 2 => continue, - else => if (file.zir.string_bytes[decl_name_index] == 0) { + .empty, + .unnamed_test_decl, + .decltest, + => continue, + _ => if (file.zir.nullTerminatedString(decl_name_index).len == 0) { continue; }, } @@ -4195,31 +4198,31 @@ fn analyzeDecl( // const line = file.zir.extra[extra_index]; extra_index += 1; - const decl_name_index = file.zir.extra[extra_index]; + const decl_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; const value_index: Zir.Inst.Index = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; - const doc_comment_index = file.zir.extra[extra_index]; + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: { - const inst = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const inst: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; break :inst inst; }; _ = align_inst; const section_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: { - const inst = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const inst: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; break :inst inst; }; _ = section_inst; const addrspace_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: { - const inst = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const inst: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; break :inst inst; }; @@ -4230,9 +4233,9 @@ fn analyzeDecl( const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src); const name: []const u8 = switch (decl_name_index) { - 0, 1, 2 => unreachable, // comptime or usingnamespace decl, decltest - else => blk: { - if (file.zir.string_bytes[decl_name_index] == 0) { + .empty, .unnamed_test_decl, .decltest => unreachable, + _ => blk: { + if (decl_name_index == .empty) { // test decl unreachable; } @@ -4240,7 +4243,7 @@ fn analyzeDecl( }, }; - const doc_comment: ?[]const u8 = if (doc_comment_index != 0) + const doc_comment: ?[]const u8 = if (doc_comment_index != .empty) file.zir.nullTerminatedString(doc_comment_index) else null; @@ -4319,13 +4322,13 @@ fn analyzeUsingnamespaceDecl( const is_pub = @as(u1, @truncate(d.flags)) != 0; const value_index: Zir.Inst.Index = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 6]); - const doc_comment_index = file.zir.extra[@intFromEnum(d.sub_index) + 7]; + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 7]); // This is known to work because decl values are always block_inlines const value_pl_node = data[@intFromEnum(value_index)].pl_node; const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src); - const doc_comment: ?[]const u8 = if (doc_comment_index != 0) + const doc_comment: ?[]const u8 = if (doc_comment_index != .empty) file.zir.nullTerminatedString(doc_comment_index) else null; @@ -4379,14 +4382,14 @@ fn analyzeDecltest( const data = file.zir.instructions.items(.data); const value_index = file.zir.extra[@intFromEnum(d.sub_index) + 6]; - const decl_name_index = file.zir.extra[@intFromEnum(d.sub_index) + 7]; + const decl_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[@intFromEnum(d.sub_index) + 7]); const value_pl_node = data[value_index].pl_node; const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src); const test_source_code = try self.getBlockSource(file, parent_src, value_pl_node.src_node); - const decl_name: ?[]const u8 = if (decl_name_index != 0) + const decl_name: ?[]const u8 = if (decl_name_index != .empty) file.zir.nullTerminatedString(decl_name_index) else null; @@ -5018,7 +5021,7 @@ fn analyzeFancyFunction( .param, .param_comptime => { const pl_tok = data[@intFromEnum(param_index)].pl_tok; const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index); - const doc_comment = if (extra.data.doc_comment != 0) + const doc_comment = if (extra.data.doc_comment != .empty) file.zir.nullTerminatedString(extra.data.doc_comment) else ""; @@ -5056,13 +5059,14 @@ fn analyzeFancyFunction( var lib_name: []const u8 = ""; if (extra.data.bits.has_lib_name) { - lib_name = file.zir.nullTerminatedString(file.zir.extra[extra_index]); + const lib_name_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]); + lib_name = file.zir.nullTerminatedString(lib_name_index); extra_index += 1; } var align_index: ?usize = null; if (extra.data.bits.has_align_ref) { - const align_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const align_ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); align_index = self.exprs.items.len; _ = try self.walkRef( file, @@ -5086,7 +5090,7 @@ fn analyzeFancyFunction( var addrspace_index: ?usize = null; if (extra.data.bits.has_addrspace_ref) { - const addrspace_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const addrspace_ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); addrspace_index = self.exprs.items.len; _ = try self.walkRef( file, @@ -5110,7 +5114,7 @@ fn analyzeFancyFunction( var section_index: ?usize = null; if (extra.data.bits.has_section_ref) { - const section_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + const section_ref: Zir.Inst.Ref = @enumFromInt(file.zir.extra[extra_index]); section_index = self.exprs.items.len; _ = try self.walkRef( file, @@ -5310,7 +5314,7 @@ fn analyzeFunction( .param, .param_comptime => { const pl_tok = data[@intFromEnum(param_index)].pl_tok; const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index); - const doc_comment = if (extra.data.doc_comment != 0) + const doc_comment = if (extra.data.doc_comment != .empty) file.zir.nullTerminatedString(extra.data.doc_comment) else ""; @@ -5497,14 +5501,11 @@ fn collectUnionFieldInfo( cur_bit_bag >>= 1; _ = unused; - const field_name = file.zir.nullTerminatedString(file.zir.extra[extra_index]); + const field_name = file.zir.nullTerminatedString(@enumFromInt(file.zir.extra[extra_index])); extra_index += 1; - const doc_comment_index = file.zir.extra[extra_index]; + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; - const field_type = if (has_type) - @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])) - else - .void_type; + const field_type: Zir.Inst.Ref = if (has_type) @enumFromInt(file.zir.extra[extra_index]) else .void_type; if (has_type) extra_index += 1; if (has_align) extra_index += 1; @@ -5526,7 +5527,7 @@ fn collectUnionFieldInfo( // ast node { try field_name_indexes.append(self.arena, self.ast_nodes.items.len); - const doc_comment: ?[]const u8 = if (doc_comment_index != 0) + const doc_comment: ?[]const u8 = if (doc_comment_index != .empty) file.zir.nullTerminatedString(doc_comment_index) else null; @@ -5559,8 +5560,8 @@ fn collectStructFieldInfo( const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; const Field = struct { - field_name: ?u32, - doc_comment_index: u32, + field_name: Zir.NullTerminatedString, + doc_comment_index: Zir.NullTerminatedString, type_body_len: u32 = 0, align_body_len: u32 = 0, init_body_len: u32 = 0, @@ -5587,13 +5588,13 @@ fn collectStructFieldInfo( const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0; cur_bit_bag >>= 1; - const field_name: ?u32 = if (!is_tuple) blk: { + const field_name: Zir.NullTerminatedString = if (!is_tuple) blk: { const fname = file.zir.extra[extra_index]; extra_index += 1; - break :blk fname; - } else null; + break :blk @enumFromInt(fname); + } else .empty; - const doc_comment_index = file.zir.extra[extra_index]; + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(file.zir.extra[extra_index]); extra_index += 1; fields[field_i] = .{ @@ -5604,7 +5605,7 @@ fn collectStructFieldInfo( if (has_type_body) { fields[field_i].type_body_len = file.zir.extra[extra_index]; } else { - fields[field_i].type_ref = @as(Zir.Inst.Ref, @enumFromInt(file.zir.extra[extra_index])); + fields[field_i].type_ref = @enumFromInt(file.zir.extra[extra_index]); } extra_index += 1; @@ -5686,12 +5687,12 @@ fn collectStructFieldInfo( // ast node { try field_name_indexes.append(self.arena, self.ast_nodes.items.len); - const doc_comment: ?[]const u8 = if (field.doc_comment_index != 0) + const doc_comment: ?[]const u8 = if (field.doc_comment_index != .empty) file.zir.nullTerminatedString(field.doc_comment_index) else null; - const field_name: []const u8 = if (field.field_name) |f_name| - file.zir.nullTerminatedString(f_name) + const field_name: []const u8 = if (field.field_name != .empty) + file.zir.nullTerminatedString(field.field_name) else ""; diff --git a/src/Module.zig b/src/Module.zig index cac4543883..8f6f0e34d1 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -4198,7 +4198,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err const line_off = zir.extra[decl_sub_index + 4]; const line = iter.parent_decl.relativeToLine(line_off); - const decl_name_index = zir.extra[decl_sub_index + 5]; + const decl_name_index: Zir.NullTerminatedString = @enumFromInt(zir.extra[decl_sub_index + 5]); const decl_doccomment_index = zir.extra[decl_sub_index + 7]; const decl_zir_index = zir.extra[decl_sub_index + 6]; const decl_block_inst_data = zir.instructions.items(.data)[decl_zir_index].pl_node; @@ -4208,7 +4208,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err var is_named_test = false; var kind: Decl.Kind = .named; const decl_name: InternPool.NullTerminatedString = switch (decl_name_index) { - 0 => name: { + .empty => name: { if (export_bit) { const i = iter.usingnamespace_index; iter.usingnamespace_index += 1; @@ -4221,23 +4221,23 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err break :name try ip.getOrPutStringFmt(gpa, "comptime_{d}", .{i}); } }, - 1 => name: { + .unnamed_test_decl => name: { const i = iter.unnamed_test_index; iter.unnamed_test_index += 1; kind = .@"test"; break :name try ip.getOrPutStringFmt(gpa, "test_{d}", .{i}); }, - 2 => name: { + .decltest => name: { is_named_test = true; - const test_name = zir.nullTerminatedString(decl_doccomment_index); + const test_name = zir.nullTerminatedString(@enumFromInt(decl_doccomment_index)); kind = .@"test"; break :name try ip.getOrPutStringFmt(gpa, "decltest.{s}", .{test_name}); }, - else => name: { + _ => name: { const raw_name = zir.nullTerminatedString(decl_name_index); if (raw_name.len == 0) { is_named_test = true; - const test_name = zir.nullTerminatedString(decl_name_index + 1); + const test_name = zir.nullTerminatedString(@enumFromInt(@intFromEnum(decl_name_index) + 1)); kind = .@"test"; break :name try ip.getOrPutStringFmt(gpa, "test.{s}", .{test_name}); } else { @@ -4246,7 +4246,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err }, }; - const is_exported = export_bit and decl_name_index != 0; + const is_exported = export_bit and decl_name_index != .empty; if (kind == .@"usingnamespace") try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1); // We create a Decl for it regardless of analysis status. @@ -4271,8 +4271,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err // test decls if in test mode, get analyzed. const decl_mod = namespace.file_scope.mod; const want_analysis = is_exported or switch (decl_name_index) { - 0 => true, // comptime or usingnamespace decl - 1 => blk: { + .empty => true, // comptime or usingnamespace decl + .unnamed_test_decl => blk: { // test decl with no name. Skip the part where we check against // the test name filter. if (!comp.config.is_test) break :blk false; diff --git a/src/Sema.zig b/src/Sema.zig index f79691f6ac..a4f6f4f7bb 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3044,7 +3044,8 @@ fn zirEnumDecl( const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0; cur_bit_bag >>= 1; - const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[extra_index]); + const field_name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]); + const field_name_zir = sema.code.nullTerminatedString(field_name_index); extra_index += 1; // doc comment @@ -3322,8 +3323,8 @@ fn zirErrorSetDecl( var extra_index: u32 = @intCast(extra.end); const extra_index_end = extra_index + (extra.data.fields_len * 2); while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string - const str_index = sema.code.extra[extra_index]; - const name = sema.code.nullTerminatedString(str_index); + const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]); + const name = sema.code.nullTerminatedString(name_index); const name_ip = try mod.intern_pool.getOrPutString(gpa, name); _ = try mod.getErrorValue(name_ip); const result = names.getOrPutAssumeCapacity(name_ip); @@ -5522,7 +5523,7 @@ fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const mod = sema.mod; const int = sema.code.instructions.items(.data)[@intFromEnum(inst)].str; const byte_count = int.len * @sizeOf(std.math.big.Limb); - const limb_bytes = sema.code.string_bytes[int.start..][0..byte_count]; + const limb_bytes = sema.code.string_bytes[@intFromEnum(int.start)..][0..byte_count]; // TODO: this allocation and copy is only needed because the limbs may be unaligned. // If ZIR is adjusted so that big int limbs are guaranteed to be aligned, these @@ -7999,11 +8000,11 @@ fn instantiateGenericCall( } }, })); const param_name: Zir.NullTerminatedString = switch (param_tag) { - .param_anytype => @enumFromInt(fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start), + .param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start, .param => name: { const inst_data = fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].pl_tok; const extra = fn_zir.extraData(Zir.Inst.Param, inst_data.payload_index); - break :name @enumFromInt(extra.data.name); + break :name extra.data.name; }, else => unreachable, }; @@ -9616,7 +9617,7 @@ fn finishFunc( .param_anytype => data[@intFromEnum(param_index)].str_tok.src(), else => unreachable, }; - const name = sema.code.nullTerminatedString2(name_nts); + const name = sema.code.nullTerminatedString(name_nts); if (name.len != 0) { try sema.errNote(block, param_src, msg, "param '{s}' is required to be comptime", .{name}); } else { @@ -9690,7 +9691,7 @@ fn zirParam( const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_tok; const src = inst_data.src(); const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index); - const param_name: Zir.NullTerminatedString = @enumFromInt(extra.data.name); + const param_name: Zir.NullTerminatedString = extra.data.name; const body = sema.code.bodySlice(extra.end, extra.data.body_len); const param_ty = param_ty: { @@ -9781,7 +9782,7 @@ fn zirParamAnytype( comptime_syntax: bool, ) CompileError!void { const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; - const param_name: Zir.NullTerminatedString = @enumFromInt(inst_data.start); + const param_name: Zir.NullTerminatedString = inst_data.start; // We are evaluating a generic function without any comptime args provided. @@ -16184,7 +16185,7 @@ fn zirAsm( const is_global_assembly = sema.func_index == .none; const asm_source: []const u8 = if (tmpl_is_expr) blk: { - const tmpl: Zir.Inst.Ref = @enumFromInt(extra.data.asm_source); + const tmpl: Zir.Inst.Ref = @enumFromInt(@intFromEnum(extra.data.asm_source)); const s: []const u8 = try sema.resolveConstString(block, src, tmpl, .{ .needed_comptime_reason = "assembly code must be comptime-known", }); @@ -16272,7 +16273,8 @@ fn zirAsm( const clobbers = try sema.arena.alloc([]const u8, clobbers_len); for (clobbers) |*name| { - name.* = sema.code.nullTerminatedString(sema.code.extra[extra_i]); + const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_i]); + name.* = sema.code.nullTerminatedString(name_index); extra_i += 1; needed_capacity += name.*.len / 4 + 1; @@ -24713,7 +24715,8 @@ fn zirVarExtended( var extra_index: usize = extra.end; const lib_name = if (small.has_lib_name) lib_name: { - const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]); + const lib_name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]); + const lib_name = sema.code.nullTerminatedString(lib_name_index); extra_index += 1; try sema.handleExternLibName(block, ty_src, lib_name); break :lib_name lib_name; @@ -24781,7 +24784,8 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A var extra_index: usize = extra.end; const lib_name: ?[]const u8 = if (extra.data.bits.has_lib_name) blk: { - const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]); + const lib_name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]); + const lib_name = sema.code.nullTerminatedString(lib_name_index); extra_index += 1; break :blk lib_name; } else null; @@ -35841,7 +35845,7 @@ fn semaStructFields( var opt_field_name_zir: ?[:0]const u8 = null; if (!small.is_tuple) { - opt_field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]); + opt_field_name_zir = zir.nullTerminatedString(@enumFromInt(zir.extra[extra_index])); extra_index += 1; } extra_index += 1; // doc_comment @@ -36344,7 +36348,8 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un cur_bit_bag >>= 1; _ = unused; - const field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]); + const field_name_index: Zir.NullTerminatedString = @enumFromInt(zir.extra[extra_index]); + const field_name_zir = zir.nullTerminatedString(field_name_index); extra_index += 1; // doc_comment diff --git a/src/Zir.zig b/src/Zir.zig index 3faffabb40..1ecd8ff484 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -93,6 +93,7 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) { Inst.Ref, Inst.Index, + NullTerminatedString, => @enumFromInt(code.extra[i]), i32, @@ -112,18 +113,15 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) { }; } -/// TODO migrate to use this for type safety pub const NullTerminatedString = enum(u32) { + empty = 0, + unnamed_test_decl = 1, + decltest = 2, _, }; -/// TODO: migrate to nullTerminatedString2 for type safety -pub fn nullTerminatedString(code: Zir, index: usize) [:0]const u8 { - return nullTerminatedString2(code, @enumFromInt(index)); -} - /// Given an index into `string_bytes` returns the null-terminated string found there. -pub fn nullTerminatedString2(code: Zir, index: NullTerminatedString) [:0]const u8 { +pub fn nullTerminatedString(code: Zir, index: NullTerminatedString) [:0]const u8 { const start = @intFromEnum(index); var end: u32 = start; while (code.string_bytes[end] != 0) { @@ -2298,17 +2296,17 @@ pub const Inst = struct { /// For strings which may contain null bytes. str: struct { /// Offset into `string_bytes`. - start: u32, + start: NullTerminatedString, /// Number of bytes in the string. len: u32, pub fn get(self: @This(), code: Zir) []const u8 { - return code.string_bytes[self.start..][0..self.len]; + return code.string_bytes[@intFromEnum(self.start)..][0..self.len]; } }, str_tok: struct { /// Offset into `string_bytes`. Null-terminated. - start: u32, + start: NullTerminatedString, /// Offset from Decl AST token index. src_tok: u32, @@ -2385,7 +2383,7 @@ pub const Inst = struct { }, str_op: struct { /// Offset into `string_bytes`. Null-terminated. - str: u32, + str: NullTerminatedString, operand: Ref, pub fn getStr(self: @This(), zir: Zir) [:0]const u8 { @@ -2466,11 +2464,11 @@ pub const Inst = struct { /// Trailing: /// 0. Output for every outputs_len /// 1. Input for every inputs_len - /// 2. clobber: u32 // index into string_bytes (null terminated) for every clobbers_len. + /// 2. clobber: NullTerminatedString // index into string_bytes (null terminated) for every clobbers_len. pub const Asm = struct { src_node: i32, // null-terminated string index - asm_source: u32, + asm_source: NullTerminatedString, /// 1 bit for each outputs_len: whether it uses `-> T` or not. /// 0b0 - operand is a pointer to where to store the output. /// 0b1 - operand is a type; asm expression has the output as the result. @@ -2479,18 +2477,18 @@ pub const Inst = struct { pub const Output = struct { /// index into string_bytes (null terminated) - name: u32, + name: NullTerminatedString, /// index into string_bytes (null terminated) - constraint: u32, + constraint: NullTerminatedString, /// How to interpret this is determined by `output_type_bits`. operand: Ref, }; pub const Input = struct { /// index into string_bytes (null terminated) - name: u32, + name: NullTerminatedString, /// index into string_bytes (null terminated) - constraint: u32, + constraint: NullTerminatedString, operand: Ref, }; }; @@ -2524,7 +2522,7 @@ pub const Inst = struct { }; /// Trailing: - /// 0. lib_name: u32, // null terminated string index, if has_lib_name is set + /// 0. lib_name: NullTerminatedString, // null terminated string index, if has_lib_name is set /// if (has_align_ref and !has_align_body) { /// 1. align: Ref, /// } @@ -2598,7 +2596,7 @@ pub const Inst = struct { }; /// Trailing: - /// 0. lib_name: u32, // null terminated string index, if has_lib_name is set + /// 0. lib_name: NullTerminatedString, // null terminated string index, if has_lib_name is set /// 1. align: Ref, // if has_align is set /// 2. init: Ref // if has_init is set /// The source node is obtained from the containing `block_inline`. @@ -2672,7 +2670,7 @@ pub const Inst = struct { flags: Call.Flags, obj_ptr: Ref, /// Offset into `string_bytes`. - field_name_start: u32, + field_name_start: NullTerminatedString, }; pub const TypeOfPeer = struct { @@ -2871,7 +2869,7 @@ pub const Inst = struct { pub const Field = struct { lhs: Ref, /// Offset into `string_bytes`. - field_name_start: u32, + field_name_start: NullTerminatedString, }; pub const FieldNamed = struct { @@ -2900,7 +2898,7 @@ pub const Inst = struct { /// 7. decl: { // for every decls_len /// src_hash: [4]u32, // hash of source bytes /// line: u32, // line number of decl, relative to parent - /// name: u32, // null terminated string index + /// name: NullTerminatedString, // null terminated string index /// - 0 means comptime or usingnamespace decl. /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace /// - 1 means test decl with no name. @@ -2908,7 +2906,7 @@ pub const Inst = struct { /// - if there is a 0 byte at the position `name` indexes, it indicates /// this is a test decl, and the name starts at `name+1`. /// value: Index, - /// doc_comment: u32, 0 if no doc comment, if this is a decltest, doc_comment references the decl name in the string table + /// doc_comment: u32, .empty if no doc comment, if this is a decltest, doc_comment references the decl name in the string table /// align: Ref, // if corresponding bit is set /// link_section_or_address_space: { // if corresponding bit is set. /// link_section: Ref, @@ -2923,7 +2921,7 @@ pub const Inst = struct { /// 0bX000: whether corresponding field has a type expression /// 9. fields: { // for every fields_len /// field_name: u32, // if !is_tuple - /// doc_comment: u32, // 0 if no doc comment + /// doc_comment: NullTerminatedString, // .empty if no doc comment /// field_type: Ref, // if corresponding bit is not set. none means anytype. /// field_type_body_len: u32, // if corresponding bit is set /// align_body_len: u32, // if corresponding bit is set @@ -2996,14 +2994,14 @@ pub const Inst = struct { /// 6. decl: { // for every decls_len /// src_hash: [4]u32, // hash of source bytes /// line: u32, // line number of decl, relative to parent - /// name: u32, // null terminated string index + /// name: NullTerminatedString, // null terminated string index /// - 0 means comptime or usingnamespace decl. /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace /// - 1 means test decl with no name. /// - if there is a 0 byte at the position `name` indexes, it indicates /// this is a test decl, and the name starts at `name+1`. /// value: Index, - /// doc_comment: u32, // 0 if no doc_comment + /// doc_comment: u32, // .empty if no doc_comment /// align: Ref, // if corresponding bit is set /// link_section_or_address_space: { // if corresponding bit is set. /// link_section: Ref, @@ -3015,7 +3013,7 @@ pub const Inst = struct { /// - the bit is whether corresponding field has an value expression /// 9. fields: { // for every fields_len /// field_name: u32, - /// doc_comment: u32, // 0 if no doc_comment + /// doc_comment: u32, // .empty if no doc_comment /// value: Ref, // if corresponding bit is set /// } pub const EnumDecl = struct { @@ -3046,14 +3044,14 @@ pub const Inst = struct { /// 6. decl: { // for every decls_len /// src_hash: [4]u32, // hash of source bytes /// line: u32, // line number of decl, relative to parent - /// name: u32, // null terminated string index + /// name: NullTerminatedString, // null terminated string index /// - 0 means comptime or usingnamespace decl. /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace /// - 1 means test decl with no name. /// - if there is a 0 byte at the position `name` indexes, it indicates /// this is a test decl, and the name starts at `name+1`. /// value: Index, - /// doc_comment: u32, // 0 if no doc comment + /// doc_comment: NullTerminatedString, // .empty if no doc comment /// align: Ref, // if corresponding bit is set /// link_section_or_address_space: { // if corresponding bit is set. /// link_section: Ref, @@ -3068,8 +3066,8 @@ pub const Inst = struct { /// 0b0X00: whether corresponding field has a tag value expression /// 0bX000: unused /// 9. fields: { // for every fields_len - /// field_name: u32, // null terminated string index - /// doc_comment: u32, // 0 if no doc comment + /// field_name: NullTerminatedString, // null terminated string index + /// doc_comment: NullTerminatedString, // .empty if no doc comment /// field_type: Ref, // if corresponding bit is set /// - if none, means `anytype`. /// align: Ref, // if corresponding bit is set @@ -3108,14 +3106,14 @@ pub const Inst = struct { /// 3. decl: { // for every decls_len /// src_hash: [4]u32, // hash of source bytes /// line: u32, // line number of decl, relative to parent - /// name: u32, // null terminated string index + /// name: NullTerminatedString, // null terminated string index /// - 0 means comptime or usingnamespace decl. /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace /// - 1 means test decl with no name. /// - if there is a 0 byte at the position `name` indexes, it indicates /// this is a test decl, and the name starts at `name+1`. /// value: Index, - /// doc_comment: u32, // 0 if no doc comment, + /// doc_comment: NullTerminatedString, // .empty if no doc comment, /// align: Ref, // if corresponding bit is set /// link_section_or_address_space: { // if corresponding bit is set. /// link_section: Ref, @@ -3133,8 +3131,8 @@ pub const Inst = struct { /// Trailing: /// { // for every fields_len - /// field_name: u32 // null terminated string index - /// doc_comment: u32 // null terminated string index + /// field_name: NullTerminatedString // null terminated string index + /// doc_comment: NullTerminatedString // null terminated string index /// } pub const ErrorSetDecl = struct { fields_len: u32, @@ -3177,7 +3175,7 @@ pub const Inst = struct { pub const Item = struct { /// Null-terminated string table index. - field_name: u32, + field_name: NullTerminatedString, /// The field init expression to be used as the field value. init: Ref, }; @@ -3186,7 +3184,7 @@ pub const Inst = struct { pub const FieldType = struct { container_type: Ref, /// Offset into `string_bytes`, null terminated. - name_start: u32, + name_start: NullTerminatedString, }; pub const FieldTypeRef = struct { @@ -3266,9 +3264,9 @@ pub const Inst = struct { /// Trailing: inst: Index // for every body_len pub const Param = struct { /// Null-terminated string index. - name: u32, - /// 0 if no doc comment - doc_comment: u32, + name: NullTerminatedString, + /// Null-terminated string index. + doc_comment: NullTerminatedString, /// The body contains the type of the parameter. body_len: u32, }; @@ -3293,7 +3291,7 @@ pub const Inst = struct { /// If omitted, this is referring to a Decl via identifier, e.g. `a`. namespace: Ref, /// Null-terminated string index. - decl_name: u32, + decl_name: NullTerminatedString, options: Ref, }; @@ -3311,7 +3309,7 @@ pub const Inst = struct { /// It's a payload index of another `Item`. pub const Item = struct { /// null terminated string index - msg: u32, + msg: NullTerminatedString, node: Ast.Node.Index, /// If node is 0 then this will be populated. token: Ast.TokenIndex, @@ -3335,7 +3333,7 @@ pub const Inst = struct { pub const Item = struct { /// null terminated string index - name: u32, + name: NullTerminatedString, /// points to the import name token: Ast.TokenIndex, }; @@ -3412,7 +3410,7 @@ pub const DeclIterator = struct { const sub_index: ExtraIndex = @enumFromInt(it.extra_index); it.extra_index += 5; // src_hash(4) + line(1) - const name = it.zir.nullTerminatedString(it.zir.extra[it.extra_index]); + const name = it.zir.nullTerminatedString(@enumFromInt(it.zir.extra[it.extra_index])); it.extra_index += 3; // name(1) + value(1) + doc_comment(1) it.extra_index += @as(u1, @truncate(flags >> 2)); // align it.extra_index += @as(u1, @truncate(flags >> 3)); // link_section diff --git a/src/print_zir.zig b/src/print_zir.zig index 3f2334e18d..efa0775291 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -752,7 +752,7 @@ const Writer = struct { fn writeIntBig(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].str; const byte_count = inst_data.len * @sizeOf(std.math.big.Limb); - const limb_bytes = self.code.string_bytes[inst_data.start..][0..byte_count]; + const limb_bytes = self.code.nullTerminatedString(inst_data.start)[0..byte_count]; // limb_bytes is not aligned properly; we must allocate and copy the bytes // in order to accomplish this. const limbs = try self.gpa.alloc(std.math.big.Limb, inst_data.len); @@ -945,7 +945,7 @@ const Writer = struct { std.zig.fmtEscapes(self.code.nullTerminatedString(extra.data.name)), }); - if (extra.data.doc_comment != 0) { + if (extra.data.doc_comment != .empty) { try stream.writeAll("\n"); try self.writeDocComment(stream, extra.data.doc_comment); try stream.writeByteNTimes(' ', self.indent); @@ -1226,7 +1226,7 @@ const Writer = struct { try self.writeFlag(stream, "volatile, ", is_volatile); if (tmpl_is_expr) { - try self.writeInstRef(stream, @as(Zir.Inst.Ref, @enumFromInt(extra.data.asm_source))); + try self.writeInstRef(stream, @enumFromInt(@intFromEnum(extra.data.asm_source))); try stream.writeAll(", "); } else { const asm_source = self.code.nullTerminatedString(extra.data.asm_source); @@ -1281,7 +1281,7 @@ const Writer = struct { while (i < clobbers_len) : (i += 1) { const str_index = self.code.extra[extra_i]; extra_i += 1; - const clobber = self.code.nullTerminatedString(str_index); + const clobber = self.code.nullTerminatedString(@enumFromInt(str_index)); try stream.print("{}", .{std.zig.fmtId(clobber)}); if (i + 1 < clobbers_len) { try stream.writeAll(", "); @@ -1466,12 +1466,12 @@ const Writer = struct { const fields_per_u32 = 32 / bits_per_field; const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; const Field = struct { - doc_comment_index: u32, + doc_comment_index: Zir.NullTerminatedString, type_len: u32 = 0, align_len: u32 = 0, init_len: u32 = 0, type: Zir.Inst.Ref = .none, - name: u32, + name: Zir.NullTerminatedString, is_comptime: bool, }; const fields = try self.arena.alloc(Field, fields_len); @@ -1494,24 +1494,24 @@ const Writer = struct { const has_type_body = @as(u1, @truncate(cur_bit_bag)) != 0; cur_bit_bag >>= 1; - var field_name: u32 = 0; + var field_name_index: Zir.NullTerminatedString = .empty; if (!small.is_tuple) { - field_name = self.code.extra[extra_index]; + field_name_index = @enumFromInt(self.code.extra[extra_index]); extra_index += 1; } - const doc_comment_index = self.code.extra[extra_index]; + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]); extra_index += 1; fields[field_i] = .{ .doc_comment_index = doc_comment_index, .is_comptime = is_comptime, - .name = field_name, + .name = field_name_index, }; if (has_type_body) { fields[field_i].type_len = self.code.extra[extra_index]; } else { - fields[field_i].type = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index])); + fields[field_i].type = @enumFromInt(self.code.extra[extra_index]); } extra_index += 1; @@ -1536,7 +1536,7 @@ const Writer = struct { try self.writeDocComment(stream, field.doc_comment_index); try stream.writeByteNTimes(' ', self.indent); try self.writeFlag(stream, "comptime ", field.is_comptime); - if (field.name != 0) { + if (field.name != .empty) { const field_name = self.code.nullTerminatedString(field.name); try stream.print("{}: ", .{std.zig.fmtId(field_name)}); } else { @@ -1684,9 +1684,10 @@ const Writer = struct { _ = unused; - const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]); + const field_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]); + const field_name = self.code.nullTerminatedString(field_name_index); extra_index += 1; - const doc_comment_index = self.code.extra[extra_index]; + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]); extra_index += 1; try self.writeDocComment(stream, doc_comment_index); @@ -1756,7 +1757,7 @@ const Writer = struct { extra_index += 1; const decl_index: Zir.Inst.Index = @enumFromInt(self.code.extra[extra_index]); extra_index += 1; - const doc_comment_index = self.code.extra[extra_index]; + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]); extra_index += 1; const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: { @@ -1789,9 +1790,9 @@ const Writer = struct { try stream.writeByteNTimes(' ', self.indent); try stream.print("[{d}] decltest {s}", .{ sub_index, self.code.nullTerminatedString(doc_comment_index) }); } else { - const raw_decl_name = self.code.nullTerminatedString(decl_name_index); + const raw_decl_name = self.code.nullTerminatedString(@enumFromInt(decl_name_index)); const decl_name = if (raw_decl_name.len == 0) - self.code.nullTerminatedString(decl_name_index + 1) + self.code.nullTerminatedString(@enumFromInt(decl_name_index + 1)) else raw_decl_name; const test_str = if (raw_decl_name.len == 0) "test \"" else ""; @@ -1927,10 +1928,10 @@ const Writer = struct { const has_tag_value = @as(u1, @truncate(cur_bit_bag)) != 0; cur_bit_bag >>= 1; - const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]); + const field_name = self.code.nullTerminatedString(@enumFromInt(self.code.extra[extra_index])); extra_index += 1; - const doc_comment_index = self.code.extra[extra_index]; + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]); extra_index += 1; try self.writeDocComment(stream, doc_comment_index); @@ -2011,9 +2012,9 @@ const Writer = struct { var extra_index = @as(u32, @intCast(extra.end)); const extra_index_end = extra_index + (extra.data.fields_len * 2); while (extra_index < extra_index_end) : (extra_index += 2) { - const str_index = self.code.extra[extra_index]; - const name = self.code.nullTerminatedString(str_index); - const doc_comment_index = self.code.extra[extra_index + 1]; + const name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]); + const name = self.code.nullTerminatedString(name_index); + const doc_comment_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index + 1]); try self.writeDocComment(stream, doc_comment_index); try stream.writeByteNTimes(' ', self.indent); try stream.print("{},\n", .{std.zig.fmtId(name)}); @@ -2292,7 +2293,7 @@ const Writer = struct { var ret_ty_body: []const Zir.Inst.Index = &.{}; if (extra.data.bits.has_lib_name) { - const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]); + const lib_name = self.code.nullTerminatedString(@enumFromInt(self.code.extra[extra_index])); extra_index += 1; try stream.print("lib_name=\"{}\", ", .{std.zig.fmtEscapes(lib_name)}); } @@ -2388,7 +2389,8 @@ const Writer = struct { var extra_index: usize = extra.end; if (small.has_lib_name) { - const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]); + const lib_name_index: Zir.NullTerminatedString = @enumFromInt(self.code.extra[extra_index]); + const lib_name = self.code.nullTerminatedString(lib_name_index); extra_index += 1; try stream.print(", lib_name=\"{}\"", .{std.zig.fmtEscapes(lib_name)}); } @@ -2740,8 +2742,8 @@ const Writer = struct { } } - fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: u32) !void { - if (doc_comment_index != 0) { + fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: Zir.NullTerminatedString) !void { + if (doc_comment_index != .empty) { const doc_comment = self.code.nullTerminatedString(doc_comment_index); var it = std.mem.tokenizeScalar(u8, doc_comment, '\n'); while (it.next()) |doc_line| {