| ... | @@ -117,7 +117,103 @@ const build_options = @import("build_options"); | ... | @@ -117,7 +117,103 @@ const build_options = @import("build_options"); |
| 117 | pub const default_branch_quota = 1000; | 117 | pub const default_branch_quota = 1000; |
| 118 | pub const default_reference_trace_len = 2; | 118 | pub const default_reference_trace_len = 2; |
| 119 | | 119 | |
| 120 | pub const InstMap = std.AutoHashMapUnmanaged(Zir.Inst.Index, Air.Inst.Ref); | 120 | /// Stores the mapping from `Zir.Inst.Index -> Air.Inst.Ref`, which is used by sema to resolve |
| | 121 | /// instructions during analysis. |
| | 122 | /// Instead of a hash table approach, InstMap is simply a slice that is indexed into using the |
| | 123 | /// zir instruction index and a start offset. An index is not pressent in the map if the value |
| | 124 | /// at the index is `Air.Inst.Ref.none`. |
| | 125 | /// `ensureSpaceForInstructions` can be called to force InstMap to have a mapped range that |
| | 126 | /// includes all instructions in a slice. After calling this function, `putAssumeCapacity*` can |
| | 127 | /// be called safely for any of the instructions passed in. |
| | 128 | pub const InstMap = struct { |
| | 129 | items: []Air.Inst.Ref = &[_]Air.Inst.Ref{}, |
| | 130 | start: Zir.Inst.Index = 0, |
| | 131 | |
| | 132 | pub fn deinit(map: InstMap, allocator: mem.Allocator) void { |
| | 133 | allocator.free(map.items); |
| | 134 | } |
| | 135 | |
| | 136 | pub fn get(map: InstMap, key: Zir.Inst.Index) ?Air.Inst.Ref { |
| | 137 | if (!map.contains(key)) return null; |
| | 138 | return map.items[key - map.start]; |
| | 139 | } |
| | 140 | |
| | 141 | pub fn putAssumeCapacity( |
| | 142 | map: *InstMap, |
| | 143 | key: Zir.Inst.Index, |
| | 144 | ref: Air.Inst.Ref, |
| | 145 | ) void { |
| | 146 | map.items[key - map.start] = ref; |
| | 147 | } |
| | 148 | |
| | 149 | pub fn putAssumeCapacityNoClobber( |
| | 150 | map: *InstMap, |
| | 151 | key: Zir.Inst.Index, |
| | 152 | ref: Air.Inst.Ref, |
| | 153 | ) void { |
| | 154 | assert(!map.contains(key)); |
| | 155 | map.putAssumeCapacity(key, ref); |
| | 156 | } |
| | 157 | |
| | 158 | pub const GetOrPutResult = struct { |
| | 159 | value_ptr: *Air.Inst.Ref, |
| | 160 | found_existing: bool, |
| | 161 | }; |
| | 162 | |
| | 163 | pub fn getOrPutAssumeCapacity( |
| | 164 | map: *InstMap, |
| | 165 | key: Zir.Inst.Index, |
| | 166 | ) GetOrPutResult { |
| | 167 | const index = key - map.start; |
| | 168 | return GetOrPutResult{ |
| | 169 | .value_ptr = &map.items[index], |
| | 170 | .found_existing = map.items[index] != .none, |
| | 171 | }; |
| | 172 | } |
| | 173 | |
| | 174 | pub fn remove(map: InstMap, key: Zir.Inst.Index) bool { |
| | 175 | if (!map.contains(key)) return false; |
| | 176 | map.items[key - map.start] = .none; |
| | 177 | return true; |
| | 178 | } |
| | 179 | |
| | 180 | pub fn contains(map: InstMap, key: Zir.Inst.Index) bool { |
| | 181 | return map.items[key - map.start] != .none; |
| | 182 | } |
| | 183 | |
| | 184 | pub fn ensureSpaceForInstructions( |
| | 185 | map: *InstMap, |
| | 186 | allocator: mem.Allocator, |
| | 187 | insts: []const Zir.Inst.Index, |
| | 188 | ) !void { |
| | 189 | const min_max = mem.minMax(Zir.Inst.Index, insts); |
| | 190 | const start = min_max.min; |
| | 191 | const end = min_max.max; |
| | 192 | if (map.start <= start and end < map.items.len + map.start) |
| | 193 | return; |
| | 194 | |
| | 195 | const old_start = if (map.items.len == 0) start else map.start; |
| | 196 | var better_capacity = map.items.len; |
| | 197 | var better_start = old_start; |
| | 198 | while (true) { |
| | 199 | const extra_capacity = better_capacity / 2 + 16; |
| | 200 | better_capacity += extra_capacity; |
| | 201 | better_start -|= @intCast(Zir.Inst.Index, extra_capacity / 2); |
| | 202 | if (better_start <= start and end < better_capacity + better_start) |
| | 203 | break; |
| | 204 | } |
| | 205 | |
| | 206 | const start_diff = old_start - better_start; |
| | 207 | const new_items = try allocator.alloc(Air.Inst.Ref, better_capacity); |
| | 208 | mem.set(Air.Inst.Ref, new_items[0..start_diff], .none); |
| | 209 | mem.copy(Air.Inst.Ref, new_items[start_diff..], map.items); |
| | 210 | mem.set(Air.Inst.Ref, new_items[start_diff + map.items.len ..], .none); |
| | 211 | |
| | 212 | allocator.free(map.items); |
| | 213 | map.items = new_items; |
| | 214 | map.start = @intCast(Zir.Inst.Index, better_start); |
| | 215 | } |
| | 216 | }; |
| 121 | | 217 | |
| 122 | /// This is the context needed to semantically analyze ZIR instructions and | 218 | /// This is the context needed to semantically analyze ZIR instructions and |
| 123 | /// produce AIR instructions. | 219 | /// produce AIR instructions. |
| ... | @@ -753,6 +849,8 @@ fn analyzeBodyInner( | ... | @@ -753,6 +849,8 @@ fn analyzeBodyInner( |
| 753 | ) CompileError!Zir.Inst.Index { | 849 | ) CompileError!Zir.Inst.Index { |
| 754 | // No tracy calls here, to avoid interfering with the tail call mechanism. | 850 | // No tracy calls here, to avoid interfering with the tail call mechanism. |
| 755 | | 851 | |
| | 852 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body); |
| | 853 | |
| 756 | const parent_capture_scope = block.wip_capture_scope; | 854 | const parent_capture_scope = block.wip_capture_scope; |
| 757 | | 855 | |
| 758 | var wip_captures = WipCaptureScope{ | 856 | var wip_captures = WipCaptureScope{ |
| ... | @@ -1443,7 +1541,7 @@ fn analyzeBodyInner( | ... | @@ -1443,7 +1541,7 @@ fn analyzeBodyInner( |
| 1443 | labeled_block.destroy(gpa); | 1541 | labeled_block.destroy(gpa); |
| 1444 | assert(sema.post_hoc_blocks.remove(new_block_inst)); | 1542 | assert(sema.post_hoc_blocks.remove(new_block_inst)); |
| 1445 | } | 1543 | } |
| 1446 | try map.put(gpa, inst, block_result); | 1544 | map.putAssumeCapacity(inst, block_result); |
| 1447 | i += 1; | 1545 | i += 1; |
| 1448 | continue; | 1546 | continue; |
| 1449 | } | 1547 | } |
| ... | @@ -1622,7 +1720,7 @@ fn analyzeBodyInner( | ... | @@ -1622,7 +1720,7 @@ fn analyzeBodyInner( |
| 1622 | const extra = sema.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data; | 1720 | const extra = sema.code.extraData(Zir.Inst.DeferErrCode, inst_data.payload_index).data; |
| 1623 | const defer_body = sema.code.extra[extra.index..][0..extra.len]; | 1721 | const defer_body = sema.code.extra[extra.index..][0..extra.len]; |
| 1624 | const err_code = try sema.resolveInst(inst_data.err_code); | 1722 | const err_code = try sema.resolveInst(inst_data.err_code); |
| 1625 | try sema.inst_map.put(sema.gpa, extra.remapped_err_code, err_code); | 1723 | sema.inst_map.putAssumeCapacity(extra.remapped_err_code, err_code); |
| 1626 | const break_inst = sema.analyzeBodyInner(block, defer_body) catch |err| switch (err) { | 1724 | const break_inst = sema.analyzeBodyInner(block, defer_body) catch |err| switch (err) { |
| 1627 | error.ComptimeBreak => sema.comptime_break_inst, | 1725 | error.ComptimeBreak => sema.comptime_break_inst, |
| 1628 | else => |e| return e, | 1726 | else => |e| return e, |
| ... | @@ -1633,7 +1731,7 @@ fn analyzeBodyInner( | ... | @@ -1633,7 +1731,7 @@ fn analyzeBodyInner( |
| 1633 | }; | 1731 | }; |
| 1634 | if (sema.typeOf(air_inst).isNoReturn()) | 1732 | if (sema.typeOf(air_inst).isNoReturn()) |
| 1635 | break always_noreturn; | 1733 | break always_noreturn; |
| 1636 | try map.put(sema.gpa, inst, air_inst); | 1734 | map.putAssumeCapacity(inst, air_inst); |
| 1637 | i += 1; | 1735 | i += 1; |
| 1638 | } else unreachable; | 1736 | } else unreachable; |
| 1639 | | 1737 | |
| ... | @@ -5980,7 +6078,7 @@ fn zirCall( | ... | @@ -5980,7 +6078,7 @@ fn zirCall( |
| 5980 | } | 6078 | } |
| 5981 | | 6079 | |
| 5982 | const param_ty_inst = try sema.addType(param_ty); | 6080 | const param_ty_inst = try sema.addType(param_ty); |
| 5983 | try sema.inst_map.put(sema.gpa, inst, param_ty_inst); | 6081 | sema.inst_map.putAssumeCapacity(inst, param_ty_inst); |
| 5984 | | 6082 | |
| 5985 | const resolved = try sema.resolveBody(block, args_body[arg_start..arg_end], inst); | 6083 | const resolved = try sema.resolveBody(block, args_body[arg_start..arg_end], inst); |
| 5986 | const resolved_ty = sema.typeOf(resolved); | 6084 | const resolved_ty = sema.typeOf(resolved); |
| ... | @@ -6368,6 +6466,8 @@ fn analyzeCall( | ... | @@ -6368,6 +6466,8 @@ fn analyzeCall( |
| 6368 | // which means its parameter type expressions must be resolved in order and used | 6466 | // which means its parameter type expressions must be resolved in order and used |
| 6369 | // to successively coerce the arguments. | 6467 | // to successively coerce the arguments. |
| 6370 | const fn_info = sema.code.getFnInfo(module_fn.zir_body_inst); | 6468 | const fn_info = sema.code.getFnInfo(module_fn.zir_body_inst); |
| | 6469 | try sema.inst_map.ensureSpaceForInstructions(sema.gpa, fn_info.param_body); |
| | 6470 | |
| 6371 | var arg_i: usize = 0; | 6471 | var arg_i: usize = 0; |
| 6372 | for (fn_info.param_body) |inst| { | 6472 | for (fn_info.param_body) |inst| { |
| 6373 | sema.analyzeInlineCallArg( | 6473 | sema.analyzeInlineCallArg( |
| ... | @@ -6662,7 +6762,7 @@ fn analyzeInlineCallArg( | ... | @@ -6662,7 +6762,7 @@ fn analyzeInlineCallArg( |
| 6662 | const casted_arg = try sema.coerce(arg_block, param_ty, uncasted_arg, arg_src); | 6762 | const casted_arg = try sema.coerce(arg_block, param_ty, uncasted_arg, arg_src); |
| 6663 | | 6763 | |
| 6664 | if (is_comptime_call) { | 6764 | if (is_comptime_call) { |
| 6665 | try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg); | 6765 | sema.inst_map.putAssumeCapacityNoClobber(inst, casted_arg); |
| 6666 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime-known") catch |err| { | 6766 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime-known") catch |err| { |
| 6667 | if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err); | 6767 | if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err); |
| 6668 | return err; | 6768 | return err; |
| ... | @@ -6686,13 +6786,13 @@ fn analyzeInlineCallArg( | ... | @@ -6686,13 +6786,13 @@ fn analyzeInlineCallArg( |
| 6686 | .val = arg_val, | 6786 | .val = arg_val, |
| 6687 | }; | 6787 | }; |
| 6688 | } else if (zir_tags[inst] == .param_comptime or try sema.typeRequiresComptime(param_ty)) { | 6788 | } else if (zir_tags[inst] == .param_comptime or try sema.typeRequiresComptime(param_ty)) { |
| 6689 | try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg); | 6789 | sema.inst_map.putAssumeCapacityNoClobber(inst, casted_arg); |
| 6690 | } else if (try sema.resolveMaybeUndefVal(casted_arg)) |val| { | 6790 | } else if (try sema.resolveMaybeUndefVal(casted_arg)) |val| { |
| 6691 | // We have a comptime value but we need a runtime value to preserve inlining semantics, | 6791 | // We have a comptime value but we need a runtime value to preserve inlining semantics, |
| 6692 | const wrapped = try sema.addConstant(param_ty, try Value.Tag.runtime_value.create(sema.arena, val)); | 6792 | const wrapped = try sema.addConstant(param_ty, try Value.Tag.runtime_value.create(sema.arena, val)); |
| 6693 | try sema.inst_map.putNoClobber(sema.gpa, inst, wrapped); | 6793 | sema.inst_map.putAssumeCapacityNoClobber(inst, wrapped); |
| 6694 | } else { | 6794 | } else { |
| 6695 | try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg); | 6795 | sema.inst_map.putAssumeCapacityNoClobber(inst, casted_arg); |
| 6696 | } | 6796 | } |
| 6697 | | 6797 | |
| 6698 | arg_i.* += 1; | 6798 | arg_i.* += 1; |
| ... | @@ -6704,7 +6804,7 @@ fn analyzeInlineCallArg( | ... | @@ -6704,7 +6804,7 @@ fn analyzeInlineCallArg( |
| 6704 | const param_ty = sema.typeOf(uncasted_arg); | 6804 | const param_ty = sema.typeOf(uncasted_arg); |
| 6705 | | 6805 | |
| 6706 | if (is_comptime_call) { | 6806 | if (is_comptime_call) { |
| 6707 | try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg); | 6807 | sema.inst_map.putAssumeCapacityNoClobber(inst, uncasted_arg); |
| 6708 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime-known") catch |err| { | 6808 | const arg_val = sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime-known") catch |err| { |
| 6709 | if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err); | 6809 | if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err); |
| 6710 | return err; | 6810 | return err; |
| ... | @@ -6728,13 +6828,13 @@ fn analyzeInlineCallArg( | ... | @@ -6728,13 +6828,13 @@ fn analyzeInlineCallArg( |
| 6728 | .val = arg_val, | 6828 | .val = arg_val, |
| 6729 | }; | 6829 | }; |
| 6730 | } else if (zir_tags[inst] == .param_anytype_comptime or try sema.typeRequiresComptime(param_ty)) { | 6830 | } else if (zir_tags[inst] == .param_anytype_comptime or try sema.typeRequiresComptime(param_ty)) { |
| 6731 | try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg); | 6831 | sema.inst_map.putAssumeCapacityNoClobber(inst, uncasted_arg); |
| 6732 | } else if (try sema.resolveMaybeUndefVal(uncasted_arg)) |val| { | 6832 | } else if (try sema.resolveMaybeUndefVal(uncasted_arg)) |val| { |
| 6733 | // We have a comptime value but we need a runtime value to preserve inlining semantics, | 6833 | // We have a comptime value but we need a runtime value to preserve inlining semantics, |
| 6734 | const wrapped = try sema.addConstant(param_ty, try Value.Tag.runtime_value.create(sema.arena, val)); | 6834 | const wrapped = try sema.addConstant(param_ty, try Value.Tag.runtime_value.create(sema.arena, val)); |
| 6735 | try sema.inst_map.putNoClobber(sema.gpa, inst, wrapped); | 6835 | sema.inst_map.putAssumeCapacityNoClobber(inst, wrapped); |
| 6736 | } else { | 6836 | } else { |
| 6737 | try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg); | 6837 | sema.inst_map.putAssumeCapacityNoClobber(inst, uncasted_arg); |
| 6738 | } | 6838 | } |
| 6739 | | 6839 | |
| 6740 | arg_i.* += 1; | 6840 | arg_i.* += 1; |
| ... | @@ -7008,7 +7108,8 @@ fn instantiateGenericCall( | ... | @@ -7008,7 +7108,8 @@ fn instantiateGenericCall( |
| 7008 | child_block.params.deinit(gpa); | 7108 | child_block.params.deinit(gpa); |
| 7009 | } | 7109 | } |
| 7010 | | 7110 | |
| 7011 | try child_sema.inst_map.ensureUnusedCapacity(gpa, @intCast(u32, uncasted_args.len)); | 7111 | try child_sema.inst_map.ensureSpaceForInstructions(gpa, fn_info.param_body); |
| | 7112 | |
| 7012 | var arg_i: usize = 0; | 7113 | var arg_i: usize = 0; |
| 7013 | for (fn_info.param_body) |inst| { | 7114 | for (fn_info.param_body) |inst| { |
| 7014 | var is_comptime = false; | 7115 | var is_comptime = false; |
| ... | @@ -8111,6 +8212,7 @@ fn resolveGenericBody( | ... | @@ -8111,6 +8212,7 @@ fn resolveGenericBody( |
| 8111 | block.params.deinit(sema.gpa); | 8212 | block.params.deinit(sema.gpa); |
| 8112 | block.params = prev_params; | 8213 | block.params = prev_params; |
| 8113 | } | 8214 | } |
| | 8215 | |
| 8114 | const uncasted = sema.resolveBody(block, body, func_inst) catch |err| break :err err; | 8216 | const uncasted = sema.resolveBody(block, body, func_inst) catch |err| break :err err; |
| 8115 | const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err; | 8217 | const result = sema.coerce(block, dest_ty, uncasted, src) catch |err| break :err err; |
| 8116 | const val = sema.resolveConstValue(block, src, result, reason) catch |err| break :err err; | 8218 | const val = sema.resolveConstValue(block, src, result, reason) catch |err| break :err err; |
| ... | @@ -8660,7 +8762,7 @@ fn zirParam( | ... | @@ -8660,7 +8762,7 @@ fn zirParam( |
| 8660 | .is_comptime = comptime_syntax, | 8762 | .is_comptime = comptime_syntax, |
| 8661 | .name = param_name, | 8763 | .name = param_name, |
| 8662 | }); | 8764 | }); |
| 8663 | try sema.inst_map.putNoClobber(sema.gpa, inst, .generic_poison); | 8765 | sema.inst_map.putAssumeCapacityNoClobber(inst, .generic_poison); |
| 8664 | return; | 8766 | return; |
| 8665 | }, | 8767 | }, |
| 8666 | else => |e| return e, | 8768 | else => |e| return e, |
| ... | @@ -8676,7 +8778,7 @@ fn zirParam( | ... | @@ -8676,7 +8778,7 @@ fn zirParam( |
| 8676 | .is_comptime = comptime_syntax, | 8778 | .is_comptime = comptime_syntax, |
| 8677 | .name = param_name, | 8779 | .name = param_name, |
| 8678 | }); | 8780 | }); |
| 8679 | try sema.inst_map.putNoClobber(sema.gpa, inst, .generic_poison); | 8781 | sema.inst_map.putAssumeCapacityNoClobber(inst, .generic_poison); |
| 8680 | return; | 8782 | return; |
| 8681 | }, | 8783 | }, |
| 8682 | else => |e| return e, | 8784 | else => |e| return e, |
| ... | @@ -8700,7 +8802,7 @@ fn zirParam( | ... | @@ -8700,7 +8802,7 @@ fn zirParam( |
| 8700 | // non-anytype parameter that ended up being a one-possible-type. | 8802 | // non-anytype parameter that ended up being a one-possible-type. |
| 8701 | // We don't want the parameter to be part of the instantiated function type. | 8803 | // We don't want the parameter to be part of the instantiated function type. |
| 8702 | const result = try sema.addConstant(param_ty, opv); | 8804 | const result = try sema.addConstant(param_ty, opv); |
| 8703 | try sema.inst_map.put(sema.gpa, inst, result); | 8805 | sema.inst_map.putAssumeCapacity(inst, result); |
| 8704 | return; | 8806 | return; |
| 8705 | } | 8807 | } |
| 8706 | } | 8808 | } |
| ... | @@ -8715,7 +8817,7 @@ fn zirParam( | ... | @@ -8715,7 +8817,7 @@ fn zirParam( |
| 8715 | // If this is a comptime parameter we can add a constant generic_poison | 8817 | // If this is a comptime parameter we can add a constant generic_poison |
| 8716 | // since this is also a generic parameter. | 8818 | // since this is also a generic parameter. |
| 8717 | const result = try sema.addConstant(param_ty, Value.initTag(.generic_poison)); | 8819 | const result = try sema.addConstant(param_ty, Value.initTag(.generic_poison)); |
| 8718 | try sema.inst_map.putNoClobber(sema.gpa, inst, result); | 8820 | sema.inst_map.putAssumeCapacityNoClobber(inst, result); |
| 8719 | } else { | 8821 | } else { |
| 8720 | // Otherwise we need a dummy runtime instruction. | 8822 | // Otherwise we need a dummy runtime instruction. |
| 8721 | const result_index = @intCast(Air.Inst.Index, sema.air_instructions.len); | 8823 | const result_index = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| ... | @@ -8724,7 +8826,7 @@ fn zirParam( | ... | @@ -8724,7 +8826,7 @@ fn zirParam( |
| 8724 | .data = .{ .ty = param_ty }, | 8826 | .data = .{ .ty = param_ty }, |
| 8725 | }); | 8827 | }); |
| 8726 | const result = Air.indexToRef(result_index); | 8828 | const result = Air.indexToRef(result_index); |
| 8727 | try sema.inst_map.putNoClobber(sema.gpa, inst, result); | 8829 | sema.inst_map.putAssumeCapacityNoClobber(inst, result); |
| 8728 | } | 8830 | } |
| 8729 | } | 8831 | } |
| 8730 | | 8832 | |
| ... | @@ -8763,7 +8865,7 @@ fn zirParamAnytype( | ... | @@ -8763,7 +8865,7 @@ fn zirParamAnytype( |
| 8763 | .is_comptime = comptime_syntax, | 8865 | .is_comptime = comptime_syntax, |
| 8764 | .name = param_name, | 8866 | .name = param_name, |
| 8765 | }); | 8867 | }); |
| 8766 | try sema.inst_map.put(sema.gpa, inst, .generic_poison); | 8868 | sema.inst_map.putAssumeCapacity(inst, .generic_poison); |
| 8767 | } | 8869 | } |
| 8768 | | 8870 | |
| 8769 | fn zirAs(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 8871 | fn zirAs(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -11220,7 +11322,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op | ... | @@ -11220,7 +11322,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op |
| 11220 | }; | 11322 | }; |
| 11221 | if (sema.typeOf(air_inst).isNoReturn()) | 11323 | if (sema.typeOf(air_inst).isNoReturn()) |
| 11222 | return true; | 11324 | return true; |
| 11223 | try sema.inst_map.put(sema.gpa, inst, air_inst); | 11325 | sema.inst_map.putAssumeCapacity(inst, air_inst); |
| 11224 | } | 11326 | } |
| 11225 | unreachable; | 11327 | unreachable; |
| 11226 | } | 11328 | } |
| ... | @@ -16348,7 +16450,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -16348,7 +16450,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 16348 | // break from an inline loop. In such case we must convert it to | 16450 | // break from an inline loop. In such case we must convert it to |
| 16349 | // a runtime break. | 16451 | // a runtime break. |
| 16350 | fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !void { | 16452 | fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !void { |
| 16351 | const gop = try sema.inst_map.getOrPut(sema.gpa, break_data.block_inst); | 16453 | const gop = sema.inst_map.getOrPutAssumeCapacity(break_data.block_inst); |
| 16352 | const labeled_block = if (!gop.found_existing) blk: { | 16454 | const labeled_block = if (!gop.found_existing) blk: { |
| 16353 | try sema.post_hoc_blocks.ensureUnusedCapacity(sema.gpa, 1); | 16455 | try sema.post_hoc_blocks.ensureUnusedCapacity(sema.gpa, 1); |
| 16354 | | 16456 | |