| author | |
| committer | |
| log | cccc4c38273eb3e937c3572952b5609b51010baa |
| tree | eb202efed413f4d7be467c5e14a8ee44bda9b24d |
| parent | 07a7c2f7c86d72bd15e980d098aa2b46f236412f |
6 files changed, 63 insertions(+), 31 deletions(-)
src/AstGen.zig+10-4| ... | ... | @@ -6312,6 +6312,9 @@ fn switchExpr( |
| 6312 | 6312 | }, |
| 6313 | 6313 | ); |
| 6314 | 6314 | } |
| 6315 | if (case.inline_token != null) { | |
| 6316 | return astgen.failTok(case_src, "cannot inline '_' prong", .{}); | |
| 6317 | } | |
| 6315 | 6318 | special_node = case_node; |
| 6316 | 6319 | special_prong = .under; |
| 6317 | 6320 | underscore_src = case_src; |
| ... | ... | @@ -6365,8 +6368,8 @@ fn switchExpr( |
| 6365 | 6368 | var scalar_case_index: u32 = 0; |
| 6366 | 6369 | for (case_nodes) |case_node| { |
| 6367 | 6370 | 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), | |
| 6370 | 6373 | else => unreachable, |
| 6371 | 6374 | }; |
| 6372 | 6375 | |
| ... | ... | @@ -6506,7 +6509,8 @@ fn switchExpr( |
| 6506 | 6509 | const case_slice = case_scope.instructionsSlice(); |
| 6507 | 6510 | const body_len = astgen.countBodyLenAfterFixups(case_slice); |
| 6508 | 6511 | 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; | |
| 6510 | 6514 | appendBodyWithFixupsArrayList(astgen, payloads, case_slice); |
| 6511 | 6515 | } |
| 6512 | 6516 | } |
| ... | ... | @@ -6553,7 +6557,7 @@ fn switchExpr( |
| 6553 | 6557 | end_index += 3 + items_len + 2 * ranges_len; |
| 6554 | 6558 | } |
| 6555 | 6559 | |
| 6556 | const body_len = payloads.items[body_len_index]; | |
| 6560 | const body_len = @truncate(u31, payloads.items[body_len_index]); | |
| 6557 | 6561 | end_index += body_len; |
| 6558 | 6562 | |
| 6559 | 6563 | switch (strat.tag) { |
| ... | ... | @@ -9134,7 +9138,9 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| 9134 | 9138 | .@"usingnamespace", |
| 9135 | 9139 | .test_decl, |
| 9136 | 9140 | .switch_case, |
| 9141 | .switch_case_inline, | |
| 9137 | 9142 | .switch_case_one, |
| 9143 | .switch_case_inline_one, | |
| 9138 | 9144 | .container_field_init, |
| 9139 | 9145 | .container_field_align, |
| 9140 | 9146 | .container_field, |
src/Sema.zig+15-15| ... | ... | @@ -9237,7 +9237,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9237 | 9237 | const special: struct { body: []const Zir.Inst.Index, end: usize } = switch (special_prong) { |
| 9238 | 9238 | .none => .{ .body = &.{}, .end = header_extra_index }, |
| 9239 | 9239 | .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]); | |
| 9241 | 9241 | const extra_body_start = header_extra_index + 1; |
| 9242 | 9242 | break :blk .{ |
| 9243 | 9243 | .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 |
| 9307 | 9307 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 9308 | 9308 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 9309 | 9309 | extra_index += 1; |
| 9310 | const body_len = sema.code.extra[extra_index]; | |
| 9310 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9311 | 9311 | extra_index += 1; |
| 9312 | 9312 | extra_index += body_len; |
| 9313 | 9313 | |
| ... | ... | @@ -9328,7 +9328,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9328 | 9328 | extra_index += 1; |
| 9329 | 9329 | const ranges_len = sema.code.extra[extra_index]; |
| 9330 | 9330 | extra_index += 1; |
| 9331 | const body_len = sema.code.extra[extra_index]; | |
| 9331 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9332 | 9332 | extra_index += 1; |
| 9333 | 9333 | const items = sema.code.refSlice(extra_index, items_len); |
| 9334 | 9334 | extra_index += items_len + body_len; |
| ... | ... | @@ -9407,7 +9407,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9407 | 9407 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 9408 | 9408 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 9409 | 9409 | extra_index += 1; |
| 9410 | const body_len = sema.code.extra[extra_index]; | |
| 9410 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9411 | 9411 | extra_index += 1; |
| 9412 | 9412 | extra_index += body_len; |
| 9413 | 9413 | |
| ... | ... | @@ -9427,7 +9427,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9427 | 9427 | extra_index += 1; |
| 9428 | 9428 | const ranges_len = sema.code.extra[extra_index]; |
| 9429 | 9429 | extra_index += 1; |
| 9430 | const body_len = sema.code.extra[extra_index]; | |
| 9430 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9431 | 9431 | extra_index += 1; |
| 9432 | 9432 | const items = sema.code.refSlice(extra_index, items_len); |
| 9433 | 9433 | extra_index += items_len + body_len; |
| ... | ... | @@ -9549,7 +9549,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9549 | 9549 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 9550 | 9550 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 9551 | 9551 | extra_index += 1; |
| 9552 | const body_len = sema.code.extra[extra_index]; | |
| 9552 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9553 | 9553 | extra_index += 1; |
| 9554 | 9554 | extra_index += body_len; |
| 9555 | 9555 | |
| ... | ... | @@ -9570,7 +9570,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9570 | 9570 | extra_index += 1; |
| 9571 | 9571 | const ranges_len = sema.code.extra[extra_index]; |
| 9572 | 9572 | extra_index += 1; |
| 9573 | const body_len = sema.code.extra[extra_index]; | |
| 9573 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9574 | 9574 | extra_index += 1; |
| 9575 | 9575 | const items = sema.code.refSlice(extra_index, items_len); |
| 9576 | 9576 | extra_index += items_len; |
| ... | ... | @@ -9647,7 +9647,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9647 | 9647 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 9648 | 9648 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 9649 | 9649 | extra_index += 1; |
| 9650 | const body_len = sema.code.extra[extra_index]; | |
| 9650 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9651 | 9651 | extra_index += 1; |
| 9652 | 9652 | extra_index += body_len; |
| 9653 | 9653 | |
| ... | ... | @@ -9668,7 +9668,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9668 | 9668 | extra_index += 1; |
| 9669 | 9669 | const ranges_len = sema.code.extra[extra_index]; |
| 9670 | 9670 | extra_index += 1; |
| 9671 | const body_len = sema.code.extra[extra_index]; | |
| 9671 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9672 | 9672 | extra_index += 1; |
| 9673 | 9673 | const items = sema.code.refSlice(extra_index, items_len); |
| 9674 | 9674 | extra_index += items_len + body_len; |
| ... | ... | @@ -9732,7 +9732,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9732 | 9732 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 9733 | 9733 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 9734 | 9734 | extra_index += 1; |
| 9735 | const body_len = sema.code.extra[extra_index]; | |
| 9735 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9736 | 9736 | extra_index += 1; |
| 9737 | 9737 | extra_index += body_len; |
| 9738 | 9738 | |
| ... | ... | @@ -9752,7 +9752,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9752 | 9752 | extra_index += 1; |
| 9753 | 9753 | const ranges_len = sema.code.extra[extra_index]; |
| 9754 | 9754 | extra_index += 1; |
| 9755 | const body_len = sema.code.extra[extra_index]; | |
| 9755 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9756 | 9756 | extra_index += 1; |
| 9757 | 9757 | const items = sema.code.refSlice(extra_index, items_len); |
| 9758 | 9758 | extra_index += items_len + body_len; |
| ... | ... | @@ -9832,7 +9832,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9832 | 9832 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 9833 | 9833 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 9834 | 9834 | extra_index += 1; |
| 9835 | const body_len = sema.code.extra[extra_index]; | |
| 9835 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9836 | 9836 | extra_index += 1; |
| 9837 | 9837 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 9838 | 9838 | extra_index += body_len; |
| ... | ... | @@ -9853,7 +9853,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9853 | 9853 | extra_index += 1; |
| 9854 | 9854 | const ranges_len = sema.code.extra[extra_index]; |
| 9855 | 9855 | extra_index += 1; |
| 9856 | const body_len = sema.code.extra[extra_index]; | |
| 9856 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9857 | 9857 | extra_index += 1; |
| 9858 | 9858 | const items = sema.code.refSlice(extra_index, items_len); |
| 9859 | 9859 | extra_index += items_len; |
| ... | ... | @@ -9926,7 +9926,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9926 | 9926 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 9927 | 9927 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 9928 | 9928 | extra_index += 1; |
| 9929 | const body_len = sema.code.extra[extra_index]; | |
| 9929 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9930 | 9930 | extra_index += 1; |
| 9931 | 9931 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 9932 | 9932 | extra_index += body_len; |
| ... | ... | @@ -9988,7 +9988,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9988 | 9988 | extra_index += 1; |
| 9989 | 9989 | const ranges_len = sema.code.extra[extra_index]; |
| 9990 | 9990 | extra_index += 1; |
| 9991 | const body_len = sema.code.extra[extra_index]; | |
| 9991 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | |
| 9992 | 9992 | extra_index += 1; |
| 9993 | 9993 | const items = sema.code.refSlice(extra_index, items_len); |
| 9994 | 9994 | extra_index += items_len; |
src/Zir.zig+8-8| ... | ... | @@ -2990,7 +2990,7 @@ pub const Inst = struct { |
| 2990 | 2990 | } |
| 2991 | 2991 | |
| 2992 | 2992 | if (self.bits.specialProng() != .none) { |
| 2993 | const body_len = zir.extra[extra_index]; | |
| 2993 | const body_len = @truncate(u31, zir.extra[extra_index]); | |
| 2994 | 2994 | extra_index += 1; |
| 2995 | 2995 | const body = zir.extra[extra_index..][0..body_len]; |
| 2996 | 2996 | extra_index += body.len; |
| ... | ... | @@ -3000,7 +3000,7 @@ pub const Inst = struct { |
| 3000 | 3000 | while (true) : (scalar_i += 1) { |
| 3001 | 3001 | const item = @intToEnum(Ref, zir.extra[extra_index]); |
| 3002 | 3002 | extra_index += 1; |
| 3003 | const body_len = zir.extra[extra_index]; | |
| 3003 | const body_len = @truncate(u31, zir.extra[extra_index]); | |
| 3004 | 3004 | extra_index += 1; |
| 3005 | 3005 | const body = zir.extra[extra_index..][0..body_len]; |
| 3006 | 3006 | extra_index += body.len; |
| ... | ... | @@ -3029,7 +3029,7 @@ pub const Inst = struct { |
| 3029 | 3029 | var extra_index: usize = extra_end + 1; |
| 3030 | 3030 | |
| 3031 | 3031 | if (self.bits.specialProng() != .none) { |
| 3032 | const body_len = zir.extra[extra_index]; | |
| 3032 | const body_len = @truncate(u31, zir.extra[extra_index]); | |
| 3033 | 3033 | extra_index += 1; |
| 3034 | 3034 | const body = zir.extra[extra_index..][0..body_len]; |
| 3035 | 3035 | extra_index += body.len; |
| ... | ... | @@ -3038,7 +3038,7 @@ pub const Inst = struct { |
| 3038 | 3038 | var scalar_i: usize = 0; |
| 3039 | 3039 | while (scalar_i < self.bits.scalar_cases_len) : (scalar_i += 1) { |
| 3040 | 3040 | extra_index += 1; |
| 3041 | const body_len = zir.extra[extra_index]; | |
| 3041 | const body_len = @truncate(u31, zir.extra[extra_index]); | |
| 3042 | 3042 | extra_index += 1; |
| 3043 | 3043 | extra_index += body_len; |
| 3044 | 3044 | } |
| ... | ... | @@ -3046,7 +3046,7 @@ pub const Inst = struct { |
| 3046 | 3046 | while (true) : (multi_i += 1) { |
| 3047 | 3047 | const items_len = zir.extra[extra_index]; |
| 3048 | 3048 | extra_index += 2; |
| 3049 | const body_len = zir.extra[extra_index]; | |
| 3049 | const body_len = @truncate(u31, zir.extra[extra_index]); | |
| 3050 | 3050 | extra_index += 1; |
| 3051 | 3051 | const items = zir.refSlice(extra_index, items_len); |
| 3052 | 3052 | extra_index += items_len; |
| ... | ... | @@ -3858,7 +3858,7 @@ fn findDeclsSwitch( |
| 3858 | 3858 | |
| 3859 | 3859 | const special_prong = extra.data.bits.specialProng(); |
| 3860 | 3860 | if (special_prong != .none) { |
| 3861 | const body_len = zir.extra[extra_index]; | |
| 3861 | const body_len = @truncate(u31, zir.extra[extra_index]); | |
| 3862 | 3862 | extra_index += 1; |
| 3863 | 3863 | const body = zir.extra[extra_index..][0..body_len]; |
| 3864 | 3864 | extra_index += body.len; |
| ... | ... | @@ -3871,7 +3871,7 @@ fn findDeclsSwitch( |
| 3871 | 3871 | var scalar_i: usize = 0; |
| 3872 | 3872 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 3873 | 3873 | extra_index += 1; |
| 3874 | const body_len = zir.extra[extra_index]; | |
| 3874 | const body_len = @truncate(u31, zir.extra[extra_index]); | |
| 3875 | 3875 | extra_index += 1; |
| 3876 | 3876 | const body = zir.extra[extra_index..][0..body_len]; |
| 3877 | 3877 | extra_index += body_len; |
| ... | ... | @@ -3886,7 +3886,7 @@ fn findDeclsSwitch( |
| 3886 | 3886 | extra_index += 1; |
| 3887 | 3887 | const ranges_len = zir.extra[extra_index]; |
| 3888 | 3888 | extra_index += 1; |
| 3889 | const body_len = zir.extra[extra_index]; | |
| 3889 | const body_len = @truncate(u31, zir.extra[extra_index]); | |
| 3890 | 3890 | extra_index += 1; |
| 3891 | 3891 | const items = zir.refSlice(extra_index, items_len); |
| 3892 | 3892 | extra_index += items_len; |
src/print_zir.zig+9-4| ... | ... | @@ -1868,14 +1868,15 @@ const Writer = struct { |
| 1868 | 1868 | else => break :else_prong, |
| 1869 | 1869 | }; |
| 1870 | 1870 | |
| 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 ""; | |
| 1872 | 1873 | extra_index += 1; |
| 1873 | 1874 | const body = self.code.extra[extra_index..][0..body_len]; |
| 1874 | 1875 | extra_index += body.len; |
| 1875 | 1876 | |
| 1876 | 1877 | try stream.writeAll(",\n"); |
| 1877 | 1878 | try stream.writeByteNTimes(' ', self.indent); |
| 1878 | try stream.print("{s} => ", .{prong_name}); | |
| 1879 | try stream.print("{s}{s} => ", .{ inline_text, prong_name }); | |
| 1879 | 1880 | try self.writeBracedBody(stream, body); |
| 1880 | 1881 | } |
| 1881 | 1882 | |
| ... | ... | @@ -1885,13 +1886,15 @@ const Writer = struct { |
| 1885 | 1886 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 1886 | 1887 | const item_ref = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); |
| 1887 | 1888 | 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; | |
| 1889 | 1891 | extra_index += 1; |
| 1890 | 1892 | const body = self.code.extra[extra_index..][0..body_len]; |
| 1891 | 1893 | extra_index += body_len; |
| 1892 | 1894 | |
| 1893 | 1895 | try stream.writeAll(",\n"); |
| 1894 | 1896 | try stream.writeByteNTimes(' ', self.indent); |
| 1897 | if (is_inline) try stream.writeAll("inline "); | |
| 1895 | 1898 | try self.writeInstRef(stream, item_ref); |
| 1896 | 1899 | try stream.writeAll(" => "); |
| 1897 | 1900 | try self.writeBracedBody(stream, body); |
| ... | ... | @@ -1904,13 +1907,15 @@ const Writer = struct { |
| 1904 | 1907 | extra_index += 1; |
| 1905 | 1908 | const ranges_len = self.code.extra[extra_index]; |
| 1906 | 1909 | 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; | |
| 1908 | 1912 | extra_index += 1; |
| 1909 | 1913 | const items = self.code.refSlice(extra_index, items_len); |
| 1910 | 1914 | extra_index += items_len; |
| 1911 | 1915 | |
| 1912 | 1916 | try stream.writeAll(",\n"); |
| 1913 | 1917 | try stream.writeByteNTimes(' ', self.indent); |
| 1918 | if (is_inline) try stream.writeAll("inline "); | |
| 1914 | 1919 | |
| 1915 | 1920 | for (items) |item_ref, item_i| { |
| 1916 | 1921 | 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 |
| 6987 | 6987 | assert(switch_node->type == NodeTypeSwitchExpr); |
| 6988 | 6988 | assert(prong_node->type == NodeTypeSwitchProng); |
| 6989 | 6989 | |
| 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 | ||
| 6990 | 6996 | AstNode *expr_node = prong_node->data.switch_prong.expr; |
| 6991 | 6997 | AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; |
| 6992 | 6998 | Scope *child_scope; |
test/cases/compile_errors/inline_underscore_prong.zig created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | const E = enum(u8) { a, b, c, d, _ }; | |
| 2 | pub 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 |