diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index 0b0459ec88..cb3ea3ecf3 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -1430,7 +1430,7 @@ pub const Tree = struct { .ast = .{ .lbracket = tree.nodes.items(.main_token)[node], .elem_count = data.lhs, - .sentinel = null, + .sentinel = 0, .elem_type = data.rhs, }, }; @@ -1440,6 +1440,7 @@ pub const Tree = struct { assert(tree.nodes.items(.tag)[node] == .array_type_sentinel); const data = tree.nodes.items(.data)[node]; const extra = tree.extraData(data.rhs, Node.ArrayTypeSentinel); + assert(extra.sentinel != 0); return .{ .ast = .{ .lbracket = tree.nodes.items(.main_token)[node], @@ -2262,7 +2263,7 @@ pub const full = struct { pub const Ast = struct { lbracket: TokenIndex, elem_count: Node.Index, - sentinel: ?Node.Index, + sentinel: Node.Index, elem_type: Node.Index, }; }; @@ -2549,9 +2550,9 @@ pub const Node = struct { @"await", /// `?lhs`. rhs unused. main_token is the `?`. optional_type, - /// `[lhs]rhs`. lhs can be omitted to make it a slice. + /// `[lhs]rhs`. array_type, - /// `[lhs:a]b`. `array_type_sentinel[rhs]`. + /// `[lhs:a]b`. `ArrayTypeSentinel[rhs]`. array_type_sentinel, /// `[*]align(lhs) rhs`. lhs can be omitted. /// `*align(lhs) rhs`. lhs can be omitted. diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 640f25829a..7add8383f3 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -717,9 +717,9 @@ fn renderArrayType( ais.pushIndentNextLine(); try renderToken(ais, tree, array_type.ast.lbracket, inner_space); // lbracket try renderExpression(gpa, ais, tree, array_type.ast.elem_count, inner_space); - if (array_type.ast.sentinel) |sentinel| { - try renderToken(ais, tree, tree.firstToken(sentinel) - 1, inner_space); // colon - try renderExpression(gpa, ais, tree, sentinel, inner_space); + if (array_type.ast.sentinel != 0) { + try renderToken(ais, tree, tree.firstToken(array_type.ast.sentinel) - 1, inner_space); // colon + try renderExpression(gpa, ais, tree, array_type.ast.sentinel, inner_space); } ais.popIndent(); try renderToken(ais, tree, rbracket, .none); // rbracket diff --git a/src/Module.zig b/src/Module.zig index c89ffadcc1..5fcdd8c6f1 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1210,6 +1210,32 @@ pub const Scope = struct { return new_index + gz.zir_code.ref_start_index; } + pub fn addArrayTypeSentinel( + gz: *GenZir, + len: zir.Inst.Ref, + sentinel: zir.Inst.Ref, + elem_type: zir.Inst.Ref, + ) !zir.Inst.Ref { + const gpa = gz.zir_code.gpa; + try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); + try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1); + + const payload_index = try gz.zir_code.addExtra(zir.Inst.ArrayTypeSentinel{ + .sentinel = sentinel, + .elem_type = elem_type, + }); + const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); + gz.zir_code.instructions.appendAssumeCapacity(.{ + .tag = .array_type_sentinel, + .data = .{ .array_type_sentinel = .{ + .len = len, + .payload_index = payload_index, + } }, + }); + gz.instructions.appendAssumeCapacity(new_index); + return new_index + gz.zir_code.ref_start_index; + } + pub fn addUnTok( gz: *GenZir, tag: zir.Inst.Tag, diff --git a/src/astgen.zig b/src/astgen.zig index 4e3fdccb6d..75856c67d4 100644 --- a/src/astgen.zig +++ b/src/astgen.zig @@ -1390,56 +1390,33 @@ fn ptrType( } fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !zir.Inst.Ref { - if (true) @panic("TODO update for zir-memory-layout"); const tree = scope.tree(); - const main_tokens = tree.nodes.items(.main_token); const node_datas = tree.nodes.items(.data); + const gz = scope.getGenZir(); + const usize_type = @enumToInt(zir.Const.usize_type); - const usize_type = try addZIRInstConst(mod, scope, src, .{ - .ty = Type.initTag(.type), - .val = Value.initTag(.usize_type), - }); - const len_node = node_datas[node].lhs; - const elem_node = node_datas[node].rhs; - if (len_node == 0) { - const elem_type = try typeExpr(mod, scope, elem_node); - const result = try addZIRUnOp(mod, scope, src, .mut_slice_type, elem_type); - return rvalue(mod, scope, rl, result); - } else { - // TODO check for [_]T - const len = try expr(mod, scope, .{ .ty = usize_type }, len_node); - const elem_type = try typeExpr(mod, scope, elem_node); + // TODO check for [_]T + const len = try expr(mod, scope, .{ .ty = usize_type }, node_datas[node].lhs); + const elem_type = try typeExpr(mod, scope, node_datas[node].rhs); - const result = try addZIRBinOp(mod, scope, src, .array_type, len, elem_type); - return rvalue(mod, scope, rl, result); - } + const result = try gz.addBin(.array_type, len, elem_type); + return rvalue(mod, scope, rl, result, node); } fn arrayTypeSentinel(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !zir.Inst.Ref { - if (true) @panic("TODO update for zir-memory-layout"); const tree = scope.tree(); - const main_tokens = tree.nodes.items(.main_token); const node_datas = tree.nodes.items(.data); - - const len_node = node_datas[node].lhs; const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel); - const usize_type = try addZIRInstConst(mod, scope, src, .{ - .ty = Type.initTag(.type), - .val = Value.initTag(.usize_type), - }); + const gz = scope.getGenZir(); + const usize_type = @enumToInt(zir.Const.usize_type); // TODO check for [_]T - const len = try expr(mod, scope, .{ .ty = usize_type }, len_node); - const sentinel_uncasted = try expr(mod, scope, .none, extra.sentinel); + const len = try expr(mod, scope, .{ .ty = usize_type }, node_datas[node].lhs); const elem_type = try typeExpr(mod, scope, extra.elem_type); - const sentinel = try addZIRBinOp(mod, scope, src, .as, elem_type, sentinel_uncasted); + const sentinel = try expr(mod, scope, .{ .ty = elem_type }, extra.sentinel); - const result = try addZIRInst(mod, scope, src, zir.Inst.ArrayTypeSentinel, .{ - .len = len, - .sentinel = sentinel, - .elem_type = elem_type, - }, .{}); - return rvalue(mod, scope, rl, result); + const result = try gz.addArrayTypeSentinel(len, elem_type, sentinel); + return rvalue(mod, scope, rl, result, node); } fn containerDecl(