| ... | ... | @@ -11653,7 +11653,11 @@ fn coerce( |
| 11653 | 11653 | else => {}, |
| 11654 | 11654 | }, |
| 11655 | 11655 | .Array => switch (inst_ty.zigTypeTag()) { |
| 11656 | | .Vector => return sema.coerceVectorToArray(block, dest_ty, dest_ty_src, inst, inst_src), |
| 11656 | .Vector => return sema.coerceVectorInMemory(block, dest_ty, dest_ty_src, inst, inst_src), |
| 11657 | else => {}, |
| 11658 | }, |
| 11659 | .Vector => switch (inst_ty.zigTypeTag()) { |
| 11660 | .Array => return sema.coerceVectorInMemory(block, dest_ty, dest_ty_src, inst, inst_src), |
| 11657 | 11661 | else => {}, |
| 11658 | 11662 | }, |
| 11659 | 11663 | else => {}, |
| ... | ... | @@ -12237,46 +12241,49 @@ fn coerceEnumToUnion( |
| 12237 | 12241 | return sema.failWithOwnedErrorMsg(msg); |
| 12238 | 12242 | } |
| 12239 | 12243 | |
| 12240 | | fn coerceVectorToArray( |
| 12244 | // Coerces vectors/arrays which have the same in-memory layout. This can be used for |
| 12245 | // both coercing from and to vectors. |
| 12246 | fn coerceVectorInMemory( |
| 12241 | 12247 | sema: *Sema, |
| 12242 | 12248 | block: *Block, |
| 12243 | | array_ty: Type, |
| 12244 | | array_ty_src: LazySrcLoc, |
| 12245 | | vector: Air.Inst.Ref, |
| 12246 | | vector_src: LazySrcLoc, |
| 12249 | dest_ty: Type, |
| 12250 | dest_ty_src: LazySrcLoc, |
| 12251 | inst: Air.Inst.Ref, |
| 12252 | inst_src: LazySrcLoc, |
| 12247 | 12253 | ) !Air.Inst.Ref { |
| 12248 | | const vector_ty = sema.typeOf(vector); |
| 12249 | | const array_len = array_ty.arrayLen(); |
| 12250 | | const vector_len = vector_ty.arrayLen(); |
| 12251 | | if (array_len != vector_len) { |
| 12254 | const inst_ty = sema.typeOf(inst); |
| 12255 | const inst_len = inst_ty.arrayLen(); |
| 12256 | const dest_len = dest_ty.arrayLen(); |
| 12257 | |
| 12258 | if (dest_len != inst_len) { |
| 12252 | 12259 | const msg = msg: { |
| 12253 | | const msg = try sema.errMsg(block, vector_src, "expected {}, found {}", .{ |
| 12254 | | array_ty, vector_ty, |
| 12260 | const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{ |
| 12261 | dest_ty, inst_ty, |
| 12255 | 12262 | }); |
| 12256 | 12263 | errdefer msg.destroy(sema.gpa); |
| 12257 | | try sema.errNote(block, array_ty_src, msg, "array has length {d}", .{array_len}); |
| 12258 | | try sema.errNote(block, vector_src, msg, "vector has length {d}", .{vector_len}); |
| 12264 | try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len}); |
| 12265 | try sema.errNote(block, inst_src, msg, "source has length {d}", .{inst_len}); |
| 12259 | 12266 | break :msg msg; |
| 12260 | 12267 | }; |
| 12261 | 12268 | return sema.failWithOwnedErrorMsg(msg); |
| 12262 | 12269 | } |
| 12263 | 12270 | |
| 12264 | 12271 | const target = sema.mod.getTarget(); |
| 12265 | | const array_elem_ty = array_ty.childType(); |
| 12266 | | const vector_elem_ty = vector_ty.childType(); |
| 12267 | | const in_memory_result = coerceInMemoryAllowed(array_elem_ty, vector_elem_ty, false, target); |
| 12272 | const dest_elem_ty = dest_ty.childType(); |
| 12273 | const inst_elem_ty = inst_ty.childType(); |
| 12274 | const in_memory_result = coerceInMemoryAllowed(dest_elem_ty, inst_elem_ty, false, target); |
| 12268 | 12275 | if (in_memory_result != .ok) { |
| 12269 | 12276 | // TODO recursive error notes for coerceInMemoryAllowed failure |
| 12270 | | return sema.fail(block, vector_src, "expected {}, found {}", .{ array_ty, vector_ty }); |
| 12277 | return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty }); |
| 12271 | 12278 | } |
| 12272 | 12279 | |
| 12273 | | if (try sema.resolveMaybeUndefVal(block, vector_src, vector)) |vector_val| { |
| 12280 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |inst_val| { |
| 12274 | 12281 | // These types share the same comptime value representation. |
| 12275 | | return sema.addConstant(array_ty, vector_val); |
| 12282 | return sema.addConstant(dest_ty, inst_val); |
| 12276 | 12283 | } |
| 12277 | 12284 | |
| 12278 | | try sema.requireRuntimeBlock(block, vector_src); |
| 12279 | | return block.addTyOp(.bitcast, array_ty, vector); |
| 12285 | try sema.requireRuntimeBlock(block, inst_src); |
| 12286 | return block.addTyOp(.bitcast, dest_ty, inst); |
| 12280 | 12287 | } |
| 12281 | 12288 | |
| 12282 | 12289 | fn coerceErrSetToAnyError( |