Commit cccc4c3827
Changed files (6)
test
cases
compile_errors
src/stage1/astgen.cpp
@@ -6987,6 +6987,12 @@ static bool astgen_switch_prong_expr(Stage1AstGen *ag, Scope *scope, AstNode *sw
assert(switch_node->type == NodeTypeSwitchExpr);
assert(prong_node->type == NodeTypeSwitchProng);
+ if (prong_node->data.switch_prong.is_inline) {
+ exec_add_error_node(ag->codegen, ag->exec, prong_node,
+ buf_sprintf("inline switch cases not supported by stage1"));
+ return ag->codegen->invalid_inst_src;
+ }
+
AstNode *expr_node = prong_node->data.switch_prong.expr;
AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol;
Scope *child_scope;
src/AstGen.zig
@@ -6312,6 +6312,9 @@ fn switchExpr(
},
);
}
+ if (case.inline_token != null) {
+ return astgen.failTok(case_src, "cannot inline '_' prong", .{});
+ }
special_node = case_node;
special_prong = .under;
underscore_src = case_src;
@@ -6365,8 +6368,8 @@ fn switchExpr(
var scalar_case_index: u32 = 0;
for (case_nodes) |case_node| {
const case = switch (node_tags[case_node]) {
- .switch_case_one => tree.switchCaseOne(case_node),
- .switch_case => tree.switchCase(case_node),
+ .switch_case_one, .switch_case_inline_one => tree.switchCaseOne(case_node),
+ .switch_case, .switch_case_inline => tree.switchCase(case_node),
else => unreachable,
};
@@ -6506,7 +6509,8 @@ fn switchExpr(
const case_slice = case_scope.instructionsSlice();
const body_len = astgen.countBodyLenAfterFixups(case_slice);
try payloads.ensureUnusedCapacity(gpa, body_len);
- payloads.items[body_len_index] = body_len;
+ const inline_bit = @as(u32, @boolToInt(case.inline_token != null)) << 31;
+ payloads.items[body_len_index] = body_len | inline_bit;
appendBodyWithFixupsArrayList(astgen, payloads, case_slice);
}
}
@@ -6553,7 +6557,7 @@ fn switchExpr(
end_index += 3 + items_len + 2 * ranges_len;
}
- const body_len = payloads.items[body_len_index];
+ const body_len = @truncate(u31, payloads.items[body_len_index]);
end_index += body_len;
switch (strat.tag) {
@@ -9134,7 +9138,9 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
.@"usingnamespace",
.test_decl,
.switch_case,
+ .switch_case_inline,
.switch_case_one,
+ .switch_case_inline_one,
.container_field_init,
.container_field_align,
.container_field,
src/print_zir.zig
@@ -1868,14 +1868,15 @@ const Writer = struct {
else => break :else_prong,
};
- const body_len = self.code.extra[extra_index];
+ const body_len = @truncate(u31, self.code.extra[extra_index]);
+ const inline_text = if (self.code.extra[extra_index] >> 31 != 0) "inline " else "";
extra_index += 1;
const body = self.code.extra[extra_index..][0..body_len];
extra_index += body.len;
try stream.writeAll(",\n");
try stream.writeByteNTimes(' ', self.indent);
- try stream.print("{s} => ", .{prong_name});
+ try stream.print("{s}{s} => ", .{ inline_text, prong_name });
try self.writeBracedBody(stream, body);
}
@@ -1885,13 +1886,15 @@ const Writer = struct {
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
const item_ref = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
extra_index += 1;
- const body_len = self.code.extra[extra_index];
+ const body_len = @truncate(u31, self.code.extra[extra_index]);
+ const is_inline = self.code.extra[extra_index] >> 31 != 0;
extra_index += 1;
const body = self.code.extra[extra_index..][0..body_len];
extra_index += body_len;
try stream.writeAll(",\n");
try stream.writeByteNTimes(' ', self.indent);
+ if (is_inline) try stream.writeAll("inline ");
try self.writeInstRef(stream, item_ref);
try stream.writeAll(" => ");
try self.writeBracedBody(stream, body);
@@ -1904,13 +1907,15 @@ const Writer = struct {
extra_index += 1;
const ranges_len = self.code.extra[extra_index];
extra_index += 1;
- const body_len = self.code.extra[extra_index];
+ const body_len = @truncate(u31, self.code.extra[extra_index]);
+ const is_inline = self.code.extra[extra_index] >> 31 != 0;
extra_index += 1;
const items = self.code.refSlice(extra_index, items_len);
extra_index += items_len;
try stream.writeAll(",\n");
try stream.writeByteNTimes(' ', self.indent);
+ if (is_inline) try stream.writeAll("inline ");
for (items) |item_ref, item_i| {
if (item_i != 0) try stream.writeAll(", ");
src/Sema.zig
@@ -9237,7 +9237,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
const special: struct { body: []const Zir.Inst.Index, end: usize } = switch (special_prong) {
.none => .{ .body = &.{}, .end = header_extra_index },
.under, .@"else" => blk: {
- const body_len = sema.code.extra[header_extra_index];
+ const body_len = @truncate(u31, sema.code.extra[header_extra_index]);
const extra_body_start = header_extra_index + 1;
break :blk .{
.body = sema.code.extra[extra_body_start..][0..body_len],
@@ -9307,7 +9307,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
extra_index += body_len;
@@ -9328,7 +9328,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
extra_index += 1;
const ranges_len = sema.code.extra[extra_index];
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
const items = sema.code.refSlice(extra_index, items_len);
extra_index += items_len + body_len;
@@ -9407,7 +9407,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
extra_index += body_len;
@@ -9427,7 +9427,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
extra_index += 1;
const ranges_len = sema.code.extra[extra_index];
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
const items = sema.code.refSlice(extra_index, items_len);
extra_index += items_len + body_len;
@@ -9549,7 +9549,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
extra_index += body_len;
@@ -9570,7 +9570,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
extra_index += 1;
const ranges_len = sema.code.extra[extra_index];
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
const items = sema.code.refSlice(extra_index, items_len);
extra_index += items_len;
@@ -9647,7 +9647,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
extra_index += body_len;
@@ -9668,7 +9668,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
extra_index += 1;
const ranges_len = sema.code.extra[extra_index];
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
const items = sema.code.refSlice(extra_index, items_len);
extra_index += items_len + body_len;
@@ -9732,7 +9732,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
extra_index += body_len;
@@ -9752,7 +9752,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
extra_index += 1;
const ranges_len = sema.code.extra[extra_index];
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
const items = sema.code.refSlice(extra_index, items_len);
extra_index += items_len + body_len;
@@ -9832,7 +9832,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
const body = sema.code.extra[extra_index..][0..body_len];
extra_index += body_len;
@@ -9853,7 +9853,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
extra_index += 1;
const ranges_len = sema.code.extra[extra_index];
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
const items = sema.code.refSlice(extra_index, items_len);
extra_index += items_len;
@@ -9926,7 +9926,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
const body = sema.code.extra[extra_index..][0..body_len];
extra_index += body_len;
@@ -9988,7 +9988,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
extra_index += 1;
const ranges_len = sema.code.extra[extra_index];
extra_index += 1;
- const body_len = sema.code.extra[extra_index];
+ const body_len = @truncate(u31, sema.code.extra[extra_index]);
extra_index += 1;
const items = sema.code.refSlice(extra_index, items_len);
extra_index += items_len;
src/Zir.zig
@@ -2990,7 +2990,7 @@ pub const Inst = struct {
}
if (self.bits.specialProng() != .none) {
- const body_len = zir.extra[extra_index];
+ const body_len = @truncate(u31, zir.extra[extra_index]);
extra_index += 1;
const body = zir.extra[extra_index..][0..body_len];
extra_index += body.len;
@@ -3000,7 +3000,7 @@ pub const Inst = struct {
while (true) : (scalar_i += 1) {
const item = @intToEnum(Ref, zir.extra[extra_index]);
extra_index += 1;
- const body_len = zir.extra[extra_index];
+ const body_len = @truncate(u31, zir.extra[extra_index]);
extra_index += 1;
const body = zir.extra[extra_index..][0..body_len];
extra_index += body.len;
@@ -3029,7 +3029,7 @@ pub const Inst = struct {
var extra_index: usize = extra_end + 1;
if (self.bits.specialProng() != .none) {
- const body_len = zir.extra[extra_index];
+ const body_len = @truncate(u31, zir.extra[extra_index]);
extra_index += 1;
const body = zir.extra[extra_index..][0..body_len];
extra_index += body.len;
@@ -3038,7 +3038,7 @@ pub const Inst = struct {
var scalar_i: usize = 0;
while (scalar_i < self.bits.scalar_cases_len) : (scalar_i += 1) {
extra_index += 1;
- const body_len = zir.extra[extra_index];
+ const body_len = @truncate(u31, zir.extra[extra_index]);
extra_index += 1;
extra_index += body_len;
}
@@ -3046,7 +3046,7 @@ pub const Inst = struct {
while (true) : (multi_i += 1) {
const items_len = zir.extra[extra_index];
extra_index += 2;
- const body_len = zir.extra[extra_index];
+ const body_len = @truncate(u31, zir.extra[extra_index]);
extra_index += 1;
const items = zir.refSlice(extra_index, items_len);
extra_index += items_len;
@@ -3858,7 +3858,7 @@ fn findDeclsSwitch(
const special_prong = extra.data.bits.specialProng();
if (special_prong != .none) {
- const body_len = zir.extra[extra_index];
+ const body_len = @truncate(u31, zir.extra[extra_index]);
extra_index += 1;
const body = zir.extra[extra_index..][0..body_len];
extra_index += body.len;
@@ -3871,7 +3871,7 @@ fn findDeclsSwitch(
var scalar_i: usize = 0;
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
extra_index += 1;
- const body_len = zir.extra[extra_index];
+ const body_len = @truncate(u31, zir.extra[extra_index]);
extra_index += 1;
const body = zir.extra[extra_index..][0..body_len];
extra_index += body_len;
@@ -3886,7 +3886,7 @@ fn findDeclsSwitch(
extra_index += 1;
const ranges_len = zir.extra[extra_index];
extra_index += 1;
- const body_len = zir.extra[extra_index];
+ const body_len = @truncate(u31, zir.extra[extra_index]);
extra_index += 1;
const items = zir.refSlice(extra_index, items_len);
extra_index += items_len;
test/cases/compile_errors/inline_underscore_prong.zig
@@ -0,0 +1,15 @@
+const E = enum(u8) { a, b, c, d, _ };
+pub export fn entry() void {
+ var x: E = .a;
+ switch (x) {
+ inline .a, .b => |aorb| @compileLog(aorb),
+ .c, .d => |cord| @compileLog(cord),
+ inline _ => {},
+ }
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :7:16: error: cannot inline '_' prong