| ... | @@ -28315,6 +28315,50 @@ fn coerceInMemoryAllowed( | ... | @@ -28315,6 +28315,50 @@ fn coerceInMemoryAllowed( |
| 28315 | return .ok; | 28315 | return .ok; |
| 28316 | } | 28316 | } |
| 28317 | | 28317 | |
| | 28318 | // Arrays <-> Vectors |
| | 28319 | if ((dest_tag == .Vector and src_tag == .Array) or |
| | 28320 | (dest_tag == .Array and src_tag == .Vector)) |
| | 28321 | { |
| | 28322 | const dest_len = dest_ty.arrayLen(mod); |
| | 28323 | const src_len = src_ty.arrayLen(mod); |
| | 28324 | if (dest_len != src_len) { |
| | 28325 | return InMemoryCoercionResult{ .array_len = .{ |
| | 28326 | .actual = src_len, |
| | 28327 | .wanted = dest_len, |
| | 28328 | } }; |
| | 28329 | } |
| | 28330 | |
| | 28331 | const dest_elem_ty = dest_ty.childType(mod); |
| | 28332 | const src_elem_ty = src_ty.childType(mod); |
| | 28333 | const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src); |
| | 28334 | if (child != .ok) { |
| | 28335 | return InMemoryCoercionResult{ .array_elem = .{ |
| | 28336 | .child = try child.dupe(sema.arena), |
| | 28337 | .actual = src_elem_ty, |
| | 28338 | .wanted = dest_elem_ty, |
| | 28339 | } }; |
| | 28340 | } |
| | 28341 | |
| | 28342 | if (dest_tag == .Array) { |
| | 28343 | const dest_info = dest_ty.arrayInfo(mod); |
| | 28344 | if (dest_info.sentinel != null) { |
| | 28345 | return InMemoryCoercionResult{ .array_sentinel = .{ |
| | 28346 | .actual = Value.@"unreachable", |
| | 28347 | .wanted = dest_info.sentinel.?, |
| | 28348 | .ty = dest_info.elem_type, |
| | 28349 | } }; |
| | 28350 | } |
| | 28351 | } |
| | 28352 | |
| | 28353 | // The memory layout of @Vector(N, iM) is the same as the integer type i(N*M), |
| | 28354 | // that is to say, the padding bits are not in the same place as the array [N]iM. |
| | 28355 | // If there's no padding, the bitcast is possible. |
| | 28356 | const elem_bit_size = dest_elem_ty.bitSize(mod); |
| | 28357 | const elem_abi_byte_size = dest_elem_ty.abiSize(mod); |
| | 28358 | if (elem_abi_byte_size * 8 == elem_bit_size) |
| | 28359 | return .ok; |
| | 28360 | } |
| | 28361 | |
| 28318 | // Optionals | 28362 | // Optionals |
| 28319 | if (dest_tag == .Optional and src_tag == .Optional) { | 28363 | if (dest_tag == .Optional and src_tag == .Optional) { |
| 28320 | if ((maybe_dest_ptr_ty != null) != (maybe_src_ptr_ty != null)) { | 28364 | if ((maybe_dest_ptr_ty != null) != (maybe_src_ptr_ty != null)) { |
| ... | @@ -30205,10 +30249,22 @@ fn coerceArrayLike( | ... | @@ -30205,10 +30249,22 @@ fn coerceArrayLike( |
| 30205 | ) !Air.Inst.Ref { | 30249 | ) !Air.Inst.Ref { |
| 30206 | const mod = sema.mod; | 30250 | const mod = sema.mod; |
| 30207 | const inst_ty = sema.typeOf(inst); | 30251 | const inst_ty = sema.typeOf(inst); |
| 30208 | const inst_len = inst_ty.arrayLen(mod); | | |
| 30209 | const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(mod)); | | |
| 30210 | const target = mod.getTarget(); | 30252 | const target = mod.getTarget(); |
| 30211 | | 30253 | |
| | 30254 | // try coercion of the whole array |
| | 30255 | const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); |
| | 30256 | if (in_memory_result == .ok) { |
| | 30257 | if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { |
| | 30258 | // These types share the same comptime value representation. |
| | 30259 | return sema.coerceInMemory(inst_val, dest_ty); |
| | 30260 | } |
| | 30261 | try sema.requireRuntimeBlock(block, inst_src, null); |
| | 30262 | return block.addBitCast(dest_ty, inst); |
| | 30263 | } |
| | 30264 | |
| | 30265 | // otherwise, try element by element |
| | 30266 | const inst_len = inst_ty.arrayLen(mod); |
| | 30267 | const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(mod)); |
| 30212 | if (dest_len != inst_len) { | 30268 | if (dest_len != inst_len) { |
| 30213 | const msg = msg: { | 30269 | const msg = msg: { |
| 30214 | const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{ | 30270 | const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{ |
| ... | @@ -30223,17 +30279,6 @@ fn coerceArrayLike( | ... | @@ -30223,17 +30279,6 @@ fn coerceArrayLike( |
| 30223 | } | 30279 | } |
| 30224 | | 30280 | |
| 30225 | const dest_elem_ty = dest_ty.childType(mod); | 30281 | const dest_elem_ty = dest_ty.childType(mod); |
| 30226 | const inst_elem_ty = inst_ty.childType(mod); | | |
| 30227 | const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, false, target, dest_ty_src, inst_src); | | |
| 30228 | if (in_memory_result == .ok) { | | |
| 30229 | if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { | | |
| 30230 | // These types share the same comptime value representation. | | |
| 30231 | return sema.coerceInMemory(inst_val, dest_ty); | | |
| 30232 | } | | |
| 30233 | try sema.requireRuntimeBlock(block, inst_src, null); | | |
| 30234 | return block.addBitCast(dest_ty, inst); | | |
| 30235 | } | | |
| 30236 | | | |
| 30237 | const element_vals = try sema.arena.alloc(InternPool.Index, dest_len); | 30282 | const element_vals = try sema.arena.alloc(InternPool.Index, dest_len); |
| 30238 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_len); | 30283 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_len); |
| 30239 | var runtime_src: ?LazySrcLoc = null; | 30284 | var runtime_src: ?LazySrcLoc = null; |