Skip to content

Commit

Permalink
Merge pull request ziglang#20299 from mlugg/the-great-decl-split
Browse files Browse the repository at this point in the history
The Great Decl Split (preliminary work): refactor source locations and eliminate `Sema.Block.src_decl`.
  • Loading branch information
mlugg authored Jun 20, 2024
2 parents ccd3cc3 + 2b677d1 commit f73be12
Show file tree
Hide file tree
Showing 34 changed files with 2,991 additions and 3,346 deletions.
373 changes: 0 additions & 373 deletions lib/std/zig.zig

Large diffs are not rendered by default.

44 changes: 32 additions & 12 deletions lib/std/zig/AstGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4011,7 +4011,7 @@ fn fnDecl(

// We insert this at the beginning so that its instruction index marks the
// start of the top level declaration.
const decl_inst = try gz.makeBlockInst(.declaration, fn_proto.ast.proto_node);
const decl_inst = try gz.makeDeclaration(fn_proto.ast.proto_node);
astgen.advanceSourceCursorToNode(decl_node);

var decl_gz: GenZir = .{
Expand Down Expand Up @@ -4393,7 +4393,7 @@ fn globalVarDecl(
const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var;
// We do this at the beginning so that the instruction index marks the range start
// of the top level declaration.
const decl_inst = try gz.makeBlockInst(.declaration, node);
const decl_inst = try gz.makeDeclaration(node);

const name_token = var_decl.ast.mut_token + 1;
astgen.advanceSourceCursorToNode(node);
Expand Down Expand Up @@ -4555,7 +4555,7 @@ fn comptimeDecl(

// Up top so the ZIR instruction index marks the start range of this
// top-level declaration.
const decl_inst = try gz.makeBlockInst(.declaration, node);
const decl_inst = try gz.makeDeclaration(node);
wip_members.nextDecl(decl_inst);
astgen.advanceSourceCursorToNode(node);

Expand Down Expand Up @@ -4607,7 +4607,7 @@ fn usingnamespaceDecl(
};
// Up top so the ZIR instruction index marks the start range of this
// top-level declaration.
const decl_inst = try gz.makeBlockInst(.declaration, node);
const decl_inst = try gz.makeDeclaration(node);
wip_members.nextDecl(decl_inst);
astgen.advanceSourceCursorToNode(node);

Expand Down Expand Up @@ -4651,7 +4651,7 @@ fn testDecl(

// Up top so the ZIR instruction index marks the start range of this
// top-level declaration.
const decl_inst = try gz.makeBlockInst(.declaration, node);
const decl_inst = try gz.makeDeclaration(node);

wip_members.nextDecl(decl_inst);
astgen.advanceSourceCursorToNode(node);
Expand Down Expand Up @@ -9366,9 +9366,10 @@ fn builtinCall(
try gz.instructions.ensureUnusedCapacity(gpa, 1);
try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);

const payload_index = try gz.astgen.addExtra(Zir.Inst.UnNode{
.node = gz.nodeIndexToRelative(node),
const payload_index = try gz.astgen.addExtra(Zir.Inst.Reify{
.node = node, // Absolute node index -- see the definition of `Reify`.
.operand = operand,
.src_line = astgen.source_line,
});
const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len);
gz.astgen.instructions.appendAssumeCapacity(.{
Expand Down Expand Up @@ -13076,6 +13077,21 @@ const GenZir = struct {
return new_index;
}

/// Note that this returns a `Zir.Inst.Index` not a ref.
/// Does *not* append the block instruction to the scope.
/// Leaves the `payload_index` field undefined. Use `setDeclaration` to finalize.
fn makeDeclaration(gz: *GenZir, node: Ast.Node.Index) !Zir.Inst.Index {
const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len);
try gz.astgen.instructions.append(gz.astgen.gpa, .{
.tag = .declaration,
.data = .{ .declaration = .{
.src_node = node,
.payload_index = undefined,
} },
});
return new_index;
}

/// Note that this returns a `Zir.Inst.Index` not a ref.
/// Leaves the `payload_index` field undefined.
fn addCondBr(gz: *GenZir, tag: Zir.Inst.Tag, node: Ast.Node.Index) !Zir.Inst.Index {
Expand Down Expand Up @@ -13122,7 +13138,8 @@ const GenZir = struct {
.fields_hash_1 = fields_hash_arr[1],
.fields_hash_2 = fields_hash_arr[2],
.fields_hash_3 = fields_hash_arr[3],
.src_node = gz.nodeIndexToRelative(args.src_node),
.src_line = astgen.source_line,
.src_node = args.src_node,
});

if (args.captures_len != 0) {
Expand Down Expand Up @@ -13182,7 +13199,8 @@ const GenZir = struct {
.fields_hash_1 = fields_hash_arr[1],
.fields_hash_2 = fields_hash_arr[2],
.fields_hash_3 = fields_hash_arr[3],
.src_node = gz.nodeIndexToRelative(args.src_node),
.src_line = astgen.source_line,
.src_node = args.src_node,
});

if (args.tag_type != .none) {
Expand Down Expand Up @@ -13243,7 +13261,8 @@ const GenZir = struct {
.fields_hash_1 = fields_hash_arr[1],
.fields_hash_2 = fields_hash_arr[2],
.fields_hash_3 = fields_hash_arr[3],
.src_node = gz.nodeIndexToRelative(args.src_node),
.src_line = astgen.source_line,
.src_node = args.src_node,
});

if (args.tag_type != .none) {
Expand Down Expand Up @@ -13291,7 +13310,8 @@ const GenZir = struct {

try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).Struct.fields.len + 2);
const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.OpaqueDecl{
.src_node = gz.nodeIndexToRelative(args.src_node),
.src_line = astgen.source_line,
.src_node = args.src_node,
});

if (args.captures_len != 0) {
Expand Down Expand Up @@ -13902,7 +13922,7 @@ fn setDeclaration(
.has_align_linksection_addrspace = align_len != 0 or linksection_len != 0 or addrspace_len != 0,
},
};
astgen.instructions.items(.data)[@intFromEnum(decl_inst)].pl_node.payload_index = try astgen.addExtra(extra);
astgen.instructions.items(.data)[@intFromEnum(decl_inst)].declaration.payload_index = try astgen.addExtra(extra);
if (extra.flags.has_doc_comment) {
try astgen.extra.append(gpa, @intFromEnum(true_doc_comment));
}
Expand Down
97 changes: 32 additions & 65 deletions lib/std/zig/Zir.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const BigIntMutable = std.math.big.int.Mutable;
const Ast = std.zig.Ast;

const Zir = @This();
const LazySrcLoc = std.zig.LazySrcLoc;

instructions: std.MultiArrayList(Inst).Slice,
/// In order to store references to strings in fewer bytes, we copy all
Expand Down Expand Up @@ -287,7 +286,7 @@ pub const Inst = struct {
/// namespace type, e.g. within a `struct_decl` instruction. It represents a
/// single source declaration (`const`/`var`/`fn`), containing the name,
/// attributes, type, and value of the declaration.
/// Uses the `pl_node` union field. Payload is `Declaration`.
/// Uses the `declaration` union field. Payload is `Declaration`.
declaration,
/// Implements `suspend {...}`.
/// Uses the `pl_node` union field. Payload is `Block`.
Expand Down Expand Up @@ -1596,7 +1595,7 @@ pub const Inst = struct {
.block = .pl_node,
.block_comptime = .pl_node,
.block_inline = .pl_node,
.declaration = .pl_node,
.declaration = .declaration,
.suspend_block = .pl_node,
.bool_not = .un_node,
.bool_br_and = .pl_node,
Expand Down Expand Up @@ -1982,7 +1981,7 @@ pub const Inst = struct {
/// `operand` is payload index to `UnNode`.
error_from_int,
/// Implement builtin `@Type`.
/// `operand` is payload index to `UnNode`.
/// `operand` is payload index to `Reify`.
/// `small` contains `NameStrategy`.
reify,
/// Implements the `@asyncCall` builtin.
Expand Down Expand Up @@ -2221,21 +2220,13 @@ pub const Inst = struct {
src_node: i32,
/// The meaning of this operand depends on the corresponding `Tag`.
operand: Ref,

pub fn src(self: @This()) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
},
/// Used for unary operators, with a token source location.
un_tok: struct {
/// Offset from Decl AST token index.
src_tok: Ast.TokenIndex,
/// The meaning of this operand depends on the corresponding `Tag`.
operand: Ref,

pub fn src(self: @This()) LazySrcLoc {
return .{ .token_offset = self.src_tok };
}
},
pl_node: struct {
/// Offset from Decl AST node index.
Expand All @@ -2244,21 +2235,13 @@ pub const Inst = struct {
/// index into extra.
/// `Tag` determines what lives there.
payload_index: u32,

pub fn src(self: @This()) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
},
pl_tok: struct {
/// Offset from Decl AST token index.
src_tok: Ast.TokenIndex,
/// index into extra.
/// `Tag` determines what lives there.
payload_index: u32,

pub fn src(self: @This()) LazySrcLoc {
return .{ .token_offset = self.src_tok };
}
},
bin: Bin,
/// For strings which may contain null bytes.
Expand All @@ -2281,10 +2264,6 @@ pub const Inst = struct {
pub fn get(self: @This(), code: Zir) [:0]const u8 {
return code.nullTerminatedString(self.start);
}

pub fn src(self: @This()) LazySrcLoc {
return .{ .token_offset = self.src_tok };
}
},
/// Offset from Decl AST token index.
tok: Ast.TokenIndex,
Expand Down Expand Up @@ -2313,19 +2292,11 @@ pub const Inst = struct {
src_node: i32,
signedness: std.builtin.Signedness,
bit_count: u16,

pub fn src(self: @This()) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
},
@"unreachable": struct {
/// Offset from Decl AST node index.
/// `Tag` determines which kind of AST node this points to.
src_node: i32,

pub fn src(self: @This()) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
},
@"break": struct {
operand: Ref,
Expand All @@ -2339,10 +2310,6 @@ pub const Inst = struct {
src_node: i32,
/// The meaning of this operand depends on the corresponding `Tag`.
inst: Index,

pub fn src(self: @This()) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
},
str_op: struct {
/// Offset into `string_bytes`. Null-terminated.
Expand Down Expand Up @@ -2370,6 +2337,12 @@ pub const Inst = struct {
/// The index being accessed.
idx: u32,
},
declaration: struct {
/// This node provides a new absolute baseline node for all instructions within this struct.
src_node: Ast.Node.Index,
/// index into extra to a `Declaration` payload.
payload_index: u32,
},

// Make sure we don't accidentally add a field to make this union
// bigger than expected. Note that in Debug builds, Zig is allowed
Expand Down Expand Up @@ -2408,6 +2381,7 @@ pub const Inst = struct {
defer_err_code,
save_err_ret_index,
elem_val_imm,
declaration,
};
};

Expand Down Expand Up @@ -2860,6 +2834,14 @@ pub const Inst = struct {
index: u32,
};

pub const Reify = struct {
/// This node is absolute, because `reify` instructions are tracked across updates, and
/// this simplifies the logic for getting source locations for types.
node: Ast.Node.Index,
operand: Ref,
src_line: u32,
};

pub const SwitchBlockErrUnion = struct {
operand: Ref,
bits: Bits,
Expand Down Expand Up @@ -3018,11 +3000,9 @@ pub const Inst = struct {
fields_hash_1: u32,
fields_hash_2: u32,
fields_hash_3: u32,
src_node: i32,

pub fn src(self: StructDecl) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
src_line: u32,
/// This node provides a new absolute baseline node for all instructions within this struct.
src_node: Ast.Node.Index,

pub const Small = packed struct {
has_captures_len: bool,
Expand Down Expand Up @@ -3150,11 +3130,9 @@ pub const Inst = struct {
fields_hash_1: u32,
fields_hash_2: u32,
fields_hash_3: u32,
src_node: i32,

pub fn src(self: EnumDecl) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
src_line: u32,
/// This node provides a new absolute baseline node for all instructions within this struct.
src_node: Ast.Node.Index,

pub const Small = packed struct {
has_tag_type: bool,
Expand Down Expand Up @@ -3198,11 +3176,9 @@ pub const Inst = struct {
fields_hash_1: u32,
fields_hash_2: u32,
fields_hash_3: u32,
src_node: i32,

pub fn src(self: UnionDecl) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
src_line: u32,
/// This node provides a new absolute baseline node for all instructions within this struct.
src_node: Ast.Node.Index,

pub const Small = packed struct {
has_tag_type: bool,
Expand Down Expand Up @@ -3230,11 +3206,9 @@ pub const Inst = struct {
/// 2. capture: Capture, // for every captures_len
/// 3. decl: Index, // for every decls_len; points to a `declaration` instruction
pub const OpaqueDecl = struct {
src_node: i32,

pub fn src(self: OpaqueDecl) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
src_line: u32,
/// This node provides a new absolute baseline node for all instructions within this struct.
src_node: Ast.Node.Index,

pub const Small = packed struct {
has_captures_len: bool,
Expand Down Expand Up @@ -3352,10 +3326,6 @@ pub const Inst = struct {
parent_ptr_type: Ref,
field_name: Ref,
field_ptr: Ref,

pub fn src(self: FieldParentPtr) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
};

pub const Shuffle = struct {
Expand Down Expand Up @@ -3505,10 +3475,6 @@ pub const Inst = struct {
block: Ref,
/// If `.none`, restore unconditionally.
operand: Ref,

pub fn src(self: RestoreErrRetIndex) LazySrcLoc {
return LazySrcLoc.nodeOffset(self.src_node);
}
};
};

Expand Down Expand Up @@ -3772,6 +3738,7 @@ fn findDeclsInner(
.union_decl,
.enum_decl,
.opaque_decl,
.reify,
=> return list.append(inst),

else => return,
Expand Down Expand Up @@ -4046,7 +4013,7 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {

pub fn getDeclaration(zir: Zir, inst: Zir.Inst.Index) struct { Inst.Declaration, u32 } {
assert(zir.instructions.items(.tag)[@intFromEnum(inst)] == .declaration);
const pl_node = zir.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const pl_node = zir.instructions.items(.data)[@intFromEnum(inst)].declaration;
const extra = zir.extraData(Inst.Declaration, pl_node.payload_index);
return .{
extra.data,
Expand Down
Loading

0 comments on commit f73be12

Please sign in to comment.