authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-11-29 15:05:49-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-11-29 15:05:49-05:00
logcfdb001a8f0353466a4445cc046341ce9cc43fc5
treecc4a7aa548bef863781069b643f89cc19547401b
parent4a73b8cbb3cf1a7047da445790d39eef8474c652
parent77f16d457b4238c91aa0a686114af96b0548daf7
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22099 from Rexicon226/fix-cat-mul

change `++` and `**` to not return mutable pointers

2 files changed, 81 insertions(+), 5 deletions(-)

src/Sema.zig+78-2
......@@ -15226,7 +15226,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1522615226 if (ptr_addrspace) |ptr_as| {
1522715227 const alloc_ty = try pt.ptrTypeSema(.{
1522815228 .child = result_ty.toIntern(),
15229 .flags = .{ .address_space = ptr_as },
15229 .flags = .{
15230 .address_space = ptr_as,
15231 .is_const = true,
15232 },
1523015233 });
1523115234 const alloc = try block.addTy(.alloc, alloc_ty);
1523215235 const elem_ptr_ty = try pt.ptrTypeSema(.{
......@@ -15234,6 +15237,76 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1523415237 .flags = .{ .address_space = ptr_as },
1523515238 });
1523615239
15240 // if both the source and destination are arrays
15241 // we can hot path via a memcpy.
15242 if (lhs_ty.zigTypeTag(zcu) == .pointer and
15243 rhs_ty.zigTypeTag(zcu) == .pointer)
15244 {
15245 const slice_ty = try pt.ptrTypeSema(.{
15246 .child = resolved_elem_ty.toIntern(),
15247 .flags = .{
15248 .size = .Slice,
15249 .address_space = ptr_as,
15250 },
15251 });
15252 const many_ty = try pt.ptrTypeSema(.{
15253 .child = resolved_elem_ty.toIntern(),
15254 .flags = .{
15255 .size = .Many,
15256 .address_space = ptr_as,
15257 },
15258 });
15259 const slice_ty_ref = Air.internedToRef(slice_ty.toIntern());
15260
15261 // lhs_dest_slice = dest[0..lhs.len]
15262 const lhs_len_ref = try pt.intRef(Type.usize, lhs_len);
15263 const lhs_dest_slice = try block.addInst(.{
15264 .tag = .slice,
15265 .data = .{ .ty_pl = .{
15266 .ty = slice_ty_ref,
15267 .payload = try sema.addExtra(Air.Bin{
15268 .lhs = alloc,
15269 .rhs = lhs_len_ref,
15270 }),
15271 } },
15272 });
15273 _ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
15274
15275 // rhs_dest_slice = dest[lhs.len..][0..rhs.len]
15276 const rhs_len_ref = try pt.intRef(Type.usize, rhs_len);
15277 const rhs_dest_offset = try block.addInst(.{
15278 .tag = .ptr_add,
15279 .data = .{ .ty_pl = .{
15280 .ty = Air.internedToRef(many_ty.toIntern()),
15281 .payload = try sema.addExtra(Air.Bin{
15282 .lhs = alloc,
15283 .rhs = lhs_len_ref,
15284 }),
15285 } },
15286 });
15287 const rhs_dest_slice = try block.addInst(.{
15288 .tag = .slice,
15289 .data = .{ .ty_pl = .{
15290 .ty = slice_ty_ref,
15291 .payload = try sema.addExtra(Air.Bin{
15292 .lhs = rhs_dest_offset,
15293 .rhs = rhs_len_ref,
15294 }),
15295 } },
15296 });
15297
15298 _ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
15299
15300 if (res_sent_val) |sent_val| {
15301 const elem_index = try pt.intRef(Type.usize, result_len);
15302 const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
15303 const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern());
15304 try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);
15305 }
15306
15307 return alloc;
15308 }
15309
1523715310 var elem_i: u32 = 0;
1523815311 while (elem_i < lhs_len) : (elem_i += 1) {
1523915312 const elem_index = try pt.intRef(Type.usize, elem_i);
......@@ -15558,7 +15631,10 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1555815631 if (ptr_addrspace) |ptr_as| {
1555915632 const alloc_ty = try pt.ptrTypeSema(.{
1556015633 .child = result_ty.toIntern(),
15561 .flags = .{ .address_space = ptr_as },
15634 .flags = .{
15635 .address_space = ptr_as,
15636 .is_const = true,
15637 },
1556215638 });
1556315639 const alloc = try block.addTy(.alloc, alloc_ty);
1556415640 const elem_ptr_ty = try pt.ptrTypeSema(.{
test/behavior/eval.zig+3-3
......@@ -786,7 +786,7 @@ test "array concatenation peer resolves element types - pointer" {
786786 var a = [2]u3{ 1, 7 };
787787 var b = [3]u8{ 200, 225, 255 };
788788 const c = &a ++ &b;
789 comptime assert(@TypeOf(c) == *[5]u8);
789 comptime assert(@TypeOf(c) == *const [5]u8);
790790 try expect(c[0] == 1);
791791 try expect(c[1] == 7);
792792 try expect(c[2] == 200);
......@@ -822,7 +822,7 @@ test "array concatenation sets the sentinel - pointer" {
822822 var a = [2]u3{ 1, 7 };
823823 var b = [3:69]u8{ 200, 225, 255 };
824824 const c = &a ++ &b;
825 comptime assert(@TypeOf(c) == *[5:69]u8);
825 comptime assert(@TypeOf(c) == *const [5:69]u8);
826826 try expect(c[0] == 1);
827827 try expect(c[1] == 7);
828828 try expect(c[2] == 200);
......@@ -858,7 +858,7 @@ test "array multiplication sets the sentinel - pointer" {
858858
859859 var a = [2:7]u3{ 1, 6 };
860860 const b = &a ** 2;
861 comptime assert(@TypeOf(b) == *[4:7]u3);
861 comptime assert(@TypeOf(b) == *const [4:7]u3);
862862 try expect(b[0] == 1);
863863 try expect(b[1] == 6);
864864 try expect(b[2] == 1);