| ... | @@ -532,13 +532,15 @@ const DocData = struct { | ... | @@ -532,13 +532,15 @@ const DocData = struct { |
| 532 | // directly refer to their return value. The problem at the moment | 532 | // directly refer to their return value. The problem at the moment |
| 533 | // is that we can't analyze function calls at all. | 533 | // is that we can't analyze function calls at all. |
| 534 | call: usize, // index in `calls` | 534 | call: usize, // index in `calls` |
| | 535 | typeOf: *WalkResult, |
| 535 | | 536 | |
| 536 | pub fn jsonStringify( | 537 | pub fn jsonStringify( |
| 537 | self: TypeRef, | 538 | self: TypeRef, |
| 538 | _: std.json.StringifyOptions, | 539 | options: std.json.StringifyOptions, |
| 539 | w: anytype, | 540 | w: anytype, |
| 540 | ) !void { | 541 | ) !void { |
| 541 | switch (self) { | 542 | switch (self) { |
| | 543 | .typeOf => |v| try std.json.stringify(v, options, w), |
| 542 | .unspecified, .@"anytype" => { | 544 | .unspecified, .@"anytype" => { |
| 543 | try w.print( | 545 | try w.print( |
| 544 | \\{{ "{s}":{{}} }} | 546 | \\{{ "{s}":{{}} }} |
| ... | @@ -591,13 +593,19 @@ const DocData = struct { | ... | @@ -591,13 +593,19 @@ const DocData = struct { |
| 591 | array: Array, | 593 | array: Array, |
| 592 | call: usize, // index in `calls` | 594 | call: usize, // index in `calls` |
| 593 | enumLiteral: []const u8, | 595 | enumLiteral: []const u8, |
| | 596 | typeOf: *WalkResult, |
| | 597 | sizeOf: *WalkResult, |
| | 598 | compileError: []const u8, |
| | 599 | string: []const u8, |
| 594 | | 600 | |
| 595 | const Struct = struct { | 601 | const Struct = struct { |
| 596 | typeRef: TypeRef, | 602 | typeRef: TypeRef, |
| 597 | fieldVals: []struct { | 603 | fieldVals: []FieldVal, |
| | 604 | |
| | 605 | const FieldVal = struct { |
| 598 | name: []const u8, | 606 | name: []const u8, |
| 599 | val: WalkResult, | 607 | val: WalkResult, |
| 600 | }, | 608 | }; |
| 601 | }; | 609 | }; |
| 602 | const Array = struct { | 610 | const Array = struct { |
| 603 | typeRef: TypeRef, | 611 | typeRef: TypeRef, |
| ... | @@ -647,6 +655,9 @@ const DocData = struct { | ... | @@ -647,6 +655,9 @@ const DocData = struct { |
| 647 | }, | 655 | }, |
| 648 | .@"undefined" => |v| try std.json.stringify(v, options, w), | 656 | .@"undefined" => |v| try std.json.stringify(v, options, w), |
| 649 | .@"null" => |v| try std.json.stringify(v, options, w), | 657 | .@"null" => |v| try std.json.stringify(v, options, w), |
| | 658 | .typeOf, .sizeOf => |v| try std.json.stringify(v, options, w), |
| | 659 | .compileError => |v| try std.json.stringify(v, options, w), |
| | 660 | .string => |v| try std.json.stringify(v, options, w), |
| 650 | .@"struct" => |v| try std.json.stringify( | 661 | .@"struct" => |v| try std.json.stringify( |
| 651 | struct { @"struct": Struct }{ .@"struct" = v }, | 662 | struct { @"struct": Struct }{ .@"struct" = v }, |
| 652 | options, | 663 | options, |
| ... | @@ -709,11 +720,21 @@ fn walkInstruction( | ... | @@ -709,11 +720,21 @@ fn walkInstruction( |
| 709 | | 720 | |
| 710 | switch (tags[inst_index]) { | 721 | switch (tags[inst_index]) { |
| 711 | else => { | 722 | else => { |
| 712 | std.debug.panic( | 723 | panicWithContext( |
| | 724 | file, |
| | 725 | inst_index, |
| 713 | "TODO: implement `{s}` for walkInstruction\n\n", | 726 | "TODO: implement `{s}` for walkInstruction\n\n", |
| 714 | .{@tagName(tags[inst_index])}, | 727 | .{@tagName(tags[inst_index])}, |
| 715 | ); | 728 | ); |
| 716 | }, | 729 | }, |
| | 730 | .closure_get => { |
| | 731 | const inst_node = data[inst_index].inst_node; |
| | 732 | return try self.walkInstruction(file, parent_scope, inst_node.inst); |
| | 733 | }, |
| | 734 | .closure_capture => { |
| | 735 | const un_tok = data[inst_index].un_tok; |
| | 736 | return try self.walkRef(file, parent_scope, un_tok.operand); |
| | 737 | }, |
| 717 | .import => { | 738 | .import => { |
| 718 | const str_tok = data[inst_index].str_tok; | 739 | const str_tok = data[inst_index].str_tok; |
| 719 | const path = str_tok.get(file.zir); | 740 | const path = str_tok.get(file.zir); |
| ... | @@ -749,11 +770,46 @@ fn walkInstruction( | ... | @@ -749,11 +770,46 @@ fn walkInstruction( |
| 749 | | 770 | |
| 750 | return new_file_walk_result; | 771 | return new_file_walk_result; |
| 751 | }, | 772 | }, |
| | 773 | .str => { |
| | 774 | const str = data[inst_index].str; |
| | 775 | return DocData.WalkResult{ |
| | 776 | .string = str.get(file.zir), |
| | 777 | }; |
| | 778 | }, |
| | 779 | .compile_error => { |
| | 780 | const un_node = data[inst_index].un_node; |
| | 781 | var operand: DocData.WalkResult = try self.walkRef( |
| | 782 | file, |
| | 783 | parent_scope, |
| | 784 | un_node.operand, |
| | 785 | ); |
| | 786 | |
| | 787 | return DocData.WalkResult{ .compileError = operand.string }; |
| | 788 | }, |
| | 789 | .switch_block => { |
| | 790 | const cte_slot_index = self.comptime_exprs.items.len; |
| | 791 | try self.comptime_exprs.append(self.arena, .{ |
| | 792 | .code = "switch", |
| | 793 | .typeRef = .{ |
| | 794 | .type = @enumToInt(DocData.DocTypeKinds.ComptimeExpr), |
| | 795 | }, |
| | 796 | }); |
| | 797 | |
| | 798 | return DocData.WalkResult{ .comptimeExpr = cte_slot_index }; |
| | 799 | }, |
| 752 | .enum_literal => { | 800 | .enum_literal => { |
| 753 | const str_tok = data[inst_index].str_tok; | 801 | const str_tok = data[inst_index].str_tok; |
| 754 | const literal = file.zir.nullTerminatedString(str_tok.start); | 802 | const literal = file.zir.nullTerminatedString(str_tok.start); |
| 755 | return DocData.WalkResult{ .enumLiteral = literal }; | 803 | return DocData.WalkResult{ .enumLiteral = literal }; |
| 756 | }, | 804 | }, |
| | 805 | .div_exact, .div => { |
| | 806 | const cte_slot_index = self.comptime_exprs.items.len; |
| | 807 | try self.comptime_exprs.append(self.arena, .{ |
| | 808 | .code = "@div*(...)", |
| | 809 | .typeRef = .{ .type = @enumToInt(DocData.DocTypeKinds.ComptimeExpr) }, |
| | 810 | }); |
| | 811 | return DocData.WalkResult{ .comptimeExpr = cte_slot_index }; |
| | 812 | }, |
| 757 | .int => { | 813 | .int => { |
| 758 | const int = data[inst_index].int; | 814 | const int = data[inst_index].int; |
| 759 | return DocData.WalkResult{ | 815 | return DocData.WalkResult{ |
| ... | @@ -785,6 +841,25 @@ fn walkInstruction( | ... | @@ -785,6 +841,25 @@ fn walkInstruction( |
| 785 | | 841 | |
| 786 | return DocData.WalkResult{ .type = type_slot_index }; | 842 | return DocData.WalkResult{ .type = type_slot_index }; |
| 787 | }, | 843 | }, |
| | 844 | .ptr_type => { |
| | 845 | const ptr = data[inst_index].ptr_type; |
| | 846 | const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index); |
| | 847 | |
| | 848 | const type_slot_index = self.types.items.len; |
| | 849 | const elem_type_ref = try self.walkRef( |
| | 850 | file, |
| | 851 | parent_scope, |
| | 852 | extra.data.elem_type, |
| | 853 | ); |
| | 854 | try self.types.append(self.arena, .{ |
| | 855 | .Pointer = .{ |
| | 856 | .size = ptr.size, |
| | 857 | .child = walkResultToTypeRef(elem_type_ref), |
| | 858 | }, |
| | 859 | }); |
| | 860 | |
| | 861 | return DocData.WalkResult{ .type = type_slot_index }; |
| | 862 | }, |
| 788 | .array_type => { | 863 | .array_type => { |
| 789 | const bin = data[inst_index].bin; | 864 | const bin = data[inst_index].bin; |
| 790 | const len = try self.walkRef(file, parent_scope, bin.lhs); | 865 | const len = try self.walkRef(file, parent_scope, bin.lhs); |
| ... | @@ -848,6 +923,27 @@ fn walkInstruction( | ... | @@ -848,6 +923,27 @@ fn walkInstruction( |
| 848 | operand.int.negated = true; // only support ints for now | 923 | operand.int.negated = true; // only support ints for now |
| 849 | return operand; | 924 | return operand; |
| 850 | }, | 925 | }, |
| | 926 | .size_of => { |
| | 927 | const un_node = data[inst_index].un_node; |
| | 928 | var operand = try self.arena.create(DocData.WalkResult); |
| | 929 | operand.* = try self.walkRef( |
| | 930 | file, |
| | 931 | parent_scope, |
| | 932 | un_node.operand, |
| | 933 | ); |
| | 934 | return DocData.WalkResult{ .sizeOf = operand }; |
| | 935 | }, |
| | 936 | |
| | 937 | .typeof => { |
| | 938 | const un_node = data[inst_index].un_node; |
| | 939 | var operand = try self.arena.create(DocData.WalkResult); |
| | 940 | operand.* = try self.walkRef( |
| | 941 | file, |
| | 942 | parent_scope, |
| | 943 | un_node.operand, |
| | 944 | ); |
| | 945 | return DocData.WalkResult{ .typeOf = operand }; |
| | 946 | }, |
| 851 | .as_node => { | 947 | .as_node => { |
| 852 | const pl_node = data[inst_index].pl_node; | 948 | const pl_node = data[inst_index].pl_node; |
| 853 | const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index); | 949 | const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index); |
| ... | @@ -857,11 +953,13 @@ fn walkInstruction( | ... | @@ -857,11 +953,13 @@ fn walkInstruction( |
| 857 | var operand = try self.walkRef(file, parent_scope, extra.data.operand); | 953 | var operand = try self.walkRef(file, parent_scope, extra.data.operand); |
| 858 | | 954 | |
| 859 | switch (operand) { | 955 | switch (operand) { |
| 860 | else => std.debug.panic( | 956 | else => panicWithContext( |
| | 957 | file, |
| | 958 | inst_index, |
| 861 | "TODO: handle {s} in `walkInstruction.as_node`\n", | 959 | "TODO: handle {s} in `walkInstruction.as_node`\n", |
| 862 | .{@tagName(operand)}, | 960 | .{@tagName(operand)}, |
| 863 | ), | 961 | ), |
| 864 | .declPath, .type => {}, | 962 | .declPath, .type, .string => {}, |
| 865 | // we don't do anything because up until now, | 963 | // we don't do anything because up until now, |
| 866 | // I've only seen this used as such: | 964 | // I've only seen this used as such: |
| 867 | // @as(@as(type, Baz), .{}) | 965 | // @as(@as(type, Baz), .{}) |
| ... | @@ -894,14 +992,16 @@ fn walkInstruction( | ... | @@ -894,14 +992,16 @@ fn walkInstruction( |
| 894 | }); | 992 | }); |
| 895 | return res; | 993 | return res; |
| 896 | }, | 994 | }, |
| 897 | .decl_val => { | 995 | .decl_val, .decl_ref => { |
| 898 | const str_tok = data[inst_index].str_tok; | 996 | const str_tok = data[inst_index].str_tok; |
| 899 | const decls_slot_index = parent_scope.resolveDeclName(str_tok.start); | 997 | const decls_slot_index = parent_scope.resolveDeclName(str_tok.start); |
| 900 | var path = try self.arena.alloc(usize, 1); | 998 | var path = try self.arena.alloc(usize, 1); |
| 901 | path[0] = decls_slot_index; | 999 | path[0] = decls_slot_index; |
| 902 | return DocData.WalkResult{ .declPath = .{ .path = path } }; | 1000 | return DocData.WalkResult{ .declPath = .{ .path = path } }; |
| 903 | }, | 1001 | }, |
| 904 | .field_val, .field_call_bind, .field_ptr => { | 1002 | .field_val, .field_call_bind, .field_ptr, .field_type => { |
| | 1003 | // TODO: field type uses Zir.Inst.FieldType, it just happens to have the |
| | 1004 | // same layout as Zir.Inst.Field :^) |
| 905 | const pl_node = data[inst_index].pl_node; | 1005 | const pl_node = data[inst_index].pl_node; |
| 906 | const extra = file.zir.extraData(Zir.Inst.Field, pl_node.payload_index); | 1006 | const extra = file.zir.extraData(Zir.Inst.Field, pl_node.payload_index); |
| 907 | | 1007 | |
| ... | @@ -909,8 +1009,8 @@ fn walkInstruction( | ... | @@ -909,8 +1009,8 @@ fn walkInstruction( |
| 909 | var lhs = @enumToInt(extra.data.lhs) - Ref.typed_value_map.len; // underflow = need to handle Refs | 1009 | var lhs = @enumToInt(extra.data.lhs) - Ref.typed_value_map.len; // underflow = need to handle Refs |
| 910 | | 1010 | |
| 911 | try path.append(self.arena, extra.data.field_name_start); | 1011 | try path.append(self.arena, extra.data.field_name_start); |
| 912 | // Put inside path the starting index of each decl name | 1012 | // Put inside path the starting index of each decl name that |
| 913 | // that we encounter as we navigate through all the field_vals | 1013 | // we encounter as we navigate through all the field_vals |
| 914 | while (tags[lhs] == .field_val or | 1014 | while (tags[lhs] == .field_val or |
| 915 | tags[lhs] == .field_call_bind or | 1015 | tags[lhs] == .field_call_bind or |
| 916 | tags[lhs] == .field_ptr) | 1016 | tags[lhs] == .field_ptr) |
| ... | @@ -925,11 +1025,35 @@ fn walkInstruction( | ... | @@ -925,11 +1025,35 @@ fn walkInstruction( |
| 925 | } | 1025 | } |
| 926 | | 1026 | |
| 927 | switch (tags[lhs]) { | 1027 | switch (tags[lhs]) { |
| 928 | else => { | 1028 | else => panicWithContext( |
| 929 | std.debug.panic( | 1029 | file, |
| 930 | "TODO: handle `{s}` endings in walkInstruction.field_val", | 1030 | inst_index, |
| 931 | .{@tagName(tags[lhs])}, | 1031 | "TODO: handle `{s}` in walkInstruction.field_val", |
| 932 | ); | 1032 | .{@tagName(tags[lhs])}, |
| | 1033 | ), |
| | 1034 | .call => { |
| | 1035 | const walk_result = try self.walkInstruction(file, parent_scope, lhs); |
| | 1036 | const ast_node_index = idx: { |
| | 1037 | const idx = self.ast_nodes.items.len; |
| | 1038 | try self.ast_nodes.append(self.arena, .{ |
| | 1039 | .file = 0, |
| | 1040 | .line = 0, |
| | 1041 | .col = 0, |
| | 1042 | .docs = "", |
| | 1043 | .fields = null, |
| | 1044 | }); |
| | 1045 | break :idx idx; |
| | 1046 | }; |
| | 1047 | |
| | 1048 | const decls_slot_index = self.decls.items.len; |
| | 1049 | try self.decls.append(self.arena, .{ |
| | 1050 | ._analyzed = true, |
| | 1051 | .name = "call()", |
| | 1052 | .src = ast_node_index, |
| | 1053 | .value = walk_result, |
| | 1054 | .kind = "const", |
| | 1055 | }); |
| | 1056 | try path.append(self.arena, decls_slot_index); |
| 933 | }, | 1057 | }, |
| 934 | .import => { | 1058 | .import => { |
| 935 | const walk_result = try self.walkInstruction(file, parent_scope, lhs); | 1059 | const walk_result = try self.walkInstruction(file, parent_scope, lhs); |
| ... | @@ -942,7 +1066,7 @@ fn walkInstruction( | ... | @@ -942,7 +1066,7 @@ fn walkInstruction( |
| 942 | .line = 0, | 1066 | .line = 0, |
| 943 | .col = 0, | 1067 | .col = 0, |
| 944 | .docs = "", | 1068 | .docs = "", |
| 945 | .fields = null, // walkInstruction will fill `fields` if necessary | 1069 | .fields = null, |
| 946 | }); | 1070 | }); |
| 947 | break :idx idx; | 1071 | break :idx idx; |
| 948 | }; | 1072 | }; |
| ... | @@ -999,6 +1123,76 @@ fn walkInstruction( | ... | @@ -999,6 +1123,76 @@ fn walkInstruction( |
| 999 | .block_inline => { | 1123 | .block_inline => { |
| 1000 | return self.walkRef(file, parent_scope, getBlockInlineBreak(file.zir, inst_index)); | 1124 | return self.walkRef(file, parent_scope, getBlockInlineBreak(file.zir, inst_index)); |
| 1001 | }, | 1125 | }, |
| | 1126 | .struct_init => { |
| | 1127 | const pl_node = data[inst_index].pl_node; |
| | 1128 | const extra = file.zir.extraData(Zir.Inst.StructInit, pl_node.payload_index); |
| | 1129 | const field_vals = try self.arena.alloc( |
| | 1130 | DocData.WalkResult.Struct.FieldVal, |
| | 1131 | extra.data.fields_len, |
| | 1132 | ); |
| | 1133 | |
| | 1134 | var type_ref: DocData.TypeRef = undefined; |
| | 1135 | var idx = extra.end; |
| | 1136 | for (field_vals) |*fv| { |
| | 1137 | const init_extra = file.zir.extraData(Zir.Inst.StructInit.Item, idx); |
| | 1138 | idx = init_extra.end; |
| | 1139 | |
| | 1140 | const field_name = blk: { |
| | 1141 | const field_inst_index = init_extra.data.field_type; |
| | 1142 | if (tags[field_inst_index] != .field_type) unreachable; |
| | 1143 | const field_pl_node = data[field_inst_index].pl_node; |
| | 1144 | const field_extra = file.zir.extraData( |
| | 1145 | Zir.Inst.FieldType, |
| | 1146 | field_pl_node.payload_index, |
| | 1147 | ); |
| | 1148 | |
| | 1149 | // On first iteration use field info to find out the struct type |
| | 1150 | if (idx == extra.end) { |
| | 1151 | const wr = try self.walkRef( |
| | 1152 | file, |
| | 1153 | parent_scope, |
| | 1154 | field_extra.data.container_type, |
| | 1155 | ); |
| | 1156 | type_ref = walkResultToTypeRef(wr); |
| | 1157 | } |
| | 1158 | break :blk file.zir.nullTerminatedString(field_extra.data.name_start); |
| | 1159 | }; |
| | 1160 | |
| | 1161 | const value = try self.walkRef(file, parent_scope, init_extra.data.init); |
| | 1162 | fv.* = .{ .name = field_name, .val = value }; |
| | 1163 | } |
| | 1164 | |
| | 1165 | return DocData.WalkResult{ .@"struct" = .{ |
| | 1166 | .typeRef = type_ref, |
| | 1167 | .fieldVals = field_vals, |
| | 1168 | } }; |
| | 1169 | }, |
| | 1170 | .param_anytype => { |
| | 1171 | // Analysis of anytype function params happens in `.func`. |
| | 1172 | // This switch case handles the case where an expression depends |
| | 1173 | // on an anytype field. E.g.: `fn foo(bar: anytype) @TypeOf(bar)`. |
| | 1174 | // This means that we're looking at a generic expression. |
| | 1175 | const str_tok = data[inst_index].str_tok; |
| | 1176 | const name = str_tok.get(file.zir); |
| | 1177 | const cte_slot_index = self.comptime_exprs.items.len; |
| | 1178 | try self.comptime_exprs.append(self.arena, .{ |
| | 1179 | .code = name, |
| | 1180 | .typeRef = .{ .type = @enumToInt(DocData.DocTypeKinds.ComptimeExpr) }, |
| | 1181 | }); |
| | 1182 | return DocData.WalkResult{ .comptimeExpr = cte_slot_index }; |
| | 1183 | }, |
| | 1184 | .param, .param_comptime => { |
| | 1185 | // See .param_anytype for more information. |
| | 1186 | const pl_tok = data[inst_index].pl_tok; |
| | 1187 | const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index); |
| | 1188 | const name = file.zir.nullTerminatedString(extra.data.name); |
| | 1189 | const cte_slot_index = self.comptime_exprs.items.len; |
| | 1190 | try self.comptime_exprs.append(self.arena, .{ |
| | 1191 | .code = name, |
| | 1192 | .typeRef = .{ .type = @enumToInt(DocData.DocTypeKinds.ComptimeExpr) }, |
| | 1193 | }); |
| | 1194 | return DocData.WalkResult{ .comptimeExpr = cte_slot_index }; |
| | 1195 | }, |
| 1002 | .call => { | 1196 | .call => { |
| 1003 | const pl_node = data[inst_index].pl_node; | 1197 | const pl_node = data[inst_index].pl_node; |
| 1004 | const extra = file.zir.extraData(Zir.Inst.Call, pl_node.payload_index); | 1198 | const extra = file.zir.extraData(Zir.Inst.Call, pl_node.payload_index); |
| ... | @@ -1048,12 +1242,12 @@ fn walkInstruction( | ... | @@ -1048,12 +1242,12 @@ fn walkInstruction( |
| 1048 | // TODO: handle scope rules for fn parameters | 1242 | // TODO: handle scope rules for fn parameters |
| 1049 | for (fn_info.param_body[0..fn_info.total_params_len]) |param_index| { | 1243 | for (fn_info.param_body[0..fn_info.total_params_len]) |param_index| { |
| 1050 | switch (tags[param_index]) { | 1244 | switch (tags[param_index]) { |
| 1051 | else => { | 1245 | else => panicWithContext( |
| 1052 | std.debug.panic( | 1246 | file, |
| 1053 | "TODO: handle `{s}` in walkInstruction.func\n", | 1247 | param_index, |
| 1054 | .{@tagName(tags[param_index])}, | 1248 | "TODO: handle `{s}` in walkInstruction.func\n", |
| 1055 | ); | 1249 | .{@tagName(tags[param_index])}, |
| 1056 | }, | 1250 | ), |
| 1057 | .param_anytype => { | 1251 | .param_anytype => { |
| 1058 | // TODO: where are the doc comments? | 1252 | // TODO: where are the doc comments? |
| 1059 | const str_tok = data[param_index].str_tok; | 1253 | const str_tok = data[param_index].str_tok; |
| ... | @@ -2158,6 +2352,8 @@ fn walkResultToTypeRef(wr: DocData.WalkResult) DocData.TypeRef { | ... | @@ -2158,6 +2352,8 @@ fn walkResultToTypeRef(wr: DocData.WalkResult) DocData.TypeRef { |
| 2158 | .{@tagName(wr)}, | 2352 | .{@tagName(wr)}, |
| 2159 | ), | 2353 | ), |
| 2160 | | 2354 | |
| | 2355 | .typeOf => |v| .{ .typeOf = v }, |
| | 2356 | .comptimeExpr => |v| .{ .comptimeExpr = v }, |
| 2161 | .declPath => |v| .{ .declPath = v }, | 2357 | .declPath => |v| .{ .declPath = v }, |
| 2162 | .type => |v| .{ .type = v }, | 2358 | .type => |v| .{ .type = v }, |
| 2163 | .call => |v| .{ .call = v }, | 2359 | .call => |v| .{ .call = v }, |
| ... | @@ -2187,3 +2383,8 @@ fn getBlockInlineBreak(zir: Zir, inst_index: usize) Zir.Inst.Ref { | ... | @@ -2187,3 +2383,8 @@ fn getBlockInlineBreak(zir: Zir, inst_index: usize) Zir.Inst.Ref { |
| 2187 | const break_index = zir.extra[extra.end..][extra.data.body_len - 1]; | 2383 | const break_index = zir.extra[extra.end..][extra.data.body_len - 1]; |
| 2188 | return data[break_index].@"break".operand; | 2384 | return data[break_index].@"break".operand; |
| 2189 | } | 2385 | } |
| | 2386 | |
| | 2387 | fn panicWithContext(file: *File, inst: usize, comptime fmt: []const u8, args: anytype) noreturn { |
| | 2388 | std.debug.print("Context [{s}] % {}\n", .{ file.sub_file_path, inst }); |
| | 2389 | std.debug.panic(fmt, args); |
| | 2390 | } |