| ... | ... | @@ -12358,31 +12358,6 @@ fn coerce( |
| 12358 | 12358 | // T to E!T or E to E!T |
| 12359 | 12359 | return sema.wrapErrorUnion(block, dest_ty, inst, inst_src); |
| 12360 | 12360 | }, |
| 12361 | | .ErrorSet => switch (inst_ty.zigTypeTag()) { |
| 12362 | | .ErrorSet => { |
| 12363 | | // Coercion to `anyerror`. Note that this check can return false positives |
| 12364 | | // in case the error sets did not get resolved. |
| 12365 | | if (dest_ty.isAnyError()) { |
| 12366 | | return sema.coerceCompatibleErrorSets(block, inst, inst_src); |
| 12367 | | } |
| 12368 | | // If both are inferred error sets of functions, and |
| 12369 | | // the dest includes the source function, the coercion is OK. |
| 12370 | | // This check is important because it works without forcing a full resolution |
| 12371 | | // of inferred error sets. |
| 12372 | | if (inst_ty.castTag(.error_set_inferred)) |src_payload| { |
| 12373 | | if (dest_ty.castTag(.error_set_inferred)) |dst_payload| { |
| 12374 | | const src_func = src_payload.data.func; |
| 12375 | | const dst_func = dst_payload.data.func; |
| 12376 | | |
| 12377 | | if (src_func == dst_func or dst_payload.data.functions.contains(src_func)) { |
| 12378 | | return sema.coerceCompatibleErrorSets(block, inst, inst_src); |
| 12379 | | } |
| 12380 | | } |
| 12381 | | } |
| 12382 | | // TODO full error set resolution and compare sets by names. |
| 12383 | | }, |
| 12384 | | else => {}, |
| 12385 | | }, |
| 12386 | 12361 | .Union => switch (inst_ty.zigTypeTag()) { |
| 12387 | 12362 | .Enum, .EnumLiteral => return sema.coerceEnumToUnion(block, dest_ty, dest_ty_src, inst, inst_src), |
| 12388 | 12363 | else => {}, |
| ... | ... | @@ -12440,15 +12415,47 @@ fn coerceInMemoryAllowed(dest_ty: Type, src_ty: Type, dest_is_mut: bool, target: |
| 12440 | 12415 | return coerceInMemoryAllowedFns(dest_ty, src_ty, target); |
| 12441 | 12416 | } |
| 12442 | 12417 | |
| 12418 | // Error Sets |
| 12419 | if (dest_ty.zigTypeTag() == .ErrorSet and src_ty.zigTypeTag() == .ErrorSet) { |
| 12420 | return coerceInMemoryAllowedErrorSets(dest_ty, src_ty); |
| 12421 | } |
| 12422 | |
| 12443 | 12423 | // TODO: arrays |
| 12444 | 12424 | // TODO: non-pointer-like optionals |
| 12445 | 12425 | // TODO: error unions |
| 12446 | | // TODO: error sets |
| 12447 | 12426 | // TODO: vectors |
| 12448 | 12427 | |
| 12449 | 12428 | return .no_match; |
| 12450 | 12429 | } |
| 12451 | 12430 | |
| 12431 | fn coerceInMemoryAllowedErrorSets( |
| 12432 | dest_ty: Type, |
| 12433 | src_ty: Type, |
| 12434 | ) InMemoryCoercionResult { |
| 12435 | // Coercion to `anyerror`. Note that this check can return false positives |
| 12436 | // in case the error sets did not get resolved. |
| 12437 | if (dest_ty.isAnyError()) { |
| 12438 | return .ok; |
| 12439 | } |
| 12440 | // If both are inferred error sets of functions, and |
| 12441 | // the dest includes the source function, the coercion is OK. |
| 12442 | // This check is important because it works without forcing a full resolution |
| 12443 | // of inferred error sets. |
| 12444 | if (src_ty.castTag(.error_set_inferred)) |src_payload| { |
| 12445 | if (dest_ty.castTag(.error_set_inferred)) |dst_payload| { |
| 12446 | const src_func = src_payload.data.func; |
| 12447 | const dst_func = dst_payload.data.func; |
| 12448 | |
| 12449 | if (src_func == dst_func or dst_payload.data.functions.contains(src_func)) { |
| 12450 | return .ok; |
| 12451 | } |
| 12452 | } |
| 12453 | } |
| 12454 | |
| 12455 | // TODO full error set resolution and compare sets by names. |
| 12456 | return .no_match; |
| 12457 | } |
| 12458 | |
| 12452 | 12459 | fn coerceInMemoryAllowedFns( |
| 12453 | 12460 | dest_ty: Type, |
| 12454 | 12461 | src_ty: Type, |
| ... | ... | @@ -13224,26 +13231,6 @@ fn coerceVectorInMemory( |
| 13224 | 13231 | return block.addBitCast(dest_ty, inst); |
| 13225 | 13232 | } |
| 13226 | 13233 | |
| 13227 | | fn coerceCompatibleErrorSets( |
| 13228 | | sema: *Sema, |
| 13229 | | block: *Block, |
| 13230 | | err_set: Air.Inst.Ref, |
| 13231 | | err_set_src: LazySrcLoc, |
| 13232 | | ) !Air.Inst.Ref { |
| 13233 | | if (try sema.resolveDefinedValue(block, err_set_src, err_set)) |err_set_val| { |
| 13234 | | // Same representation works. |
| 13235 | | return sema.addConstant(Type.anyerror, err_set_val); |
| 13236 | | } |
| 13237 | | try sema.requireRuntimeBlock(block, err_set_src); |
| 13238 | | return block.addInst(.{ |
| 13239 | | .tag = .bitcast, |
| 13240 | | .data = .{ .ty_op = .{ |
| 13241 | | .ty = Air.Inst.Ref.anyerror_type, |
| 13242 | | .operand = err_set, |
| 13243 | | } }, |
| 13244 | | }); |
| 13245 | | } |
| 13246 | | |
| 13247 | 13234 | fn analyzeDeclVal( |
| 13248 | 13235 | sema: *Sema, |
| 13249 | 13236 | block: *Block, |