| ... | @@ -3187,12 +3187,32 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v | ... | @@ -3187,12 +3187,32 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v |
| 3187 | const tracy = trace(@src()); | 3187 | const tracy = trace(@src()); |
| 3188 | defer tracy.end(); | 3188 | defer tracy.end(); |
| 3189 | | 3189 | |
| 3190 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 3190 | const zir_tags = sema.code.instructions.items(.tag); |
| | 3191 | const zir_datas = sema.code.instructions.items(.data); |
| | 3192 | const inst_data = zir_datas[inst].pl_node; |
| 3191 | const src = inst_data.src(); | 3193 | const src = inst_data.src(); |
| 3192 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 3194 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 3193 | const ptr = sema.resolveInst(extra.lhs); | 3195 | const ptr = sema.resolveInst(extra.lhs); |
| 3194 | const value = sema.resolveInst(extra.rhs); | 3196 | const operand = sema.resolveInst(extra.rhs); |
| 3195 | return sema.storePtr(block, src, ptr, value); | 3197 | |
| | 3198 | // Check for the possibility of this pattern: |
| | 3199 | // %a = ret_ptr |
| | 3200 | // %b = store(%a, %c) |
| | 3201 | // Where %c is an error union. In such case we need to add to the current function's |
| | 3202 | // inferred error set, if any. |
| | 3203 | if (sema.typeOf(operand).zigTypeTag() == .ErrorUnion and |
| | 3204 | sema.fn_ret_ty.zigTypeTag() == .ErrorUnion) |
| | 3205 | { |
| | 3206 | if (Zir.refToIndex(extra.lhs)) |ptr_index| { |
| | 3207 | if (zir_tags[ptr_index] == .extended and |
| | 3208 | zir_datas[ptr_index].extended.opcode == .ret_ptr) |
| | 3209 | { |
| | 3210 | try sema.addToInferredErrorSet(operand); |
| | 3211 | } |
| | 3212 | } |
| | 3213 | } |
| | 3214 | |
| | 3215 | return sema.storePtr(block, src, ptr, operand); |
| 3196 | } | 3216 | } |
| 3197 | | 3217 | |
| 3198 | fn zirStr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 3218 | fn zirStr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -10400,6 +10420,23 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir | ... | @@ -10400,6 +10420,23 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 10400 | return always_noreturn; | 10420 | return always_noreturn; |
| 10401 | } | 10421 | } |
| 10402 | | 10422 | |
| | 10423 | fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void { |
| | 10424 | assert(sema.fn_ret_ty.zigTypeTag() == .ErrorUnion); |
| | 10425 | |
| | 10426 | if (sema.fn_ret_ty.errorUnionSet().castTag(.error_set_inferred)) |payload| { |
| | 10427 | const op_ty = sema.typeOf(uncasted_operand); |
| | 10428 | switch (op_ty.zigTypeTag()) { |
| | 10429 | .ErrorSet => { |
| | 10430 | try payload.data.addErrorSet(sema.gpa, op_ty); |
| | 10431 | }, |
| | 10432 | .ErrorUnion => { |
| | 10433 | try payload.data.addErrorSet(sema.gpa, op_ty.errorUnionSet()); |
| | 10434 | }, |
| | 10435 | else => {}, |
| | 10436 | } |
| | 10437 | } |
| | 10438 | } |
| | 10439 | |
| 10403 | fn analyzeRet( | 10440 | fn analyzeRet( |
| 10404 | sema: *Sema, | 10441 | sema: *Sema, |
| 10405 | block: *Block, | 10442 | block: *Block, |
| ... | @@ -10410,18 +10447,7 @@ fn analyzeRet( | ... | @@ -10410,18 +10447,7 @@ fn analyzeRet( |
| 10410 | // add the error tag to the inferred error set of the in-scope function, so | 10447 | // add the error tag to the inferred error set of the in-scope function, so |
| 10411 | // that the coercion below works correctly. | 10448 | // that the coercion below works correctly. |
| 10412 | if (sema.fn_ret_ty.zigTypeTag() == .ErrorUnion) { | 10449 | if (sema.fn_ret_ty.zigTypeTag() == .ErrorUnion) { |
| 10413 | if (sema.fn_ret_ty.errorUnionSet().castTag(.error_set_inferred)) |payload| { | 10450 | try sema.addToInferredErrorSet(uncasted_operand); |
| 10414 | const op_ty = sema.typeOf(uncasted_operand); | | |
| 10415 | switch (op_ty.zigTypeTag()) { | | |
| 10416 | .ErrorSet => { | | |
| 10417 | try payload.data.addErrorSet(sema.gpa, op_ty); | | |
| 10418 | }, | | |
| 10419 | .ErrorUnion => { | | |
| 10420 | try payload.data.addErrorSet(sema.gpa, op_ty.errorUnionSet()); | | |
| 10421 | }, | | |
| 10422 | else => {}, | | |
| 10423 | } | | |
| 10424 | } | | |
| 10425 | } | 10451 | } |
| 10426 | const operand = try sema.coerce(block, sema.fn_ret_ty, uncasted_operand, src); | 10452 | const operand = try sema.coerce(block, sema.fn_ret_ty, uncasted_operand, src); |
| 10427 | | 10453 | |
| ... | @@ -14355,9 +14381,32 @@ fn coerce( | ... | @@ -14355,9 +14381,32 @@ fn coerce( |
| 14355 | }, | 14381 | }, |
| 14356 | else => {}, | 14382 | else => {}, |
| 14357 | }, | 14383 | }, |
| 14358 | .ErrorUnion => { | 14384 | .ErrorUnion => switch (inst_ty.zigTypeTag()) { |
| 14359 | // T to E!T or E to E!T | 14385 | .ErrorUnion => { |
| 14360 | return sema.wrapErrorUnion(block, dest_ty, inst, inst_src); | 14386 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |inst_val| { |
| | 14387 | switch (inst_val.tag()) { |
| | 14388 | .undef => return sema.addConstUndef(dest_ty), |
| | 14389 | .eu_payload => { |
| | 14390 | const payload = try sema.addConstant( |
| | 14391 | inst_ty.errorUnionPayload(), |
| | 14392 | inst_val.castTag(.eu_payload).?.data, |
| | 14393 | ); |
| | 14394 | return sema.wrapErrorUnion(block, dest_ty, payload, inst_src); |
| | 14395 | }, |
| | 14396 | else => { |
| | 14397 | const error_set = try sema.addConstant( |
| | 14398 | inst_ty.errorUnionSet(), |
| | 14399 | inst_val, |
| | 14400 | ); |
| | 14401 | return sema.wrapErrorUnion(block, dest_ty, error_set, inst_src); |
| | 14402 | }, |
| | 14403 | } |
| | 14404 | } |
| | 14405 | }, |
| | 14406 | else => { |
| | 14407 | // T to E!T or E to E!T |
| | 14408 | return sema.wrapErrorUnion(block, dest_ty, inst, inst_src); |
| | 14409 | }, |
| 14361 | }, | 14410 | }, |
| 14362 | .Union => switch (inst_ty.zigTypeTag()) { | 14411 | .Union => switch (inst_ty.zigTypeTag()) { |
| 14363 | .Enum, .EnumLiteral => return sema.coerceEnumToUnion(block, dest_ty, dest_ty_src, inst, inst_src), | 14412 | .Enum, .EnumLiteral => return sema.coerceEnumToUnion(block, dest_ty, dest_ty_src, inst, inst_src), |