| ... | ... | @@ -8072,9 +8072,9 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 8072 | 8072 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 8073 | 8073 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 8074 | 8074 | |
| 8075 | | const lhs_info = getArrayCatInfo(lhs_ty) orelse |
| 8075 | const lhs_info = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse |
| 8076 | 8076 | return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty}); |
| 8077 | | const rhs_info = getArrayCatInfo(rhs_ty) orelse |
| 8077 | const rhs_info = (try sema.getArrayCatInfo(block, rhs_src, rhs)) orelse |
| 8078 | 8078 | return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty}); |
| 8079 | 8079 | if (!lhs_info.elem_type.eql(rhs_info.elem_type)) { |
| 8080 | 8080 | return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{ lhs_info.elem_type, rhs_ty }); |
| ... | ... | @@ -8095,9 +8095,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 8095 | 8095 | const rhs_len = try sema.usizeCast(block, lhs_src, rhs_info.len); |
| 8096 | 8096 | const final_len = lhs_len + rhs_len; |
| 8097 | 8097 | const final_len_including_sent = final_len + @boolToInt(res_sent != null); |
| 8098 | | const is_pointer = lhs_ty.zigTypeTag() == .Pointer; |
| 8099 | | const lhs_sub_val = if (is_pointer) (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? else lhs_val; |
| 8100 | | const rhs_sub_val = if (is_pointer) (try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).? else rhs_val; |
| 8098 | const lhs_single_ptr = lhs_ty.zigTypeTag() == .Pointer and !lhs_ty.isSlice(); |
| 8099 | const rhs_single_ptr = rhs_ty.zigTypeTag() == .Pointer and !rhs_ty.isSlice(); |
| 8100 | const lhs_sub_val = if (lhs_single_ptr) (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? else lhs_val; |
| 8101 | const rhs_sub_val = if (rhs_single_ptr) (try sema.pointerDeref(block, rhs_src, rhs_val, rhs_ty)).? else rhs_val; |
| 8101 | 8102 | var anon_decl = try block.startAnonDecl(LazySrcLoc.unneeded); |
| 8102 | 8103 | defer anon_decl.deinit(); |
| 8103 | 8104 | |
| ... | ... | @@ -8129,7 +8130,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 8129 | 8130 | }); |
| 8130 | 8131 | const val = try Value.Tag.array.create(anon_decl.arena(), buf); |
| 8131 | 8132 | const decl = try anon_decl.finish(ty, val); |
| 8132 | | if (is_pointer) { |
| 8133 | if (lhs_single_ptr or rhs_single_ptr) { |
| 8133 | 8134 | return sema.analyzeDeclRef(decl); |
| 8134 | 8135 | } else { |
| 8135 | 8136 | return sema.analyzeDeclVal(block, .unneeded, decl); |
| ... | ... | @@ -8142,11 +8143,20 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 8142 | 8143 | } |
| 8143 | 8144 | } |
| 8144 | 8145 | |
| 8145 | | fn getArrayCatInfo(t: Type) ?Type.ArrayInfo { |
| 8146 | fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref) !?Type.ArrayInfo { |
| 8147 | const t = sema.typeOf(inst); |
| 8146 | 8148 | return switch (t.zigTypeTag()) { |
| 8147 | 8149 | .Array => t.arrayInfo(), |
| 8148 | 8150 | .Pointer => blk: { |
| 8149 | 8151 | const ptrinfo = t.ptrInfo().data; |
| 8152 | if (ptrinfo.size == .Slice) { |
| 8153 | const val = try sema.resolveConstValue(block, src, inst); |
| 8154 | return Type.ArrayInfo{ |
| 8155 | .elem_type = t.childType(), |
| 8156 | .sentinel = t.sentinel(), |
| 8157 | .len = val.sliceLen(), |
| 8158 | }; |
| 8159 | } |
| 8150 | 8160 | if (ptrinfo.pointee_type.zigTypeTag() != .Array) return null; |
| 8151 | 8161 | if (ptrinfo.size != .One) return null; |
| 8152 | 8162 | break :blk ptrinfo.pointee_type.arrayInfo(); |
| ... | ... | @@ -8169,7 +8179,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 8169 | 8179 | |
| 8170 | 8180 | // In `**` rhs has to be comptime-known, but lhs can be runtime-known |
| 8171 | 8181 | const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize); |
| 8172 | | const mulinfo = getArrayCatInfo(lhs_ty) orelse |
| 8182 | const mulinfo = (try sema.getArrayCatInfo(block, lhs_src, lhs)) orelse |
| 8173 | 8183 | return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty}); |
| 8174 | 8184 | |
| 8175 | 8185 | const final_len_u64 = std.math.mul(u64, mulinfo.len, factor) catch |
| ... | ... | @@ -8180,7 +8190,8 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 8180 | 8190 | const final_len_including_sent = final_len + @boolToInt(mulinfo.sentinel != null); |
| 8181 | 8191 | const lhs_len = try sema.usizeCast(block, lhs_src, mulinfo.len); |
| 8182 | 8192 | |
| 8183 | | const lhs_sub_val = if (lhs_ty.zigTypeTag() == .Pointer) (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? else lhs_val; |
| 8193 | const is_single_ptr = lhs_ty.zigTypeTag() == .Pointer and !lhs_ty.isSlice(); |
| 8194 | const lhs_sub_val = if (is_single_ptr) (try sema.pointerDeref(block, lhs_src, lhs_val, lhs_ty)).? else lhs_val; |
| 8184 | 8195 | |
| 8185 | 8196 | var anon_decl = try block.startAnonDecl(src); |
| 8186 | 8197 | defer anon_decl.deinit(); |
| ... | ... | @@ -8220,7 +8231,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 8220 | 8231 | break :blk try Value.Tag.array.create(anon_decl.arena(), buf); |
| 8221 | 8232 | }; |
| 8222 | 8233 | const decl = try anon_decl.finish(final_ty, val); |
| 8223 | | if (lhs_ty.zigTypeTag() == .Pointer) { |
| 8234 | if (is_single_ptr) { |
| 8224 | 8235 | return sema.analyzeDeclRef(decl); |
| 8225 | 8236 | } else { |
| 8226 | 8237 | return sema.analyzeDeclVal(block, .unneeded, decl); |