authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-26 13:58:04+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-27 18:05:08+03:00
logcccc4c38273eb3e937c3572952b5609b51010baa
treeeb202efed413f4d7be467c5e14a8ee44bda9b24d
parent07a7c2f7c86d72bd15e980d098aa2b46f236412f

AstGen: analyze inline switch cases


6 files changed, 63 insertions(+), 31 deletions(-)

src/AstGen.zig+10-4
......@@ -6312,6 +6312,9 @@ fn switchExpr(
63126312 },
63136313 );
63146314 }
6315 if (case.inline_token != null) {
6316 return astgen.failTok(case_src, "cannot inline '_' prong", .{});
6317 }
63156318 special_node = case_node;
63166319 special_prong = .under;
63176320 underscore_src = case_src;
......@@ -6365,8 +6368,8 @@ fn switchExpr(
63656368 var scalar_case_index: u32 = 0;
63666369 for (case_nodes) |case_node| {
63676370 const case = switch (node_tags[case_node]) {
6368 .switch_case_one => tree.switchCaseOne(case_node),
6369 .switch_case => tree.switchCase(case_node),
6371 .switch_case_one, .switch_case_inline_one => tree.switchCaseOne(case_node),
6372 .switch_case, .switch_case_inline => tree.switchCase(case_node),
63706373 else => unreachable,
63716374 };
63726375
......@@ -6506,7 +6509,8 @@ fn switchExpr(
65066509 const case_slice = case_scope.instructionsSlice();
65076510 const body_len = astgen.countBodyLenAfterFixups(case_slice);
65086511 try payloads.ensureUnusedCapacity(gpa, body_len);
6509 payloads.items[body_len_index] = body_len;
6512 const inline_bit = @as(u32, @boolToInt(case.inline_token != null)) << 31;
6513 payloads.items[body_len_index] = body_len | inline_bit;
65106514 appendBodyWithFixupsArrayList(astgen, payloads, case_slice);
65116515 }
65126516 }
......@@ -6553,7 +6557,7 @@ fn switchExpr(
65536557 end_index += 3 + items_len + 2 * ranges_len;
65546558 }
65556559
6556 const body_len = payloads.items[body_len_index];
6560 const body_len = @truncate(u31, payloads.items[body_len_index]);
65576561 end_index += body_len;
65586562
65596563 switch (strat.tag) {
......@@ -9134,7 +9138,9 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
91349138 .@"usingnamespace",
91359139 .test_decl,
91369140 .switch_case,
9141 .switch_case_inline,
91379142 .switch_case_one,
9143 .switch_case_inline_one,
91389144 .container_field_init,
91399145 .container_field_align,
91409146 .container_field,
src/Sema.zig+15-15
......@@ -9237,7 +9237,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
92379237 const special: struct { body: []const Zir.Inst.Index, end: usize } = switch (special_prong) {
92389238 .none => .{ .body = &.{}, .end = header_extra_index },
92399239 .under, .@"else" => blk: {
9240 const body_len = sema.code.extra[header_extra_index];
9240 const body_len = @truncate(u31, sema.code.extra[header_extra_index]);
92419241 const extra_body_start = header_extra_index + 1;
92429242 break :blk .{
92439243 .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
93079307 while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
93089308 const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
93099309 extra_index += 1;
9310 const body_len = sema.code.extra[extra_index];
9310 const body_len = @truncate(u31, sema.code.extra[extra_index]);
93119311 extra_index += 1;
93129312 extra_index += body_len;
93139313
......@@ -9328,7 +9328,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
93289328 extra_index += 1;
93299329 const ranges_len = sema.code.extra[extra_index];
93309330 extra_index += 1;
9331 const body_len = sema.code.extra[extra_index];
9331 const body_len = @truncate(u31, sema.code.extra[extra_index]);
93329332 extra_index += 1;
93339333 const items = sema.code.refSlice(extra_index, items_len);
93349334 extra_index += items_len + body_len;
......@@ -9407,7 +9407,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
94079407 while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
94089408 const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
94099409 extra_index += 1;
9410 const body_len = sema.code.extra[extra_index];
9410 const body_len = @truncate(u31, sema.code.extra[extra_index]);
94119411 extra_index += 1;
94129412 extra_index += body_len;
94139413
......@@ -9427,7 +9427,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
94279427 extra_index += 1;
94289428 const ranges_len = sema.code.extra[extra_index];
94299429 extra_index += 1;
9430 const body_len = sema.code.extra[extra_index];
9430 const body_len = @truncate(u31, sema.code.extra[extra_index]);
94319431 extra_index += 1;
94329432 const items = sema.code.refSlice(extra_index, items_len);
94339433 extra_index += items_len + body_len;
......@@ -9549,7 +9549,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
95499549 while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
95509550 const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
95519551 extra_index += 1;
9552 const body_len = sema.code.extra[extra_index];
9552 const body_len = @truncate(u31, sema.code.extra[extra_index]);
95539553 extra_index += 1;
95549554 extra_index += body_len;
95559555
......@@ -9570,7 +9570,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
95709570 extra_index += 1;
95719571 const ranges_len = sema.code.extra[extra_index];
95729572 extra_index += 1;
9573 const body_len = sema.code.extra[extra_index];
9573 const body_len = @truncate(u31, sema.code.extra[extra_index]);
95749574 extra_index += 1;
95759575 const items = sema.code.refSlice(extra_index, items_len);
95769576 extra_index += items_len;
......@@ -9647,7 +9647,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
96479647 while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
96489648 const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
96499649 extra_index += 1;
9650 const body_len = sema.code.extra[extra_index];
9650 const body_len = @truncate(u31, sema.code.extra[extra_index]);
96519651 extra_index += 1;
96529652 extra_index += body_len;
96539653
......@@ -9668,7 +9668,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
96689668 extra_index += 1;
96699669 const ranges_len = sema.code.extra[extra_index];
96709670 extra_index += 1;
9671 const body_len = sema.code.extra[extra_index];
9671 const body_len = @truncate(u31, sema.code.extra[extra_index]);
96729672 extra_index += 1;
96739673 const items = sema.code.refSlice(extra_index, items_len);
96749674 extra_index += items_len + body_len;
......@@ -9732,7 +9732,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
97329732 while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
97339733 const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
97349734 extra_index += 1;
9735 const body_len = sema.code.extra[extra_index];
9735 const body_len = @truncate(u31, sema.code.extra[extra_index]);
97369736 extra_index += 1;
97379737 extra_index += body_len;
97389738
......@@ -9752,7 +9752,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
97529752 extra_index += 1;
97539753 const ranges_len = sema.code.extra[extra_index];
97549754 extra_index += 1;
9755 const body_len = sema.code.extra[extra_index];
9755 const body_len = @truncate(u31, sema.code.extra[extra_index]);
97569756 extra_index += 1;
97579757 const items = sema.code.refSlice(extra_index, items_len);
97589758 extra_index += items_len + body_len;
......@@ -9832,7 +9832,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
98329832 while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
98339833 const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
98349834 extra_index += 1;
9835 const body_len = sema.code.extra[extra_index];
9835 const body_len = @truncate(u31, sema.code.extra[extra_index]);
98369836 extra_index += 1;
98379837 const body = sema.code.extra[extra_index..][0..body_len];
98389838 extra_index += body_len;
......@@ -9853,7 +9853,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
98539853 extra_index += 1;
98549854 const ranges_len = sema.code.extra[extra_index];
98559855 extra_index += 1;
9856 const body_len = sema.code.extra[extra_index];
9856 const body_len = @truncate(u31, sema.code.extra[extra_index]);
98579857 extra_index += 1;
98589858 const items = sema.code.refSlice(extra_index, items_len);
98599859 extra_index += items_len;
......@@ -9926,7 +9926,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
99269926 while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
99279927 const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
99289928 extra_index += 1;
9929 const body_len = sema.code.extra[extra_index];
9929 const body_len = @truncate(u31, sema.code.extra[extra_index]);
99309930 extra_index += 1;
99319931 const body = sema.code.extra[extra_index..][0..body_len];
99329932 extra_index += body_len;
......@@ -9988,7 +9988,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
99889988 extra_index += 1;
99899989 const ranges_len = sema.code.extra[extra_index];
99909990 extra_index += 1;
9991 const body_len = sema.code.extra[extra_index];
9991 const body_len = @truncate(u31, sema.code.extra[extra_index]);
99929992 extra_index += 1;
99939993 const items = sema.code.refSlice(extra_index, items_len);
99949994 extra_index += items_len;
src/Zir.zig+8-8
......@@ -2990,7 +2990,7 @@ pub const Inst = struct {
29902990 }
29912991
29922992 if (self.bits.specialProng() != .none) {
2993 const body_len = zir.extra[extra_index];
2993 const body_len = @truncate(u31, zir.extra[extra_index]);
29942994 extra_index += 1;
29952995 const body = zir.extra[extra_index..][0..body_len];
29962996 extra_index += body.len;
......@@ -3000,7 +3000,7 @@ pub const Inst = struct {
30003000 while (true) : (scalar_i += 1) {
30013001 const item = @intToEnum(Ref, zir.extra[extra_index]);
30023002 extra_index += 1;
3003 const body_len = zir.extra[extra_index];
3003 const body_len = @truncate(u31, zir.extra[extra_index]);
30043004 extra_index += 1;
30053005 const body = zir.extra[extra_index..][0..body_len];
30063006 extra_index += body.len;
......@@ -3029,7 +3029,7 @@ pub const Inst = struct {
30293029 var extra_index: usize = extra_end + 1;
30303030
30313031 if (self.bits.specialProng() != .none) {
3032 const body_len = zir.extra[extra_index];
3032 const body_len = @truncate(u31, zir.extra[extra_index]);
30333033 extra_index += 1;
30343034 const body = zir.extra[extra_index..][0..body_len];
30353035 extra_index += body.len;
......@@ -3038,7 +3038,7 @@ pub const Inst = struct {
30383038 var scalar_i: usize = 0;
30393039 while (scalar_i < self.bits.scalar_cases_len) : (scalar_i += 1) {
30403040 extra_index += 1;
3041 const body_len = zir.extra[extra_index];
3041 const body_len = @truncate(u31, zir.extra[extra_index]);
30423042 extra_index += 1;
30433043 extra_index += body_len;
30443044 }
......@@ -3046,7 +3046,7 @@ pub const Inst = struct {
30463046 while (true) : (multi_i += 1) {
30473047 const items_len = zir.extra[extra_index];
30483048 extra_index += 2;
3049 const body_len = zir.extra[extra_index];
3049 const body_len = @truncate(u31, zir.extra[extra_index]);
30503050 extra_index += 1;
30513051 const items = zir.refSlice(extra_index, items_len);
30523052 extra_index += items_len;
......@@ -3858,7 +3858,7 @@ fn findDeclsSwitch(
38583858
38593859 const special_prong = extra.data.bits.specialProng();
38603860 if (special_prong != .none) {
3861 const body_len = zir.extra[extra_index];
3861 const body_len = @truncate(u31, zir.extra[extra_index]);
38623862 extra_index += 1;
38633863 const body = zir.extra[extra_index..][0..body_len];
38643864 extra_index += body.len;
......@@ -3871,7 +3871,7 @@ fn findDeclsSwitch(
38713871 var scalar_i: usize = 0;
38723872 while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
38733873 extra_index += 1;
3874 const body_len = zir.extra[extra_index];
3874 const body_len = @truncate(u31, zir.extra[extra_index]);
38753875 extra_index += 1;
38763876 const body = zir.extra[extra_index..][0..body_len];
38773877 extra_index += body_len;
......@@ -3886,7 +3886,7 @@ fn findDeclsSwitch(
38863886 extra_index += 1;
38873887 const ranges_len = zir.extra[extra_index];
38883888 extra_index += 1;
3889 const body_len = zir.extra[extra_index];
3889 const body_len = @truncate(u31, zir.extra[extra_index]);
38903890 extra_index += 1;
38913891 const items = zir.refSlice(extra_index, items_len);
38923892 extra_index += items_len;
src/print_zir.zig+9-4
......@@ -1868,14 +1868,15 @@ const Writer = struct {
18681868 else => break :else_prong,
18691869 };
18701870
1871 const body_len = self.code.extra[extra_index];
1871 const body_len = @truncate(u31, self.code.extra[extra_index]);
1872 const inline_text = if (self.code.extra[extra_index] >> 31 != 0) "inline " else "";
18721873 extra_index += 1;
18731874 const body = self.code.extra[extra_index..][0..body_len];
18741875 extra_index += body.len;
18751876
18761877 try stream.writeAll(",\n");
18771878 try stream.writeByteNTimes(' ', self.indent);
1878 try stream.print("{s} => ", .{prong_name});
1879 try stream.print("{s}{s} => ", .{ inline_text, prong_name });
18791880 try self.writeBracedBody(stream, body);
18801881 }
18811882
......@@ -1885,13 +1886,15 @@ const Writer = struct {
18851886 while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
18861887 const item_ref = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
18871888 extra_index += 1;
1888 const body_len = self.code.extra[extra_index];
1889 const body_len = @truncate(u31, self.code.extra[extra_index]);
1890 const is_inline = self.code.extra[extra_index] >> 31 != 0;
18891891 extra_index += 1;
18901892 const body = self.code.extra[extra_index..][0..body_len];
18911893 extra_index += body_len;
18921894
18931895 try stream.writeAll(",\n");
18941896 try stream.writeByteNTimes(' ', self.indent);
1897 if (is_inline) try stream.writeAll("inline ");
18951898 try self.writeInstRef(stream, item_ref);
18961899 try stream.writeAll(" => ");
18971900 try self.writeBracedBody(stream, body);
......@@ -1904,13 +1907,15 @@ const Writer = struct {
19041907 extra_index += 1;
19051908 const ranges_len = self.code.extra[extra_index];
19061909 extra_index += 1;
1907 const body_len = self.code.extra[extra_index];
1910 const body_len = @truncate(u31, self.code.extra[extra_index]);
1911 const is_inline = self.code.extra[extra_index] >> 31 != 0;
19081912 extra_index += 1;
19091913 const items = self.code.refSlice(extra_index, items_len);
19101914 extra_index += items_len;
19111915
19121916 try stream.writeAll(",\n");
19131917 try stream.writeByteNTimes(' ', self.indent);
1918 if (is_inline) try stream.writeAll("inline ");
19141919
19151920 for (items) |item_ref, item_i| {
19161921 if (item_i != 0) try stream.writeAll(", ");
src/stage1/astgen.cpp+6
......@@ -6987,6 +6987,12 @@ static bool astgen_switch_prong_expr(Stage1AstGen *ag, Scope *scope, AstNode *sw
69876987 assert(switch_node->type == NodeTypeSwitchExpr);
69886988 assert(prong_node->type == NodeTypeSwitchProng);
69896989
6990 if (prong_node->data.switch_prong.is_inline) {
6991 exec_add_error_node(ag->codegen, ag->exec, prong_node,
6992 buf_sprintf("inline switch cases not supported by stage1"));
6993 return ag->codegen->invalid_inst_src;
6994 }
6995
69906996 AstNode *expr_node = prong_node->data.switch_prong.expr;
69916997 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol;
69926998 Scope *child_scope;
test/cases/compile_errors/inline_underscore_prong.zig created+15
......@@ -0,0 +1,15 @@
1const E = enum(u8) { a, b, c, d, _ };
2pub export fn entry() void {
3 var x: E = .a;
4 switch (x) {
5 inline .a, .b => |aorb| @compileLog(aorb),
6 .c, .d => |cord| @compileLog(cord),
7 inline _ => {},
8 }
9}
10
11// error
12// backend=stage2
13// target=native
14//
15// :7:16: error: cannot inline '_' prong