| ... | ... | @@ -28115,6 +28115,50 @@ fn coerceInMemoryAllowed( |
| 28115 | 28115 | return .ok; |
| 28116 | 28116 | } |
| 28117 | 28117 | |
| 28118 | // Arrays <-> Vectors |
| 28119 | if ((dest_tag == .Vector and src_tag == .Array) or |
| 28120 | (dest_tag == .Array and src_tag == .Vector)) |
| 28121 | { |
| 28122 | const dest_len = dest_ty.arrayLen(mod); |
| 28123 | const src_len = src_ty.arrayLen(mod); |
| 28124 | if (dest_len != src_len) { |
| 28125 | return InMemoryCoercionResult{ .array_len = .{ |
| 28126 | .actual = src_len, |
| 28127 | .wanted = dest_len, |
| 28128 | } }; |
| 28129 | } |
| 28130 | |
| 28131 | const dest_elem_ty = dest_ty.childType(mod); |
| 28132 | const src_elem_ty = src_ty.childType(mod); |
| 28133 | const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src); |
| 28134 | if (child != .ok) { |
| 28135 | return InMemoryCoercionResult{ .array_elem = .{ |
| 28136 | .child = try child.dupe(sema.arena), |
| 28137 | .actual = src_elem_ty, |
| 28138 | .wanted = dest_elem_ty, |
| 28139 | } }; |
| 28140 | } |
| 28141 | |
| 28142 | if (dest_tag == .Array) { |
| 28143 | const dest_info = dest_ty.arrayInfo(mod); |
| 28144 | if (dest_info.sentinel != null) { |
| 28145 | return InMemoryCoercionResult{ .array_sentinel = .{ |
| 28146 | .actual = Value.@"unreachable", |
| 28147 | .wanted = dest_info.sentinel.?, |
| 28148 | .ty = dest_info.elem_type, |
| 28149 | } }; |
| 28150 | } |
| 28151 | } |
| 28152 | |
| 28153 | // The memory layout of @Vector(N, iM) is the same as the integer type i(N*M), |
| 28154 | // that is to say, the padding bits are not in the same place as the array [N]iM. |
| 28155 | // If there's no padding, the bitcast is possible. |
| 28156 | const elem_bit_size = dest_elem_ty.bitSize(mod); |
| 28157 | const elem_abi_byte_size = dest_elem_ty.abiSize(mod); |
| 28158 | if (elem_abi_byte_size * 8 == elem_bit_size) |
| 28159 | return .ok; |
| 28160 | } |
| 28161 | |
| 28118 | 28162 | // Optionals |
| 28119 | 28163 | if (dest_tag == .Optional and src_tag == .Optional) { |
| 28120 | 28164 | if ((maybe_dest_ptr_ty != null) != (maybe_src_ptr_ty != null)) { |
| ... | ... | @@ -30005,10 +30049,22 @@ fn coerceArrayLike( |
| 30005 | 30049 | ) !Air.Inst.Ref { |
| 30006 | 30050 | const mod = sema.mod; |
| 30007 | 30051 | const inst_ty = sema.typeOf(inst); |
| 30008 | | const inst_len = inst_ty.arrayLen(mod); |
| 30009 | | const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(mod)); |
| 30010 | 30052 | const target = mod.getTarget(); |
| 30011 | 30053 | |
| 30054 | // try coercion of the whole array |
| 30055 | const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); |
| 30056 | if (in_memory_result == .ok) { |
| 30057 | if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { |
| 30058 | // These types share the same comptime value representation. |
| 30059 | return sema.coerceInMemory(inst_val, dest_ty); |
| 30060 | } |
| 30061 | try sema.requireRuntimeBlock(block, inst_src, null); |
| 30062 | return block.addBitCast(dest_ty, inst); |
| 30063 | } |
| 30064 | |
| 30065 | // otherwise, try element by element |
| 30066 | const inst_len = inst_ty.arrayLen(mod); |
| 30067 | const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(mod)); |
| 30012 | 30068 | if (dest_len != inst_len) { |
| 30013 | 30069 | const msg = msg: { |
| 30014 | 30070 | const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{ |
| ... | ... | @@ -30023,17 +30079,6 @@ fn coerceArrayLike( |
| 30023 | 30079 | } |
| 30024 | 30080 | |
| 30025 | 30081 | const dest_elem_ty = dest_ty.childType(mod); |
| 30026 | | const inst_elem_ty = inst_ty.childType(mod); |
| 30027 | | const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, false, target, dest_ty_src, inst_src); |
| 30028 | | if (in_memory_result == .ok) { |
| 30029 | | if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { |
| 30030 | | // These types share the same comptime value representation. |
| 30031 | | return sema.coerceInMemory(inst_val, dest_ty); |
| 30032 | | } |
| 30033 | | try sema.requireRuntimeBlock(block, inst_src, null); |
| 30034 | | return block.addBitCast(dest_ty, inst); |
| 30035 | | } |
| 30036 | | |
| 30037 | 30082 | const element_vals = try sema.arena.alloc(InternPool.Index, dest_len); |
| 30038 | 30083 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_len); |
| 30039 | 30084 | var runtime_src: ?LazySrcLoc = null; |