Skip to content

Commit

Permalink
opaque
Browse files Browse the repository at this point in the history
  • Loading branch information
alichraghi committed Jul 8, 2024
1 parent 1905137 commit cd6b766
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 44 deletions.
2 changes: 1 addition & 1 deletion lib/std/zig/Ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3380,7 +3380,7 @@ pub const Node = struct {
/// Same as ContainerDeclTwo except there is known to be a trailing comma
/// or semicolon before the rbrace.
container_decl_two_trailing,
/// `struct(lhs)` / `union(lhs)` / `enum(lhs)`. `SubRange[rhs]`.
/// `struct(lhs)` / `union(lhs)` / `opaque(lhs)` / `enum(lhs)`. `SubRange[rhs]`.
container_decl_arg,
/// Same as container_decl_arg but there is known to be a trailing
/// comma or semicolon before the rbrace.
Expand Down
13 changes: 11 additions & 2 deletions lib/std/zig/AstGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5696,8 +5696,6 @@ fn containerDecl(
return rvalue(gz, ri, decl_inst.toRef(), node);
},
.keyword_opaque => {
assert(container_decl.ast.arg == 0);

const decl_inst = try gz.reserveInstructionIndex();

var namespace: Scope.Namespace = .{
Expand Down Expand Up @@ -5733,8 +5731,14 @@ fn containerDecl(
}
}

const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0)
try comptimeExpr(&block_scope, &namespace.base, coerced_type_ri, container_decl.ast.arg)
else
.none;

try gz.setOpaque(decl_inst, .{
.src_node = node,
.asm_type = arg_inst,
.captures_len = @intCast(namespace.captures.count()),
.decls_len = decl_count,
});
Expand Down Expand Up @@ -13300,6 +13304,7 @@ const GenZir = struct {

fn setOpaque(gz: *GenZir, inst: Zir.Inst.Index, args: struct {
src_node: Ast.Node.Index,
asm_type: Zir.Inst.Ref,
captures_len: u32,
decls_len: u32,
}) !void {
Expand All @@ -13314,6 +13319,9 @@ const GenZir = struct {
.src_node = args.src_node,
});

if (args.asm_type != .none) {
astgen.extra.appendAssumeCapacity(@intFromEnum(args.asm_type));
}
if (args.captures_len != 0) {
astgen.extra.appendAssumeCapacity(args.captures_len);
}
Expand All @@ -13325,6 +13333,7 @@ const GenZir = struct {
.data = .{ .extended = .{
.opcode = .opaque_decl,
.small = @bitCast(Zir.Inst.OpaqueDecl.Small{
.has_asm_type = args.asm_type != .none,
.has_captures_len = args.captures_len != 0,
.has_decls_len = args.decls_len != 0,
.name_strategy = gz.anon_name_strategy,
Expand Down
39 changes: 6 additions & 33 deletions lib/std/zig/AstRlAnnotate.zig
Original file line number Diff line number Diff line change
Expand Up @@ -91,39 +91,12 @@ fn containerDecl(
block: ?*Block,
full: Ast.full.ContainerDecl,
) !void {
const tree = astrl.tree;
const token_tags = tree.tokens.items(.tag);
switch (token_tags[full.ast.main_token]) {
.keyword_struct => {
if (full.ast.arg != 0) {
_ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only);
}
for (full.ast.members) |member_node| {
_ = try astrl.expr(member_node, block, ResultInfo.none);
}
},
.keyword_union => {
if (full.ast.arg != 0) {
_ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only);
}
for (full.ast.members) |member_node| {
_ = try astrl.expr(member_node, block, ResultInfo.none);
}
},
.keyword_enum => {
if (full.ast.arg != 0) {
_ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only);
}
for (full.ast.members) |member_node| {
_ = try astrl.expr(member_node, block, ResultInfo.none);
}
},
.keyword_opaque => {
for (full.ast.members) |member_node| {
_ = try astrl.expr(member_node, block, ResultInfo.none);
}
},
else => unreachable,
if (full.ast.arg != 0) {
_ = try astrl.expr(full.ast.arg, block, ResultInfo.type_only);
}

for (full.ast.members) |member_node| {
_ = try astrl.expr(member_node, block, ResultInfo.none);
}
}

Expand Down
5 changes: 2 additions & 3 deletions lib/std/zig/Parse.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3591,14 +3591,13 @@ fn parseSuffixOp(p: *Parse, lhs: Node.Index) !Node.Index {
///
/// ContainerDeclType
/// <- KEYWORD_struct (LPAREN Expr RPAREN)?
/// / KEYWORD_opaque
/// / KEYWORD_opaque (LPAREN Expr RPAREN)?
/// / KEYWORD_enum (LPAREN Expr RPAREN)?
/// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
fn parseContainerDeclAuto(p: *Parse) !Node.Index {
const main_token = p.nextToken();
const arg_expr = switch (p.token_tags[main_token]) {
.keyword_opaque => null_node,
.keyword_struct, .keyword_enum => blk: {
.keyword_struct, .keyword_enum, .keyword_opaque => blk: {
if (p.eatToken(.l_paren)) |_| {
const expr = try p.expectExpr();
_ = try p.expectToken(.r_paren);
Expand Down
13 changes: 8 additions & 5 deletions lib/std/zig/Zir.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3199,20 +3199,22 @@ pub const Inst = struct {
};

/// Trailing:
/// 0. captures_len: u32, // if has_captures_len
/// 1. decls_len: u32, // if has_decls_len
/// 2. capture: Capture, // for every captures_len
/// 3. decl: Index, // for every decls_len; points to a `declaration` instruction
/// 0. asm_type: Ref, // if has_asm_type
/// 1. captures_len: u32, // if has_captures_len
/// 2. decls_len: u32, // if has_decls_len
/// 3. capture: Capture, // for every captures_len
/// 4. decl: Index, // for every decls_len; points to a `declaration` instruction
pub const OpaqueDecl = struct {
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_asm_type: bool,
has_captures_len: bool,
has_decls_len: bool,
name_strategy: NameStrategy,
_: u12 = undefined,
_: u11 = undefined,
};
};

Expand Down Expand Up @@ -3594,6 +3596,7 @@ pub fn declIterator(zir: Zir, decl_inst: Zir.Inst.Index) DeclIterator {
.opaque_decl => {
const small: Inst.OpaqueDecl.Small = @bitCast(extended.small);
var extra_index: u32 = @intCast(extended.operand + @typeInfo(Inst.OpaqueDecl).Struct.fields.len);
extra_index += @intFromBool(small.has_asm_type);
const decls_len = if (small.has_decls_len) decls_len: {
const decls_len = zir.extra[extra_index];
extra_index += 1;
Expand Down
4 changes: 4 additions & 0 deletions src/InternPool.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3900,6 +3900,8 @@ pub const Tag = enum(u8) {
decl: DeclIndex,
/// Contains the declarations inside this opaque.
namespace: OptionalNamespaceIndex,
/// The type provided by assembly.
asm_type: Index,
/// The index of the `opaque_decl` instruction.
zir_index: TrackedInst.Index,
/// `std.math.maxInt(u32)` indicates this type is reified.
Expand Down Expand Up @@ -7308,6 +7310,7 @@ pub fn getGeneratedTagEnumType(ip: *InternPool, gpa: Allocator, ini: GeneratedTa

pub const OpaqueTypeInit = struct {
has_namespace: bool,
asm_type: Index,
key: union(enum) {
declared: struct {
zir_index: TrackedInst.Index,
Expand Down Expand Up @@ -7342,6 +7345,7 @@ pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeInit) Alloc
const extra_index = ip.addExtraAssumeCapacity(Tag.TypeOpaque{
.decl = undefined, // set by `finish`
.namespace = .none,
.asm_type = ini.asm_type,
.zir_index = switch (ini.key) {
inline else => |x| x.zir_index,
},
Expand Down
17 changes: 17 additions & 0 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3376,6 +3376,13 @@ fn zirOpaqueDecl(

const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst);
const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) };
const asm_type_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = 0 } };

const asm_type_ref = if (small.has_asm_type) blk: {
const asm_type_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
extra_index += 1;
break :blk asm_type_ref;
} else .none;

const captures_len = if (small.has_captures_len) blk: {
const captures_len = sema.code.extra[extra_index];
Expand All @@ -3392,8 +3399,17 @@ fn zirOpaqueDecl(
const captures = try sema.getCaptures(block, src, extra_index, captures_len);
extra_index += captures_len;

const asm_type = if (asm_type_ref != .none) ty: {
const ty = try sema.resolveType(block, asm_type_src, asm_type_ref);
if (ty.ip_index != .type_type) {
return sema.fail(block, asm_type_src, "expected assembly type, found '{}'", .{ty.fmt(sema.mod)});
}
break :ty ty.ip_index;
} else .none;

const opaque_init: InternPool.OpaqueTypeInit = .{
.has_namespace = decls_len != 0,
.asm_type = asm_type,
.key = .{ .declared = .{
.zir_index = tracked_inst,
.captures = captures,
Expand Down Expand Up @@ -21586,6 +21602,7 @@ fn zirReify(

const wip_ty = switch (try ip.getOpaqueType(gpa, .{
.has_namespace = false,
.asm_type = .none, // TODO(ALI)
.key = .{ .reified = .{
.zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst),
} },
Expand Down
11 changes: 11 additions & 0 deletions src/print_zir.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1915,6 +1915,12 @@ const Writer = struct {

var extra_index: usize = extra.end;

const asm_type_ref = if (small.has_asm_type) blk: {
const asm_type_ref = @as(Zir.Inst.Ref, @enumFromInt(self.code.extra[extra_index]));
extra_index += 1;
break :blk asm_type_ref;
} else .none;

const captures_len = if (small.has_captures_len) blk: {
const captures_len = self.code.extra[extra_index];
extra_index += 1;
Expand Down Expand Up @@ -1943,6 +1949,11 @@ const Writer = struct {
try stream.writeAll(" }, ");
}

if (asm_type_ref != .none) {
try self.writeInstRef(stream, asm_type_ref);
try stream.writeAll(", ");
}

if (decls_len == 0) {
try stream.writeAll("{}) ");
} else {
Expand Down

0 comments on commit cd6b766

Please sign in to comment.