| ... | ... | @@ -1323,7 +1323,7 @@ fn analyzeBodyInner( |
| 1323 | 1323 | } |
| 1324 | 1324 | }, |
| 1325 | 1325 | .@"try" => blk: { |
| 1326 | | if (!block.is_comptime) break :blk try sema.zirTry(block, inst, false); |
| 1326 | if (!block.is_comptime) break :blk try sema.zirTry(block, inst); |
| 1327 | 1327 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 1328 | 1328 | const src = inst_data.src(); |
| 1329 | 1329 | const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| ... | ... | @@ -1376,7 +1376,7 @@ fn analyzeBodyInner( |
| 1376 | 1376 | // } |
| 1377 | 1377 | //}, |
| 1378 | 1378 | .try_ptr => blk: { |
| 1379 | | if (!block.is_comptime) break :blk try sema.zirTry(block, inst, true); |
| 1379 | if (!block.is_comptime) break :blk try sema.zirTryPtr(block, inst); |
| 1380 | 1380 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 1381 | 1381 | const src = inst_data.src(); |
| 1382 | 1382 | const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| ... | ... | @@ -13065,22 +13065,13 @@ fn zirCondbr( |
| 13065 | 13065 | return always_noreturn; |
| 13066 | 13066 | } |
| 13067 | 13067 | |
| 13068 | | fn zirTry( |
| 13069 | | sema: *Sema, |
| 13070 | | parent_block: *Block, |
| 13071 | | inst: Zir.Inst.Index, |
| 13072 | | is_ptr: bool, |
| 13073 | | ) CompileError!Zir.Inst.Ref { |
| 13068 | fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Ref { |
| 13074 | 13069 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 13075 | 13070 | const src = inst_data.src(); |
| 13076 | 13071 | const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 13077 | 13072 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); |
| 13078 | 13073 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 13079 | | const operand = try sema.resolveInst(extra.data.operand); |
| 13080 | | const err_union = if (is_ptr) |
| 13081 | | try sema.analyzeLoad(parent_block, src, operand, operand_src) |
| 13082 | | else |
| 13083 | | operand; |
| 13074 | const err_union = try sema.resolveInst(extra.data.operand); |
| 13084 | 13075 | const err_union_ty = sema.typeOf(err_union); |
| 13085 | 13076 | if (err_union_ty.zigTypeTag() != .ErrorUnion) { |
| 13086 | 13077 | return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ |
| ... | ... | @@ -13091,11 +13082,7 @@ fn zirTry( |
| 13091 | 13082 | |
| 13092 | 13083 | if (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)) |is_non_err_val| { |
| 13093 | 13084 | if (is_non_err_val.toBool()) { |
| 13094 | | if (is_ptr) { |
| 13095 | | return sema.analyzeErrUnionPayloadPtr(parent_block, src, operand, false, false); |
| 13096 | | } else { |
| 13097 | | return sema.analyzeErrUnionPayload(parent_block, src, err_union_ty, operand, operand_src, false); |
| 13098 | | } |
| 13085 | return sema.analyzeErrUnionPayload(parent_block, src, err_union_ty, err_union, operand_src, false); |
| 13099 | 13086 | } |
| 13100 | 13087 | // We can analyze the body directly in the parent block because we know there are |
| 13101 | 13088 | // no breaks from the body possible, and that the body is noreturn. |
| ... | ... | @@ -13108,39 +13095,12 @@ fn zirTry( |
| 13108 | 13095 | // This body is guaranteed to end with noreturn and has no breaks. |
| 13109 | 13096 | _ = try sema.analyzeBodyInner(&sub_block, body); |
| 13110 | 13097 | |
| 13111 | | if (is_ptr) { |
| 13112 | | const operand_ty = sema.typeOf(operand); |
| 13113 | | const ptr_info = operand_ty.ptrInfo().data; |
| 13114 | | const res_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 13115 | | .pointee_type = err_union_ty.errorUnionPayload(), |
| 13116 | | .@"addrspace" = ptr_info.@"addrspace", |
| 13117 | | .mutable = ptr_info.mutable, |
| 13118 | | .@"allowzero" = ptr_info.@"allowzero", |
| 13119 | | .@"volatile" = ptr_info.@"volatile", |
| 13120 | | }); |
| 13121 | | const res_ty_ref = try sema.addType(res_ty); |
| 13122 | | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Try).Struct.fields.len + |
| 13123 | | sub_block.instructions.items.len); |
| 13124 | | const try_inst = try parent_block.addInst(.{ |
| 13125 | | .tag = .try_ptr, |
| 13126 | | .data = .{ .ty_pl = .{ |
| 13127 | | .ty = res_ty_ref, |
| 13128 | | .payload = sema.addExtraAssumeCapacity(Air.TryPtr{ |
| 13129 | | .ptr = operand, |
| 13130 | | .body_len = @intCast(u32, sub_block.instructions.items.len), |
| 13131 | | }), |
| 13132 | | } }, |
| 13133 | | }); |
| 13134 | | sema.air_extra.appendSliceAssumeCapacity(sub_block.instructions.items); |
| 13135 | | return try_inst; |
| 13136 | | } |
| 13137 | | |
| 13138 | 13098 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Try).Struct.fields.len + |
| 13139 | 13099 | sub_block.instructions.items.len); |
| 13140 | 13100 | const try_inst = try parent_block.addInst(.{ |
| 13141 | 13101 | .tag = .@"try", |
| 13142 | 13102 | .data = .{ .pl_op = .{ |
| 13143 | | .operand = operand, |
| 13103 | .operand = err_union, |
| 13144 | 13104 | .payload = sema.addExtraAssumeCapacity(Air.Try{ |
| 13145 | 13105 | .body_len = @intCast(u32, sub_block.instructions.items.len), |
| 13146 | 13106 | }), |
| ... | ... | @@ -13150,6 +13110,63 @@ fn zirTry( |
| 13150 | 13110 | return try_inst; |
| 13151 | 13111 | } |
| 13152 | 13112 | |
| 13113 | fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Ref { |
| 13114 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 13115 | const src = inst_data.src(); |
| 13116 | const operand_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 13117 | const extra = sema.code.extraData(Zir.Inst.Try, inst_data.payload_index); |
| 13118 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 13119 | const operand = try sema.resolveInst(extra.data.operand); |
| 13120 | const err_union = try sema.analyzeLoad(parent_block, src, operand, operand_src); |
| 13121 | const err_union_ty = sema.typeOf(err_union); |
| 13122 | if (err_union_ty.zigTypeTag() != .ErrorUnion) { |
| 13123 | return sema.fail(parent_block, operand_src, "expected error union type, found '{}'", .{ |
| 13124 | err_union_ty.fmt(sema.mod), |
| 13125 | }); |
| 13126 | } |
| 13127 | const is_non_err = try sema.analyzeIsNonErr(parent_block, operand_src, err_union); |
| 13128 | |
| 13129 | if (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)) |is_non_err_val| { |
| 13130 | if (is_non_err_val.toBool()) { |
| 13131 | return sema.analyzeErrUnionPayloadPtr(parent_block, src, operand, false, false); |
| 13132 | } |
| 13133 | // We can analyze the body directly in the parent block because we know there are |
| 13134 | // no breaks from the body possible, and that the body is noreturn. |
| 13135 | return sema.resolveBody(parent_block, body, inst); |
| 13136 | } |
| 13137 | |
| 13138 | var sub_block = parent_block.makeSubBlock(); |
| 13139 | defer sub_block.instructions.deinit(sema.gpa); |
| 13140 | |
| 13141 | // This body is guaranteed to end with noreturn and has no breaks. |
| 13142 | _ = try sema.analyzeBodyInner(&sub_block, body); |
| 13143 | |
| 13144 | const operand_ty = sema.typeOf(operand); |
| 13145 | const ptr_info = operand_ty.ptrInfo().data; |
| 13146 | const res_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 13147 | .pointee_type = err_union_ty.errorUnionPayload(), |
| 13148 | .@"addrspace" = ptr_info.@"addrspace", |
| 13149 | .mutable = ptr_info.mutable, |
| 13150 | .@"allowzero" = ptr_info.@"allowzero", |
| 13151 | .@"volatile" = ptr_info.@"volatile", |
| 13152 | }); |
| 13153 | const res_ty_ref = try sema.addType(res_ty); |
| 13154 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.TryPtr).Struct.fields.len + |
| 13155 | sub_block.instructions.items.len); |
| 13156 | const try_inst = try parent_block.addInst(.{ |
| 13157 | .tag = .try_ptr, |
| 13158 | .data = .{ .ty_pl = .{ |
| 13159 | .ty = res_ty_ref, |
| 13160 | .payload = sema.addExtraAssumeCapacity(Air.TryPtr{ |
| 13161 | .ptr = operand, |
| 13162 | .body_len = @intCast(u32, sub_block.instructions.items.len), |
| 13163 | }), |
| 13164 | } }, |
| 13165 | }); |
| 13166 | sema.air_extra.appendSliceAssumeCapacity(sub_block.instructions.items); |
| 13167 | return try_inst; |
| 13168 | } |
| 13169 | |
| 13153 | 13170 | // A `break` statement is inside a runtime condition, but trying to |
| 13154 | 13171 | // break from an inline loop. In such case we must convert it to |
| 13155 | 13172 | // a runtime break. |