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

change `++` and `**` to not return mutable pointers
This commit is contained in:
Andrew Kelley 2024-11-29 15:05:49 -05:00 committed by GitHub
commit cfdb001a8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 81 additions and 5 deletions

View File

@ -15226,7 +15226,10 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
if (ptr_addrspace) |ptr_as| {
const alloc_ty = try pt.ptrTypeSema(.{
.child = result_ty.toIntern(),
.flags = .{ .address_space = ptr_as },
.flags = .{
.address_space = ptr_as,
.is_const = true,
},
});
const alloc = try block.addTy(.alloc, alloc_ty);
const elem_ptr_ty = try pt.ptrTypeSema(.{
@ -15234,6 +15237,76 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
.flags = .{ .address_space = ptr_as },
});
// if both the source and destination are arrays
// we can hot path via a memcpy.
if (lhs_ty.zigTypeTag(zcu) == .pointer and
rhs_ty.zigTypeTag(zcu) == .pointer)
{
const slice_ty = try pt.ptrTypeSema(.{
.child = resolved_elem_ty.toIntern(),
.flags = .{
.size = .Slice,
.address_space = ptr_as,
},
});
const many_ty = try pt.ptrTypeSema(.{
.child = resolved_elem_ty.toIntern(),
.flags = .{
.size = .Many,
.address_space = ptr_as,
},
});
const slice_ty_ref = Air.internedToRef(slice_ty.toIntern());
// lhs_dest_slice = dest[0..lhs.len]
const lhs_len_ref = try pt.intRef(Type.usize, lhs_len);
const lhs_dest_slice = try block.addInst(.{
.tag = .slice,
.data = .{ .ty_pl = .{
.ty = slice_ty_ref,
.payload = try sema.addExtra(Air.Bin{
.lhs = alloc,
.rhs = lhs_len_ref,
}),
} },
});
_ = try block.addBinOp(.memcpy, lhs_dest_slice, lhs);
// rhs_dest_slice = dest[lhs.len..][0..rhs.len]
const rhs_len_ref = try pt.intRef(Type.usize, rhs_len);
const rhs_dest_offset = try block.addInst(.{
.tag = .ptr_add,
.data = .{ .ty_pl = .{
.ty = Air.internedToRef(many_ty.toIntern()),
.payload = try sema.addExtra(Air.Bin{
.lhs = alloc,
.rhs = lhs_len_ref,
}),
} },
});
const rhs_dest_slice = try block.addInst(.{
.tag = .slice,
.data = .{ .ty_pl = .{
.ty = slice_ty_ref,
.payload = try sema.addExtra(Air.Bin{
.lhs = rhs_dest_offset,
.rhs = rhs_len_ref,
}),
} },
});
_ = try block.addBinOp(.memcpy, rhs_dest_slice, rhs);
if (res_sent_val) |sent_val| {
const elem_index = try pt.intRef(Type.usize, result_len);
const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty);
const init = Air.internedToRef((try pt.getCoerced(sent_val, lhs_info.elem_type)).toIntern());
try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store);
}
return alloc;
}
var elem_i: u32 = 0;
while (elem_i < lhs_len) : (elem_i += 1) {
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
if (ptr_addrspace) |ptr_as| {
const alloc_ty = try pt.ptrTypeSema(.{
.child = result_ty.toIntern(),
.flags = .{ .address_space = ptr_as },
.flags = .{
.address_space = ptr_as,
.is_const = true,
},
});
const alloc = try block.addTy(.alloc, alloc_ty);
const elem_ptr_ty = try pt.ptrTypeSema(.{

View File

@ -786,7 +786,7 @@ test "array concatenation peer resolves element types - pointer" {
var a = [2]u3{ 1, 7 };
var b = [3]u8{ 200, 225, 255 };
const c = &a ++ &b;
comptime assert(@TypeOf(c) == *[5]u8);
comptime assert(@TypeOf(c) == *const [5]u8);
try expect(c[0] == 1);
try expect(c[1] == 7);
try expect(c[2] == 200);
@ -822,7 +822,7 @@ test "array concatenation sets the sentinel - pointer" {
var a = [2]u3{ 1, 7 };
var b = [3:69]u8{ 200, 225, 255 };
const c = &a ++ &b;
comptime assert(@TypeOf(c) == *[5:69]u8);
comptime assert(@TypeOf(c) == *const [5:69]u8);
try expect(c[0] == 1);
try expect(c[1] == 7);
try expect(c[2] == 200);
@ -858,7 +858,7 @@ test "array multiplication sets the sentinel - pointer" {
var a = [2:7]u3{ 1, 6 };
const b = &a ** 2;
comptime assert(@TypeOf(b) == *[4:7]u3);
comptime assert(@TypeOf(b) == *const [4:7]u3);
try expect(b[0] == 1);
try expect(b[1] == 6);
try expect(b[2] == 1);