std: work around language changes

This commit is contained in:
Matthew Lugg 2026-01-25 11:12:26 +00:00
parent eae122b3aa
commit 372b3c33c1
No known key found for this signature in database
GPG key ID: 3F5B7DCCBF4AF02E
6 changed files with 23 additions and 16 deletions

View file

@ -1071,7 +1071,7 @@ pub const Elf32 = struct {
pub const Shdr = extern struct {
name: Word,
type: SHT,
flags: packed struct { shf: SHF },
flags: packed struct(Word) { shf: SHF },
addr: Elf32.Addr,
offset: Elf32.Off,
size: Word,
@ -1161,7 +1161,7 @@ pub const Elf64 = struct {
pub const Shdr = extern struct {
name: Word,
type: SHT,
flags: packed struct { shf: SHF, unused: Word = 0 },
flags: packed struct(Xword) { shf: SHF, unused: Word = 0 },
addr: Elf64.Addr,
offset: Elf64.Off,
size: Xword,

View file

@ -315,7 +315,7 @@ test declarationInfo {
try testing.expect(comptime mem.eql(u8, info.name, "a"));
}
}
pub fn fields(comptime T: type) switch (@typeInfo(T)) {
pub inline fn fields(comptime T: type) switch (@typeInfo(T)) {
.@"struct" => []const Type.StructField,
.@"union" => []const Type.UnionField,
.@"enum" => []const Type.EnumField,

View file

@ -19,7 +19,11 @@ const testing = std.testing;
/// For unions you can call `.items(.tags)` or `.items(.data)`.
pub fn MultiArrayList(comptime T: type) type {
return struct {
bytes: [*]align(@alignOf(T)) u8 = undefined,
/// This pointer is always aligned to the boundary `sizes.big_align`; this is not specified
/// in the type to avoid `MultiArrayList(T)` depending on the alignment of `T` because this
/// can lead to dependency loops. See `allocatedBytes` which `@alignCast`s this pointer to
/// the correct type.
bytes: [*]u8 = undefined,
len: usize = 0,
capacity: usize = 0,
@ -133,10 +137,8 @@ pub fn MultiArrayList(comptime T: type) type {
if (self.ptrs.len == 0 or self.capacity == 0) {
return .{};
}
const unaligned_ptr = self.ptrs[sizes.fields[0]];
const aligned_ptr: [*]align(@alignOf(Elem)) u8 = @alignCast(unaligned_ptr);
return .{
.bytes = aligned_ptr,
.bytes = self.ptrs[sizes.fields[0]],
.len = self.len,
.capacity = self.capacity,
};
@ -179,6 +181,7 @@ pub fn MultiArrayList(comptime T: type) type {
const fields = meta.fields(Elem);
/// `sizes.bytes` is an array of @sizeOf each T field. Sorted by alignment, descending.
/// `sizes.fields` is an array mapping from `sizes.bytes` array index to field index.
/// `sizes.big_align` is the overall alignment of the allocation, which equals the maximum field alignment.
const sizes = blk: {
const Data = struct {
size: usize,
@ -186,12 +189,14 @@ pub fn MultiArrayList(comptime T: type) type {
alignment: usize,
};
var data: [fields.len]Data = undefined;
var big_align: usize = 1;
for (fields, 0..) |field_info, i| {
data[i] = .{
.size = @sizeOf(field_info.type),
.size_index = i,
.alignment = if (@sizeOf(field_info.type) == 0) 1 else field_info.alignment,
};
big_align = @max(big_align, @alignOf(field_info.type));
}
const Sort = struct {
fn lessThan(context: void, lhs: Data, rhs: Data) bool {
@ -210,6 +215,7 @@ pub fn MultiArrayList(comptime T: type) type {
break :blk .{
.bytes = sizes_bytes,
.fields = field_indexes,
.big_align = mem.Alignment.fromByteUnits(big_align),
};
};
@ -452,7 +458,7 @@ pub fn MultiArrayList(comptime T: type) type {
assert(new_len <= self.capacity);
assert(new_len <= self.len);
const other_bytes = gpa.alignedAlloc(u8, .of(Elem), capacityInBytes(new_len)) catch {
const other_bytes = gpa.alignedAlloc(u8, sizes.big_align, capacityInBytes(new_len)) catch {
const self_slice = self.slice();
inline for (fields, 0..) |field_info, i| {
if (@sizeOf(field_info.type) != 0) {
@ -533,7 +539,7 @@ pub fn MultiArrayList(comptime T: type) type {
/// `new_capacity` must be greater or equal to `len`.
pub fn setCapacity(self: *Self, gpa: Allocator, new_capacity: usize) Allocator.Error!void {
assert(new_capacity >= self.len);
const new_bytes = try gpa.alignedAlloc(u8, .of(Elem), capacityInBytes(new_capacity));
const new_bytes = try gpa.alignedAlloc(u8, sizes.big_align, capacityInBytes(new_capacity));
if (self.len == 0) {
gpa.free(self.allocatedBytes());
self.bytes = new_bytes.ptr;
@ -650,8 +656,8 @@ pub fn MultiArrayList(comptime T: type) type {
return elem_bytes * capacity;
}
fn allocatedBytes(self: Self) []align(@alignOf(Elem)) u8 {
return self.bytes[0..capacityInBytes(self.capacity)];
fn allocatedBytes(self: Self) []align(sizes.big_align.toByteUnits()) u8 {
return @alignCast(self.bytes[0..capacityInBytes(self.capacity)]);
}
fn FieldType(comptime field: Field) type {

View file

@ -7113,7 +7113,7 @@ pub const io_uring_buf_reg = extern struct {
flags: Flags,
resv: [3]u64,
pub const Flags = packed struct {
pub const Flags = packed struct(u16) {
_0: u1 = 0,
/// Incremental buffer consumption.
inc: bool,

View file

@ -950,9 +950,8 @@ test "expectEqualDeep primitive type" {
}
test "expectEqualDeep pointer" {
const a = 1;
const b = 1;
try expectEqualDeep(&a, &b);
try comptime expectEqualDeep(&1, &1);
try expectEqualDeep(&@as(u32, 1), &@as(u32, 1));
}
test "expectEqualDeep composite type" {

View file

@ -793,9 +793,11 @@ test checkValueDepth {
try expectValueDepthEquals(2, @as(?u32, 1));
try expectValueDepthEquals(1, @as(?u32, null));
try expectValueDepthEquals(1, null);
try expectValueDepthEquals(2, &1);
try expectValueDepthEquals(3, &@as(?u32, 1));
// The pointer drops the implicit comptime-ness, so we need to specify 'comptime' here
try comptime expectValueDepthEquals(2, &1);
const Union = union(enum) {
x: u32,
y: struct { x: u32 },