| ... | @@ -11653,7 +11653,11 @@ fn coerce( | ... | @@ -11653,7 +11653,11 @@ fn coerce( |
| 11653 | else => {}, | 11653 | else => {}, |
| 11654 | }, | 11654 | }, |
| 11655 | .Array => switch (inst_ty.zigTypeTag()) { | 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 | else => {}, | 11661 | else => {}, |
| 11658 | }, | 11662 | }, |
| 11659 | else => {}, | 11663 | else => {}, |
| ... | @@ -12237,46 +12241,49 @@ fn coerceEnumToUnion( | ... | @@ -12237,46 +12241,49 @@ fn coerceEnumToUnion( |
| 12237 | return sema.failWithOwnedErrorMsg(msg); | 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 | sema: *Sema, | 12247 | sema: *Sema, |
| 12242 | block: *Block, | 12248 | block: *Block, |
| 12243 | array_ty: Type, | 12249 | dest_ty: Type, |
| 12244 | array_ty_src: LazySrcLoc, | 12250 | dest_ty_src: LazySrcLoc, |
| 12245 | vector: Air.Inst.Ref, | 12251 | inst: Air.Inst.Ref, |
| 12246 | vector_src: LazySrcLoc, | 12252 | inst_src: LazySrcLoc, |
| 12247 | ) !Air.Inst.Ref { | 12253 | ) !Air.Inst.Ref { |
| 12248 | const vector_ty = sema.typeOf(vector); | 12254 | const inst_ty = sema.typeOf(inst); |
| 12249 | const array_len = array_ty.arrayLen(); | 12255 | const inst_len = inst_ty.arrayLen(); |
| 12250 | const vector_len = vector_ty.arrayLen(); | 12256 | const dest_len = dest_ty.arrayLen(); |
| 12251 | if (array_len != vector_len) { | 12257 | |
| | 12258 | if (dest_len != inst_len) { |
| 12252 | const msg = msg: { | 12259 | const msg = msg: { |
| 12253 | const msg = try sema.errMsg(block, vector_src, "expected {}, found {}", .{ | 12260 | const msg = try sema.errMsg(block, inst_src, "expected {}, found {}", .{ |
| 12254 | array_ty, vector_ty, | 12261 | dest_ty, inst_ty, |
| 12255 | }); | 12262 | }); |
| 12256 | errdefer msg.destroy(sema.gpa); | 12263 | errdefer msg.destroy(sema.gpa); |
| 12257 | try sema.errNote(block, array_ty_src, msg, "array has length {d}", .{array_len}); | 12264 | try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len}); |
| 12258 | try sema.errNote(block, vector_src, msg, "vector has length {d}", .{vector_len}); | 12265 | try sema.errNote(block, inst_src, msg, "source has length {d}", .{inst_len}); |
| 12259 | break :msg msg; | 12266 | break :msg msg; |
| 12260 | }; | 12267 | }; |
| 12261 | return sema.failWithOwnedErrorMsg(msg); | 12268 | return sema.failWithOwnedErrorMsg(msg); |
| 12262 | } | 12269 | } |
| 12263 | | 12270 | |
| 12264 | const target = sema.mod.getTarget(); | 12271 | const target = sema.mod.getTarget(); |
| 12265 | const array_elem_ty = array_ty.childType(); | 12272 | const dest_elem_ty = dest_ty.childType(); |
| 12266 | const vector_elem_ty = vector_ty.childType(); | 12273 | const inst_elem_ty = inst_ty.childType(); |
| 12267 | const in_memory_result = coerceInMemoryAllowed(array_elem_ty, vector_elem_ty, false, target); | 12274 | const in_memory_result = coerceInMemoryAllowed(dest_elem_ty, inst_elem_ty, false, target); |
| 12268 | if (in_memory_result != .ok) { | 12275 | if (in_memory_result != .ok) { |
| 12269 | // TODO recursive error notes for coerceInMemoryAllowed failure | 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 | // These types share the same comptime value representation. | 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); | 12285 | try sema.requireRuntimeBlock(block, inst_src); |
| 12279 | return block.addTyOp(.bitcast, array_ty, vector); | 12286 | return block.addTyOp(.bitcast, dest_ty, inst); |
| 12280 | } | 12287 | } |
| 12281 | | 12288 | |
| 12282 | fn coerceErrSetToAnyError( | 12289 | fn coerceErrSetToAnyError( |