diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-06-24 16:58:19 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-24 16:58:19 -0700 |
| commit | 146b79af153bbd5dafda0ba12a040385c7fc58f8 (patch) | |
| tree | 67e3db8b444d65c667e314770fc983a7fc8ba293 /lib/std/mem.zig | |
| parent | 13853bef0df3c90633021850cc6d6abaeea03282 (diff) | |
| parent | 21ac0beb436f49fe49c6982a872f2dc48e4bea5e (diff) | |
| download | zig-146b79af153bbd5dafda0ba12a040385c7fc58f8.tar.gz zig-146b79af153bbd5dafda0ba12a040385c7fc58f8.zip | |
Merge pull request #16163 from mlugg/feat/builtins-infer-dest-ty
Infer destination type of cast builtins using result type
Diffstat (limited to 'lib/std/mem.zig')
| -rw-r--r-- | lib/std/mem.zig | 223 |
1 files changed, 110 insertions, 113 deletions
diff --git a/lib/std/mem.zig b/lib/std/mem.zig index bbeecdda23..229bc0b63e 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -69,7 +69,7 @@ pub fn ValidationAllocator(comptime T: type) type { ret_addr: usize, ) ?[*]u8 { assert(n > 0); - const self = @ptrCast(*Self, @alignCast(@alignOf(Self), ctx)); + const self: *Self = @ptrCast(@alignCast(ctx)); const underlying = self.getUnderlyingAllocatorPtr(); const result = underlying.rawAlloc(n, log2_ptr_align, ret_addr) orelse return null; @@ -84,7 +84,7 @@ pub fn ValidationAllocator(comptime T: type) type { new_len: usize, ret_addr: usize, ) bool { - const self = @ptrCast(*Self, @alignCast(@alignOf(Self), ctx)); + const self: *Self = @ptrCast(@alignCast(ctx)); assert(buf.len > 0); const underlying = self.getUnderlyingAllocatorPtr(); return underlying.rawResize(buf, log2_buf_align, new_len, ret_addr); @@ -96,7 +96,7 @@ pub fn ValidationAllocator(comptime T: type) type { log2_buf_align: u8, ret_addr: usize, ) void { - const self = @ptrCast(*Self, @alignCast(@alignOf(Self), ctx)); + const self: *Self = @ptrCast(@alignCast(ctx)); assert(buf.len > 0); const underlying = self.getUnderlyingAllocatorPtr(); underlying.rawFree(buf, log2_buf_align, ret_addr); @@ -169,7 +169,7 @@ test "Allocator.resize" { var values = try testing.allocator.alloc(T, 100); defer testing.allocator.free(values); - for (values, 0..) |*v, i| v.* = @intCast(T, i); + for (values, 0..) |*v, i| v.* = @as(T, @intCast(i)); if (!testing.allocator.resize(values, values.len + 10)) return error.OutOfMemory; values = values.ptr[0 .. values.len + 10]; try testing.expect(values.len == 110); @@ -185,7 +185,7 @@ test "Allocator.resize" { var values = try testing.allocator.alloc(T, 100); defer testing.allocator.free(values); - for (values, 0..) |*v, i| v.* = @floatFromInt(T, i); + for (values, 0..) |*v, i| v.* = @as(T, @floatFromInt(i)); if (!testing.allocator.resize(values, values.len + 10)) return error.OutOfMemory; values = values.ptr[0 .. values.len + 10]; try testing.expect(values.len == 110); @@ -233,7 +233,7 @@ pub fn zeroes(comptime T: type) T { return @as(T, 0); }, .Enum, .EnumLiteral => { - return @enumFromInt(T, 0); + return @as(T, @enumFromInt(0)); }, .Void => { return {}; @@ -264,7 +264,7 @@ pub fn zeroes(comptime T: type) T { switch (ptr_info.size) { .Slice => { if (ptr_info.sentinel) |sentinel| { - if (ptr_info.child == u8 and @ptrCast(*const u8, sentinel).* == 0) { + if (ptr_info.child == u8 and @as(*const u8, @ptrCast(sentinel)).* == 0) { return ""; // A special case for the most common use-case: null-terminated strings. } @compileError("Can't set a sentinel slice to zero. This would require allocating memory."); @@ -282,7 +282,7 @@ pub fn zeroes(comptime T: type) T { }, .Array => |info| { if (info.sentinel) |sentinel_ptr| { - const sentinel = @ptrCast(*align(1) const info.child, sentinel_ptr).*; + const sentinel = @as(*align(1) const info.child, @ptrCast(sentinel_ptr)).*; return [_:sentinel]info.child{zeroes(info.child)} ** info.len; } return [_]info.child{zeroes(info.child)} ** info.len; @@ -456,7 +456,7 @@ pub fn zeroInit(comptime T: type, init: anytype) T { }, } } else if (field.default_value) |default_value_ptr| { - const default_value = @ptrCast(*align(1) const field.type, default_value_ptr).*; + const default_value = @as(*align(1) const field.type, @ptrCast(default_value_ptr)).*; @field(value, field.name) = default_value; } else { switch (@typeInfo(field.type)) { @@ -709,7 +709,7 @@ pub fn span(ptr: anytype) Span(@TypeOf(ptr)) { const l = len(ptr); const ptr_info = @typeInfo(Result).Pointer; if (ptr_info.sentinel) |s_ptr| { - const s = @ptrCast(*align(1) const ptr_info.child, s_ptr).*; + const s = @as(*align(1) const ptr_info.child, @ptrCast(s_ptr)).*; return ptr[0..l :s]; } else { return ptr[0..l]; @@ -740,7 +740,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type { // to find the value searched for, which is only the case if it matches // the sentinel of the type passed. if (array_info.sentinel) |sentinel_ptr| { - const sentinel = @ptrCast(*align(1) const array_info.child, sentinel_ptr).*; + const sentinel = @as(*align(1) const array_info.child, @ptrCast(sentinel_ptr)).*; if (end == sentinel) { new_ptr_info.sentinel = &end; } else { @@ -755,7 +755,7 @@ fn SliceTo(comptime T: type, comptime end: meta.Elem(T)) type { // to find the value searched for, which is only the case if it matches // the sentinel of the type passed. if (ptr_info.sentinel) |sentinel_ptr| { - const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*; + const sentinel = @as(*align(1) const ptr_info.child, @ptrCast(sentinel_ptr)).*; if (end == sentinel) { new_ptr_info.sentinel = &end; } else { @@ -793,7 +793,7 @@ pub fn sliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) SliceTo(@Typ const length = lenSliceTo(ptr, end); const ptr_info = @typeInfo(Result).Pointer; if (ptr_info.sentinel) |s_ptr| { - const s = @ptrCast(*align(1) const ptr_info.child, s_ptr).*; + const s = @as(*align(1) const ptr_info.child, @ptrCast(s_ptr)).*; return ptr[0..length :s]; } else { return ptr[0..length]; @@ -810,11 +810,11 @@ test "sliceTo" { try testing.expectEqualSlices(u16, array[0..2], sliceTo(&array, 3)); try testing.expectEqualSlices(u16, array[0..2], sliceTo(array[0..3], 3)); - const sentinel_ptr = @ptrCast([*:5]u16, &array); + const sentinel_ptr = @as([*:5]u16, @ptrCast(&array)); try testing.expectEqualSlices(u16, array[0..2], sliceTo(sentinel_ptr, 3)); try testing.expectEqualSlices(u16, array[0..4], sliceTo(sentinel_ptr, 99)); - const optional_sentinel_ptr = @ptrCast(?[*:5]u16, &array); + const optional_sentinel_ptr = @as(?[*:5]u16, @ptrCast(&array)); try testing.expectEqualSlices(u16, array[0..2], sliceTo(optional_sentinel_ptr, 3).?); try testing.expectEqualSlices(u16, array[0..4], sliceTo(optional_sentinel_ptr, 99).?); @@ -846,7 +846,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { .One => switch (@typeInfo(ptr_info.child)) { .Array => |array_info| { if (array_info.sentinel) |sentinel_ptr| { - const sentinel = @ptrCast(*align(1) const array_info.child, sentinel_ptr).*; + const sentinel = @as(*align(1) const array_info.child, @ptrCast(sentinel_ptr)).*; if (sentinel == end) { return indexOfSentinel(array_info.child, end, ptr); } @@ -856,7 +856,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { else => {}, }, .Many => if (ptr_info.sentinel) |sentinel_ptr| { - const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*; + const sentinel = @as(*align(1) const ptr_info.child, @ptrCast(sentinel_ptr)).*; // We may be looking for something other than the sentinel, // but iterating past the sentinel would be a bug so we need // to check for both. @@ -870,7 +870,7 @@ fn lenSliceTo(ptr: anytype, comptime end: meta.Elem(@TypeOf(ptr))) usize { }, .Slice => { if (ptr_info.sentinel) |sentinel_ptr| { - const sentinel = @ptrCast(*align(1) const ptr_info.child, sentinel_ptr).*; + const sentinel = @as(*align(1) const ptr_info.child, @ptrCast(sentinel_ptr)).*; if (sentinel == end) { return indexOfSentinel(ptr_info.child, sentinel, ptr); } @@ -893,7 +893,7 @@ test "lenSliceTo" { try testing.expectEqual(@as(usize, 2), lenSliceTo(&array, 3)); try testing.expectEqual(@as(usize, 2), lenSliceTo(array[0..3], 3)); - const sentinel_ptr = @ptrCast([*:5]u16, &array); + const sentinel_ptr = @as([*:5]u16, @ptrCast(&array)); try testing.expectEqual(@as(usize, 2), lenSliceTo(sentinel_ptr, 3)); try testing.expectEqual(@as(usize, 4), lenSliceTo(sentinel_ptr, 99)); @@ -925,7 +925,7 @@ pub fn len(value: anytype) usize { .Many => { const sentinel_ptr = info.sentinel orelse @compileError("invalid type given to std.mem.len: " ++ @typeName(@TypeOf(value))); - const sentinel = @ptrCast(*align(1) const info.child, sentinel_ptr).*; + const sentinel = @as(*align(1) const info.child, @ptrCast(sentinel_ptr)).*; return indexOfSentinel(info.child, sentinel, value); }, .C => { @@ -1331,7 +1331,7 @@ pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: Endian) .Little => { const ShiftType = math.Log2Int(ReturnType); for (bytes, 0..) |b, index| { - result = result | (@as(ReturnType, b) << @intCast(ShiftType, index * 8)); + result = result | (@as(ReturnType, b) << @as(ShiftType, @intCast(index * 8))); } }, } @@ -1359,8 +1359,8 @@ pub fn readVarPackedInt( const Log2N = std.math.Log2Int(T); const read_size = (bit_count + (bit_offset % 8) + 7) / 8; - const bit_shift = @intCast(u3, bit_offset % 8); - const pad = @intCast(Log2N, @bitSizeOf(T) - bit_count); + const bit_shift = @as(u3, @intCast(bit_offset % 8)); + const pad = @as(Log2N, @intCast(@bitSizeOf(T) - bit_count)); const lowest_byte = switch (endian) { .Big => bytes.len - (bit_offset / 8) - read_size, @@ -1372,17 +1372,17 @@ pub fn readVarPackedInt( // These are the same shifts/masks we perform below, but adds `@truncate`/`@intCast` // where needed since int is smaller than a byte. const value = if (read_size == 1) b: { - break :b @truncate(uN, read_bytes[0] >> bit_shift); + break :b @as(uN, @truncate(read_bytes[0] >> bit_shift)); } else b: { const i: u1 = @intFromBool(endian == .Big); - const head = @truncate(uN, read_bytes[i] >> bit_shift); - const tail_shift = @intCast(Log2N, @as(u4, 8) - bit_shift); - const tail = @truncate(uN, read_bytes[1 - i]); + const head = @as(uN, @truncate(read_bytes[i] >> bit_shift)); + const tail_shift = @as(Log2N, @intCast(@as(u4, 8) - bit_shift)); + const tail = @as(uN, @truncate(read_bytes[1 - i])); break :b (tail << tail_shift) | head; }; switch (signedness) { - .signed => return @intCast(T, (@bitCast(iN, value) << pad) >> pad), - .unsigned => return @intCast(T, (@bitCast(uN, value) << pad) >> pad), + .signed => return @as(T, @intCast((@as(iN, @bitCast(value)) << pad) >> pad)), + .unsigned => return @as(T, @intCast((@as(uN, @bitCast(value)) << pad) >> pad)), } } @@ -1398,13 +1398,13 @@ pub fn readVarPackedInt( .Little => { int = read_bytes[0] >> bit_shift; for (read_bytes[1..], 0..) |elem, i| { - int |= (@as(uN, elem) << @intCast(Log2N, (8 * (i + 1) - bit_shift))); + int |= (@as(uN, elem) << @as(Log2N, @intCast((8 * (i + 1) - bit_shift)))); } }, } switch (signedness) { - .signed => return @intCast(T, (@bitCast(iN, int) << pad) >> pad), - .unsigned => return @intCast(T, (@bitCast(uN, int) << pad) >> pad), + .signed => return @as(T, @intCast((@as(iN, @bitCast(int)) << pad) >> pad)), + .unsigned => return @as(T, @intCast((@as(uN, @bitCast(int)) << pad) >> pad)), } } @@ -1414,7 +1414,7 @@ pub fn readVarPackedInt( /// Assumes the endianness of memory is native. This means the function can /// simply pointer cast memory. pub fn readIntNative(comptime T: type, bytes: *const [@divExact(@typeInfo(T).Int.bits, 8)]u8) T { - return @ptrCast(*align(1) const T, bytes).*; + return @as(*align(1) const T, @ptrCast(bytes)).*; } /// Reads an integer from memory with bit count specified by T. @@ -1480,10 +1480,10 @@ fn readPackedIntLittle(comptime T: type, bytes: []const u8, bit_offset: usize) T const Log2N = std.math.Log2Int(T); const bit_count = @as(usize, @bitSizeOf(T)); - const bit_shift = @intCast(u3, bit_offset % 8); + const bit_shift = @as(u3, @intCast(bit_offset % 8)); const load_size = (bit_count + 7) / 8; - const load_tail_bits = @intCast(u3, (load_size * 8) - bit_count); + const load_tail_bits = @as(u3, @intCast((load_size * 8) - bit_count)); const LoadInt = std.meta.Int(.unsigned, load_size * 8); if (bit_count == 0) @@ -1492,13 +1492,13 @@ fn readPackedIntLittle(comptime T: type, bytes: []const u8, bit_offset: usize) T // Read by loading a LoadInt, and then follow it up with a 1-byte read // of the tail if bit_offset pushed us over a byte boundary. const read_bytes = bytes[bit_offset / 8 ..]; - const val = @truncate(uN, readIntLittle(LoadInt, read_bytes[0..load_size]) >> bit_shift); + const val = @as(uN, @truncate(readIntLittle(LoadInt, read_bytes[0..load_size]) >> bit_shift)); if (bit_shift > load_tail_bits) { - const tail_bits = @intCast(Log2N, bit_shift - load_tail_bits); + const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits)); const tail_byte = read_bytes[load_size]; - const tail_truncated = if (bit_count < 8) @truncate(uN, tail_byte) else @as(uN, tail_byte); - return @bitCast(T, val | (tail_truncated << (@truncate(Log2N, bit_count) -% tail_bits))); - } else return @bitCast(T, val); + const tail_truncated = if (bit_count < 8) @as(uN, @truncate(tail_byte)) else @as(uN, tail_byte); + return @as(T, @bitCast(val | (tail_truncated << (@as(Log2N, @truncate(bit_count)) -% tail_bits)))); + } else return @as(T, @bitCast(val)); } fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T { @@ -1506,11 +1506,11 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T { const Log2N = std.math.Log2Int(T); const bit_count = @as(usize, @bitSizeOf(T)); - const bit_shift = @intCast(u3, bit_offset % 8); + const bit_shift = @as(u3, @intCast(bit_offset % 8)); const byte_count = (@as(usize, bit_shift) + bit_count + 7) / 8; const load_size = (bit_count + 7) / 8; - const load_tail_bits = @intCast(u3, (load_size * 8) - bit_count); + const load_tail_bits = @as(u3, @intCast((load_size * 8) - bit_count)); const LoadInt = std.meta.Int(.unsigned, load_size * 8); if (bit_count == 0) @@ -1520,12 +1520,12 @@ fn readPackedIntBig(comptime T: type, bytes: []const u8, bit_offset: usize) T { // of the tail if bit_offset pushed us over a byte boundary. const end = bytes.len - (bit_offset / 8); const read_bytes = bytes[(end - byte_count)..end]; - const val = @truncate(uN, readIntBig(LoadInt, bytes[(end - load_size)..end][0..load_size]) >> bit_shift); + const val = @as(uN, @truncate(readIntBig(LoadInt, bytes[(end - load_size)..end][0..load_size]) >> bit_shift)); if (bit_shift > load_tail_bits) { - const tail_bits = @intCast(Log2N, bit_shift - load_tail_bits); - const tail_byte = if (bit_count < 8) @truncate(uN, read_bytes[0]) else @as(uN, read_bytes[0]); - return @bitCast(T, val | (tail_byte << (@truncate(Log2N, bit_count) -% tail_bits))); - } else return @bitCast(T, val); + const tail_bits = @as(Log2N, @intCast(bit_shift - load_tail_bits)); + const tail_byte = if (bit_count < 8) @as(uN, @truncate(read_bytes[0])) else @as(uN, read_bytes[0]); + return @as(T, @bitCast(val | (tail_byte << (@as(Log2N, @truncate(bit_count)) -% tail_bits)))); + } else return @as(T, @bitCast(val)); } pub const readPackedIntNative = switch (native_endian) { @@ -1605,7 +1605,7 @@ test "readIntBig and readIntLittle" { /// This function stores in native endian, which means it is implemented as a simple /// memory store. pub fn writeIntNative(comptime T: type, buf: *[(@typeInfo(T).Int.bits + 7) / 8]u8, value: T) void { - @ptrCast(*align(1) T, buf).* = value; + @as(*align(1) T, @ptrCast(buf)).* = value; } /// Writes an integer to memory, storing it in twos-complement. @@ -1642,10 +1642,10 @@ fn writePackedIntLittle(comptime T: type, bytes: []u8, bit_offset: usize, value: const Log2N = std.math.Log2Int(T); const bit_count = @as(usize, @bitSizeOf(T)); - const bit_shift = @intCast(u3, bit_offset % 8); + const bit_shift = @as(u3, @intCast(bit_offset % 8)); const store_size = (@bitSizeOf(T) + 7) / 8; - const store_tail_bits = @intCast(u3, (store_size * 8) - bit_count); + const store_tail_bits = @as(u3, @intCast((store_size * 8) - bit_count)); const StoreInt = std.meta.Int(.unsigned, store_size * 8); if (bit_count == 0) @@ -1656,11 +1656,11 @@ fn writePackedIntLittle(comptime T: type, bytes: []u8, bit_offset: usize, value: const write_bytes = bytes[bit_offset / 8 ..]; const head = write_bytes[0] & ((@as(u8, 1) << bit_shift) - 1); - var write_value = (@as(StoreInt, @bitCast(uN, value)) << bit_shift) | @intCast(StoreInt, head); + var write_value = (@as(StoreInt, @as(uN, @bitCast(value))) << bit_shift) | @as(StoreInt, @intCast(head)); if (bit_shift > store_tail_bits) { - const tail_len = @intCast(Log2N, bit_shift - store_tail_bits); - write_bytes[store_size] &= ~((@as(u8, 1) << @intCast(u3, tail_len)) - 1); - write_bytes[store_size] |= @intCast(u8, (@bitCast(uN, value) >> (@truncate(Log2N, bit_count) -% tail_len))); + const tail_len = @as(Log2N, @intCast(bit_shift - store_tail_bits)); + write_bytes[store_size] &= ~((@as(u8, 1) << @as(u3, @intCast(tail_len))) - 1); + write_bytes[store_size] |= @as(u8, @intCast((@as(uN, @bitCast(value)) >> (@as(Log2N, @truncate(bit_count)) -% tail_len)))); } else if (bit_shift < store_tail_bits) { const tail_len = store_tail_bits - bit_shift; const tail = write_bytes[store_size - 1] & (@as(u8, 0xfe) << (7 - tail_len)); @@ -1675,11 +1675,11 @@ fn writePackedIntBig(comptime T: type, bytes: []u8, bit_offset: usize, value: T) const Log2N = std.math.Log2Int(T); const bit_count = @as(usize, @bitSizeOf(T)); - const bit_shift = @intCast(u3, bit_offset % 8); + const bit_shift = @as(u3, @intCast(bit_offset % 8)); const byte_count = (bit_shift + bit_count + 7) / 8; const store_size = (@bitSizeOf(T) + 7) / 8; - const store_tail_bits = @intCast(u3, (store_size * 8) - bit_count); + const store_tail_bits = @as(u3, @intCast((store_size * 8) - bit_count)); const StoreInt = std.meta.Int(.unsigned, store_size * 8); if (bit_count == 0) @@ -1691,11 +1691,11 @@ fn writePackedIntBig(comptime T: type, bytes: []u8, bit_offset: usize, value: T) const write_bytes = bytes[(end - byte_count)..end]; const head = write_bytes[byte_count - 1] & ((@as(u8, 1) << bit_shift) - 1); - var write_value = (@as(StoreInt, @bitCast(uN, value)) << bit_shift) | @intCast(StoreInt, head); + var write_value = (@as(StoreInt, @as(uN, @bitCast(value))) << bit_shift) | @as(StoreInt, @intCast(head)); if (bit_shift > store_tail_bits) { - const tail_len = @intCast(Log2N, bit_shift - store_tail_bits); - write_bytes[0] &= ~((@as(u8, 1) << @intCast(u3, tail_len)) - 1); - write_bytes[0] |= @intCast(u8, (@bitCast(uN, value) >> (@truncate(Log2N, bit_count) -% tail_len))); + const tail_len = @as(Log2N, @intCast(bit_shift - store_tail_bits)); + write_bytes[0] &= ~((@as(u8, 1) << @as(u3, @intCast(tail_len))) - 1); + write_bytes[0] |= @as(u8, @intCast((@as(uN, @bitCast(value)) >> (@as(Log2N, @truncate(bit_count)) -% tail_len)))); } else if (bit_shift < store_tail_bits) { const tail_len = store_tail_bits - bit_shift; const tail = write_bytes[0] & (@as(u8, 0xfe) << (7 - tail_len)); @@ -1744,14 +1744,14 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void { return @memset(buffer, 0); } else if (@typeInfo(T).Int.bits == 8) { @memset(buffer, 0); - buffer[0] = @bitCast(u8, value); + buffer[0] = @as(u8, @bitCast(value)); return; } // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits); - var bits = @bitCast(uint, value); + var bits = @as(uint, @bitCast(value)); for (buffer) |*b| { - b.* = @truncate(u8, bits); + b.* = @as(u8, @truncate(bits)); bits >>= 8; } } @@ -1768,17 +1768,17 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void { return @memset(buffer, 0); } else if (@typeInfo(T).Int.bits == 8) { @memset(buffer, 0); - buffer[buffer.len - 1] = @bitCast(u8, value); + buffer[buffer.len - 1] = @as(u8, @bitCast(value)); return; } // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits); - var bits = @bitCast(uint, value); + var bits = @as(uint, @bitCast(value)); var index: usize = buffer.len; while (index != 0) { index -= 1; - buffer[index] = @truncate(u8, bits); + buffer[index] = @as(u8, @truncate(bits)); bits >>= 8; } } @@ -1822,7 +1822,7 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value const uN = std.meta.Int(.unsigned, @bitSizeOf(T)); const Log2N = std.math.Log2Int(T); - const bit_shift = @intCast(u3, bit_offset % 8); + const bit_shift = @as(u3, @intCast(bit_offset % 8)); const write_size = (bit_count + bit_shift + 7) / 8; const lowest_byte = switch (endian) { .Big => bytes.len - (bit_offset / 8) - write_size, @@ -1833,8 +1833,8 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value if (write_size == 1) { // Single byte writes are handled specially, since we need to mask bits // on both ends of the byte. - const mask = (@as(u8, 0xff) >> @intCast(u3, 8 - bit_count)); - const new_bits = @intCast(u8, @bitCast(uN, value) & mask) << bit_shift; + const mask = (@as(u8, 0xff) >> @as(u3, @intCast(8 - bit_count))); + const new_bits = @as(u8, @intCast(@as(uN, @bitCast(value)) & mask)) << bit_shift; write_bytes[0] = (write_bytes[0] & ~(mask << bit_shift)) | new_bits; return; } @@ -1843,31 +1843,31 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value // Iterate bytes forward for Little-endian, backward for Big-endian const delta: i2 = if (endian == .Big) -1 else 1; - const start = if (endian == .Big) @intCast(isize, write_bytes.len - 1) else 0; + const start = if (endian == .Big) @as(isize, @intCast(write_bytes.len - 1)) else 0; var i: isize = start; // isize for signed index arithmetic // Write first byte, using a mask to protects bits preceding bit_offset const head_mask = @as(u8, 0xff) >> bit_shift; - write_bytes[@intCast(usize, i)] &= ~(head_mask << bit_shift); - write_bytes[@intCast(usize, i)] |= @intCast(u8, @bitCast(uN, remaining) & head_mask) << bit_shift; - remaining >>= @intCast(Log2N, @as(u4, 8) - bit_shift); + write_bytes[@as(usize, @intCast(i))] &= ~(head_mask << bit_shift); + write_bytes[@as(usize, @intCast(i))] |= @as(u8, @intCast(@as(uN, @bitCast(remaining)) & head_mask)) << bit_shift; + remaining >>= @as(Log2N, @intCast(@as(u4, 8) - bit_shift)); i += delta; // Write bytes[1..bytes.len - 1] if (@bitSizeOf(T) > 8) { - const loop_end = start + delta * (@intCast(isize, write_size) - 1); + const loop_end = start + delta * (@as(isize, @intCast(write_size)) - 1); while (i != loop_end) : (i += delta) { - write_bytes[@intCast(usize, i)] = @truncate(u8, @bitCast(uN, remaining)); + write_bytes[@as(usize, @intCast(i))] = @as(u8, @truncate(@as(uN, @bitCast(remaining)))); remaining >>= 8; } } // Write last byte, using a mask to protect bits following bit_offset + bit_count - const following_bits = -%@truncate(u3, bit_shift + bit_count); + const following_bits = -%@as(u3, @truncate(bit_shift + bit_count)); const tail_mask = (@as(u8, 0xff) << following_bits) >> following_bits; - write_bytes[@intCast(usize, i)] &= ~tail_mask; - write_bytes[@intCast(usize, i)] |= @intCast(u8, @bitCast(uN, remaining) & tail_mask); + write_bytes[@as(usize, @intCast(i))] &= ~tail_mask; + write_bytes[@as(usize, @intCast(i))] |= @as(u8, @intCast(@as(uN, @bitCast(remaining)) & tail_mask)); } test "writeIntBig and writeIntLittle" { @@ -3799,15 +3799,14 @@ pub fn alignPointerOffset(ptr: anytype, align_to: usize) ?usize { /// type. pub fn alignPointer(ptr: anytype, align_to: usize) ?@TypeOf(ptr) { const adjust_off = alignPointerOffset(ptr, align_to) orelse return null; - const T = @TypeOf(ptr); // Avoid the use of ptrFromInt to avoid losing the pointer provenance info. - return @alignCast(@typeInfo(T).Pointer.alignment, ptr + adjust_off); + return @alignCast(ptr + adjust_off); } test "alignPointer" { const S = struct { fn checkAlign(comptime T: type, base: usize, align_to: usize, expected: usize) !void { - var ptr = @ptrFromInt(T, base); + var ptr = @as(T, @ptrFromInt(base)); var aligned = alignPointer(ptr, align_to); try testing.expectEqual(expected, @intFromPtr(aligned)); } @@ -3854,9 +3853,7 @@ fn AsBytesReturnType(comptime P: type) type { /// Given a pointer to a single item, returns a slice of the underlying bytes, preserving pointer attributes. pub fn asBytes(ptr: anytype) AsBytesReturnType(@TypeOf(ptr)) { - const P = @TypeOf(ptr); - const T = AsBytesReturnType(P); - return @ptrCast(T, @alignCast(meta.alignment(T), ptr)); + return @ptrCast(@alignCast(ptr)); } test "asBytes" { @@ -3902,7 +3899,7 @@ test "asBytes" { test "asBytes preserves pointer attributes" { const inArr: u32 align(16) = 0xDEADBEEF; - const inPtr = @ptrCast(*align(16) const volatile u32, &inArr); + const inPtr = @as(*align(16) const volatile u32, @ptrCast(&inArr)); const outSlice = asBytes(inPtr); const in = @typeInfo(@TypeOf(inPtr)).Pointer; @@ -3948,7 +3945,7 @@ fn BytesAsValueReturnType(comptime T: type, comptime B: type) type { /// Given a pointer to an array of bytes, returns a pointer to a value of the specified type /// backed by those bytes, preserving pointer attributes. pub fn bytesAsValue(comptime T: type, bytes: anytype) BytesAsValueReturnType(T, @TypeOf(bytes)) { - return @ptrCast(BytesAsValueReturnType(T, @TypeOf(bytes)), bytes); + return @as(BytesAsValueReturnType(T, @TypeOf(bytes)), @ptrCast(bytes)); } test "bytesAsValue" { @@ -3993,7 +3990,7 @@ test "bytesAsValue" { test "bytesAsValue preserves pointer attributes" { const inArr align(16) = [4]u8{ 0xDE, 0xAD, 0xBE, 0xEF }; - const inSlice = @ptrCast(*align(16) const volatile [4]u8, &inArr)[0..]; + const inSlice = @as(*align(16) const volatile [4]u8, @ptrCast(&inArr))[0..]; const outPtr = bytesAsValue(u32, inSlice); const in = @typeInfo(@TypeOf(inSlice)).Pointer; @@ -4043,7 +4040,7 @@ pub fn bytesAsSlice(comptime T: type, bytes: anytype) BytesAsSliceReturnType(T, const cast_target = CopyPtrAttrs(@TypeOf(bytes), .Many, T); - return @ptrCast(cast_target, bytes)[0..@divExact(bytes.len, @sizeOf(T))]; + return @as(cast_target, @ptrCast(bytes))[0..@divExact(bytes.len, @sizeOf(T))]; } test "bytesAsSlice" { @@ -4101,7 +4098,7 @@ test "bytesAsSlice with specified alignment" { test "bytesAsSlice preserves pointer attributes" { const inArr align(16) = [4]u8{ 0xDE, 0xAD, 0xBE, 0xEF }; - const inSlice = @ptrCast(*align(16) const volatile [4]u8, &inArr)[0..]; + const inSlice = @as(*align(16) const volatile [4]u8, @ptrCast(&inArr))[0..]; const outSlice = bytesAsSlice(u16, inSlice); const in = @typeInfo(@TypeOf(inSlice)).Pointer; @@ -4133,7 +4130,7 @@ pub fn sliceAsBytes(slice: anytype) SliceAsBytesReturnType(@TypeOf(slice)) { const cast_target = CopyPtrAttrs(Slice, .Many, u8); - return @ptrCast(cast_target, slice)[0 .. slice.len * @sizeOf(meta.Elem(Slice))]; + return @as(cast_target, @ptrCast(slice))[0 .. slice.len * @sizeOf(meta.Elem(Slice))]; } test "sliceAsBytes" { @@ -4197,7 +4194,7 @@ test "sliceAsBytes and bytesAsSlice back" { test "sliceAsBytes preserves pointer attributes" { const inArr align(16) = [2]u16{ 0xDEAD, 0xBEEF }; - const inSlice = @ptrCast(*align(16) const volatile [2]u16, &inArr)[0..]; + const inSlice = @as(*align(16) const volatile [2]u16, @ptrCast(&inArr))[0..]; const outSlice = sliceAsBytes(inSlice); const in = @typeInfo(@TypeOf(inSlice)).Pointer; @@ -4218,7 +4215,7 @@ pub fn alignForward(comptime T: type, addr: T, alignment: T) T { } pub fn alignForwardLog2(addr: usize, log2_alignment: u8) usize { - const alignment = @as(usize, 1) << @intCast(math.Log2Int(usize), log2_alignment); + const alignment = @as(usize, 1) << @as(math.Log2Int(usize), @intCast(log2_alignment)); return alignForward(usize, addr, alignment); } @@ -4282,7 +4279,7 @@ pub fn doNotOptimizeAway(val: anytype) void { /// .stage2_c doesn't support asm blocks yet, so use volatile stores instead var deopt_target: if (builtin.zig_backend == .stage2_c) u8 else void = undefined; fn doNotOptimizeAwayC(ptr: anytype) void { - const dest = @ptrCast(*volatile u8, &deopt_target); + const dest = @as(*volatile u8, @ptrCast(&deopt_target)); for (asBytes(ptr)) |b| { dest.* = b; } @@ -4433,7 +4430,7 @@ pub fn alignInBytes(bytes: []u8, comptime new_alignment: usize) ?[]align(new_ali error.Overflow => return null, }; const alignment_offset = begin_address_aligned - begin_address; - return @alignCast(new_alignment, bytes[alignment_offset .. alignment_offset + new_length]); + return @alignCast(bytes[alignment_offset .. alignment_offset + new_length]); } /// Returns the largest sub-slice within the given slice that conforms to the new alignment, @@ -4445,7 +4442,7 @@ pub fn alignInSlice(slice: anytype, comptime new_alignment: usize) ?AlignedSlice const Element = @TypeOf(slice[0]); const slice_length_bytes = aligned_bytes.len - (aligned_bytes.len % @sizeOf(Element)); const aligned_slice = bytesAsSlice(Element, aligned_bytes[0..slice_length_bytes]); - return @alignCast(new_alignment, aligned_slice); + return @alignCast(aligned_slice); } test "read/write(Var)PackedInt" { @@ -4490,8 +4487,8 @@ test "read/write(Var)PackedInt" { for ([_]PackedType{ ~@as(PackedType, 0), // all ones: -1 iN / maxInt uN @as(PackedType, 0), // all zeros: 0 iN / 0 uN - @bitCast(PackedType, @as(iPackedType, math.maxInt(iPackedType))), // maxInt iN - @bitCast(PackedType, @as(iPackedType, math.minInt(iPackedType))), // maxInt iN + @as(PackedType, @bitCast(@as(iPackedType, math.maxInt(iPackedType)))), // maxInt iN + @as(PackedType, @bitCast(@as(iPackedType, math.minInt(iPackedType)))), // maxInt iN random.int(PackedType), // random random.int(PackedType), // random }) |write_value| { @@ -4502,11 +4499,11 @@ test "read/write(Var)PackedInt" { // Read const read_value1 = readPackedInt(PackedType, asBytes(&value), offset, native_endian); - try expect(read_value1 == @bitCast(PackedType, @truncate(uPackedType, value >> @intCast(Log2T, offset)))); + try expect(read_value1 == @as(PackedType, @bitCast(@as(uPackedType, @truncate(value >> @as(Log2T, @intCast(offset))))))); // Write writePackedInt(PackedType, asBytes(&value), offset, write_value, native_endian); - try expect(write_value == @bitCast(PackedType, @truncate(uPackedType, value >> @intCast(Log2T, offset)))); + try expect(write_value == @as(PackedType, @bitCast(@as(uPackedType, @truncate(value >> @as(Log2T, @intCast(offset))))))); // Read again const read_value2 = readPackedInt(PackedType, asBytes(&value), offset, native_endian); @@ -4515,9 +4512,9 @@ test "read/write(Var)PackedInt" { // Verify bits outside of the target integer are unmodified const diff_bits = init_value ^ value; if (offset != offset_at_end) - try expect(diff_bits >> @intCast(Log2T, offset + @bitSizeOf(PackedType)) == 0); + try expect(diff_bits >> @as(Log2T, @intCast(offset + @bitSizeOf(PackedType))) == 0); if (offset != 0) - try expect(diff_bits << @intCast(Log2T, @bitSizeOf(BackingType) - offset) == 0); + try expect(diff_bits << @as(Log2T, @intCast(@bitSizeOf(BackingType) - offset)) == 0); } { // Fixed-size Read/Write (Foreign-endian) @@ -4527,11 +4524,11 @@ test "read/write(Var)PackedInt" { // Read const read_value1 = readPackedInt(PackedType, asBytes(&value), offset, foreign_endian); - try expect(read_value1 == @bitCast(PackedType, @truncate(uPackedType, @byteSwap(value) >> @intCast(Log2T, offset)))); + try expect(read_value1 == @as(PackedType, @bitCast(@as(uPackedType, @truncate(@byteSwap(value) >> @as(Log2T, @intCast(offset))))))); // Write writePackedInt(PackedType, asBytes(&value), offset, write_value, foreign_endian); - try expect(write_value == @bitCast(PackedType, @truncate(uPackedType, @byteSwap(value) >> @intCast(Log2T, offset)))); + try expect(write_value == @as(PackedType, @bitCast(@as(uPackedType, @truncate(@byteSwap(value) >> @as(Log2T, @intCast(offset))))))); // Read again const read_value2 = readPackedInt(PackedType, asBytes(&value), offset, foreign_endian); @@ -4540,9 +4537,9 @@ test "read/write(Var)PackedInt" { // Verify bits outside of the target integer are unmodified const diff_bits = init_value ^ @byteSwap(value); if (offset != offset_at_end) - try expect(diff_bits >> @intCast(Log2T, offset + @bitSizeOf(PackedType)) == 0); + try expect(diff_bits >> @as(Log2T, @intCast(offset + @bitSizeOf(PackedType))) == 0); if (offset != 0) - try expect(diff_bits << @intCast(Log2T, @bitSizeOf(BackingType) - offset) == 0); + try expect(diff_bits << @as(Log2T, @intCast(@bitSizeOf(BackingType) - offset)) == 0); } const signedness = @typeInfo(PackedType).Int.signedness; @@ -4559,11 +4556,11 @@ test "read/write(Var)PackedInt" { // Read const read_value1 = readVarPackedInt(U, asBytes(&value), offset, @bitSizeOf(PackedType), native_endian, signedness); - try expect(read_value1 == @bitCast(PackedType, @truncate(uPackedType, value >> @intCast(Log2T, offset)))); + try expect(read_value1 == @as(PackedType, @bitCast(@as(uPackedType, @truncate(value >> @as(Log2T, @intCast(offset))))))); // Write writeVarPackedInt(asBytes(&value), offset, @bitSizeOf(PackedType), @as(U, write_value), native_endian); - try expect(write_value == @bitCast(PackedType, @truncate(uPackedType, value >> @intCast(Log2T, offset)))); + try expect(write_value == @as(PackedType, @bitCast(@as(uPackedType, @truncate(value >> @as(Log2T, @intCast(offset))))))); // Read again const read_value2 = readVarPackedInt(U, asBytes(&value), offset, @bitSizeOf(PackedType), native_endian, signedness); @@ -4572,9 +4569,9 @@ test "read/write(Var)PackedInt" { // Verify bits outside of the target integer are unmodified const diff_bits = init_value ^ value; if (offset != offset_at_end) - try expect(diff_bits >> @intCast(Log2T, offset + @bitSizeOf(PackedType)) == 0); + try expect(diff_bits >> @as(Log2T, @intCast(offset + @bitSizeOf(PackedType))) == 0); if (offset != 0) - try expect(diff_bits << @intCast(Log2T, @bitSizeOf(BackingType) - offset) == 0); + try expect(diff_bits << @as(Log2T, @intCast(@bitSizeOf(BackingType) - offset)) == 0); } { // Variable-size Read/Write (Foreign-endian) @@ -4587,11 +4584,11 @@ test "read/write(Var)PackedInt" { // Read const read_value1 = readVarPackedInt(U, asBytes(&value), offset, @bitSizeOf(PackedType), foreign_endian, signedness); - try expect(read_value1 == @bitCast(PackedType, @truncate(uPackedType, @byteSwap(value) >> @intCast(Log2T, offset)))); + try expect(read_value1 == @as(PackedType, @bitCast(@as(uPackedType, @truncate(@byteSwap(value) >> @as(Log2T, @intCast(offset))))))); // Write writeVarPackedInt(asBytes(&value), offset, @bitSizeOf(PackedType), @as(U, write_value), foreign_endian); - try expect(write_value == @bitCast(PackedType, @truncate(uPackedType, @byteSwap(value) >> @intCast(Log2T, offset)))); + try expect(write_value == @as(PackedType, @bitCast(@as(uPackedType, @truncate(@byteSwap(value) >> @as(Log2T, @intCast(offset))))))); // Read again const read_value2 = readVarPackedInt(U, asBytes(&value), offset, @bitSizeOf(PackedType), foreign_endian, signedness); @@ -4600,9 +4597,9 @@ test "read/write(Var)PackedInt" { // Verify bits outside of the target integer are unmodified const diff_bits = init_value ^ @byteSwap(value); if (offset != offset_at_end) - try expect(diff_bits >> @intCast(Log2T, offset + @bitSizeOf(PackedType)) == 0); + try expect(diff_bits >> @as(Log2T, @intCast(offset + @bitSizeOf(PackedType))) == 0); if (offset != 0) - try expect(diff_bits << @intCast(Log2T, @bitSizeOf(BackingType) - offset) == 0); + try expect(diff_bits << @as(Log2T, @intCast(@bitSizeOf(BackingType) - offset)) == 0); } } } |
