Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
14bda41
llvm backend: remove canElideLoad mechanism
andrewrk Sep 3, 2025
426af68
compiler: require comptime vector indexes
andrewrk Sep 3, 2025
772793c
Sema: fix accessing ptr field of double array pointer with sentinel
andrewrk Sep 3, 2025
09e4fc4
std.zon.parse: fix not initializing array sentinel
andrewrk Sep 4, 2025
d00aee0
x86 codegen: handle spilled tuples
andrewrk Sep 4, 2025
3bd62e1
Sema: fix source location of "declared here" note
andrewrk Sep 4, 2025
354c178
frontend: replace field_val and field_val_named
andrewrk Sep 5, 2025
95439c9
std.Progress: avoid problematic catch syntax
andrewrk Sep 3, 2025
9afa683
frontend: replace elem_val_node with elem_ptr_load
andrewrk Sep 5, 2025
4fef90f
Sema: more conservative elem_ptr_load implementation
andrewrk Sep 5, 2025
9b74651
Sema: fix YAGNI violation
andrewrk Sep 5, 2025
5ec0a7d
coerce vectors to arrays rather than inline for
andrewrk Sep 5, 2025
f12c4f8
aarch64: implement `ptr_slice_*_ptr`
jacobly0 Sep 6, 2025
f0fe55a
frontend: fix too strict assertion
andrewrk Sep 6, 2025
e5adfd8
translate-c: remove cases associated with runtime vector indexing
andrewrk Sep 6, 2025
2fdf0e2
aarch64: enable fixed behavior
jacobly0 Sep 6, 2025
7b8a798
frontend: additionally handle C pointers in ptrOptPayload
andrewrk Sep 6, 2025
aacff8c
add compile error coverage for dependency loop
andrewrk Sep 6, 2025
c0bbddb
Sema: avoid ptr_add/ptr_sub instructions void elem type
andrewrk Sep 9, 2025
c369def
disable spirv64-vulkan coverage
andrewrk Sep 9, 2025
e1a7506
disable wasm backend coverage
andrewrk Sep 9, 2025
0681bf0
frontend: packed struct field ptr no longer finds byte borders
andrewrk Sep 10, 2025
cbbb67c
x86_64: fix safety crashes in `storeRegs`
jacobly0 Sep 10, 2025
7ffe068
delete failing test case
andrewrk Sep 10, 2025
725dec6
Sema: add missed logic to checkPtrAttributes
andrewrk Sep 10, 2025
d7d5049
langref: don't assume too much about pointer to packed struct field
andrewrk Sep 10, 2025
2f9d8d5
Zcu: fix analysis of type of decl with inferred type
mlugg Sep 10, 2025
fcc7e37
Revert "delete failing test case"
mlugg Sep 10, 2025
baaf715
cases: update for new error
mlugg Sep 10, 2025
5d8c1fb
frontend: another packedStructFieldPtrInfo fix
andrewrk Sep 10, 2025
2ba03e9
disable failing stage2_aarch64 behavior tests
andrewrk Sep 10, 2025
60cdaca
x86_64: rewrite vector element pointer access
jacobly0 Sep 11, 2025
5144f10
aarch64: fix behavior failures
jacobly0 Sep 12, 2025
f81a721
standalone: fix misaligned stack crash
jacobly0 Sep 12, 2025
20925f2
Revert "frontend: another packedStructFieldPtrInfo fix"
mlugg Sep 18, 2025
0e16d93
fix rebase error
mlugg Sep 18, 2025
ed7ff0b
allow some test cases to regress
andrewrk Sep 20, 2025
500afbf
add behavior test: resist alias of explicit copy...
andrewrk Sep 21, 2025
1c9ac9d
add behavior test: avoid unused field function body compile error
andrewrk Sep 21, 2025
633162e
add behavior test: comptime C pointer to optional pointer
andrewrk Sep 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/langref/test_overaligned_packed_struct.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const S = packed struct {
test "overaligned pointer to packed struct" {
var foo: S align(4) = .{ .a = 1, .b = 2 };
const ptr: *align(4) S = &foo;
const ptr_to_b: *u32 = &ptr.b;
const ptr_to_b = &ptr.b;
try expect(ptr_to_b.* == 2);
}

Expand Down
36 changes: 21 additions & 15 deletions lib/std/Io/Writer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1370,19 +1370,12 @@ pub fn printValue(
},
.array => {
if (!is_any) @compileError("cannot format array without a specifier (i.e. {s} or {any})");
if (max_depth == 0) return w.writeAll("{ ... }");
try w.writeAll("{ ");
for (value, 0..) |elem, i| {
try w.printValue(fmt, options, elem, max_depth - 1);
if (i < value.len - 1) {
try w.writeAll(", ");
}
}
try w.writeAll(" }");
return printArray(w, fmt, options, &value, max_depth);
},
.vector => {
.vector => |vector| {
if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
return printVector(w, fmt, options, value, max_depth);
const array: [vector.len]vector.child = value;
return printArray(w, fmt, options, &array, max_depth);
},
.@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"),
.type => {
Expand Down Expand Up @@ -1436,12 +1429,25 @@ pub fn printVector(
value: anytype,
max_depth: usize,
) Error!void {
const len = @typeInfo(@TypeOf(value)).vector.len;
const vector = @typeInfo(@TypeOf(value)).vector;
const array: [vector.len]vector.child = value;
return printArray(w, fmt, options, &array, max_depth);
}

pub fn printArray(
w: *Writer,
comptime fmt: []const u8,
options: std.fmt.Options,
ptr_to_array: anytype,
max_depth: usize,
) Error!void {
if (max_depth == 0) return w.writeAll("{ ... }");
try w.writeAll("{ ");
inline for (0..len) |i| {
try w.printValue(fmt, options, value[i], max_depth - 1);
if (i < len - 1) try w.writeAll(", ");
for (ptr_to_array, 0..) |elem, i| {
try w.printValue(fmt, options, elem, max_depth - 1);
if (i < ptr_to_array.len - 1) {
try w.writeAll(", ");
}
}
try w.writeAll(" }");
}
Expand Down
20 changes: 15 additions & 5 deletions lib/std/Progress.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,9 @@ fn computeRedraw(serialized_buffer: *Serialized.Buffer) struct { []u8, usize } {
i += progress_pulsing.len;
} else {
const percent = completed_items * 100 / estimated_total;
i += (std.fmt.bufPrint(buf[i..], @"progress_normal {d}", .{percent}) catch &.{}).len;
if (std.fmt.bufPrint(buf[i..], @"progress_normal {d}", .{percent})) |b| {
i += b.len;
} else |_| {}
}
},
.success => {
Expand All @@ -1265,7 +1267,9 @@ fn computeRedraw(serialized_buffer: *Serialized.Buffer) struct { []u8, usize } {
i += progress_pulsing_error.len;
} else {
const percent = completed_items * 100 / estimated_total;
i += (std.fmt.bufPrint(buf[i..], @"progress_error {d}", .{percent}) catch &.{}).len;
if (std.fmt.bufPrint(buf[i..], @"progress_error {d}", .{percent})) |b| {
i += b.len;
} else |_| {}
}
},
}
Expand Down Expand Up @@ -1364,12 +1368,18 @@ fn computeNode(
if (!is_empty_root) {
if (name.len != 0 or estimated_total > 0) {
if (estimated_total > 0) {
i += (std.fmt.bufPrint(buf[i..], "[{d}/{d}] ", .{ completed_items, estimated_total }) catch &.{}).len;
if (std.fmt.bufPrint(buf[i..], "[{d}/{d}] ", .{ completed_items, estimated_total })) |b| {
i += b.len;
} else |_| {}
} else if (completed_items != 0) {
i += (std.fmt.bufPrint(buf[i..], "[{d}] ", .{completed_items}) catch &.{}).len;
if (std.fmt.bufPrint(buf[i..], "[{d}] ", .{completed_items})) |b| {
i += b.len;
} else |_| {}
}
if (name.len != 0) {
i += (std.fmt.bufPrint(buf[i..], "{s}", .{name}) catch &.{}).len;
if (std.fmt.bufPrint(buf[i..], "{s}", .{name})) |b| {
i += b.len;
} else |_| {}
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/std/Target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1187,7 +1187,7 @@ pub const Cpu = struct {
pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize)));
pub const ShiftInt = std.math.Log2Int(usize);

pub const empty = Set{ .ints = [1]usize{0} ** usize_count };
pub const empty: Set = .{ .ints = @splat(0) };

pub fn isEmpty(set: Set) bool {
return for (set.ints) |x| {
Expand Down
5 changes: 5 additions & 0 deletions lib/std/Thread.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,11 @@ test "Thread.getCurrentId" {
test "thread local storage" {
if (builtin.single_threaded) return error.SkipZigTest;

if (builtin.cpu.arch == .thumbeb) {
// https://github.com/ziglang/zig/issues/24061
return error.SkipZigTest;
}
Comment on lines +1664 to +1667
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the problem with this one? (Not obvious to me why #24061 affects it.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's not #24061 then I'll open another issue to track the regression (same with the other s390x case)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever issue this was, I'm not able to reproduce it locally. Is there a CI log for this failure or something?


const thread1 = try Thread.spawn(.{}, testTls, .{});
const thread2 = try Thread.spawn(.{}, testTls, .{});
try testTls();
Expand Down
22 changes: 11 additions & 11 deletions lib/std/crypto/chacha20.zig
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type
}
}

fn hashToBytes(comptime dm: usize, out: *[64 * dm]u8, x: BlockVec) void {
for (0..dm) |d| {
fn hashToBytes(comptime dm: usize, out: *[64 * dm]u8, x: *const BlockVec) void {
inline for (0..dm) |d| {
for (0..4) |i| {
mem.writeInt(u32, out[64 * d + 16 * i + 0 ..][0..4], x[i][0 + 4 * d], .little);
mem.writeInt(u32, out[64 * d + 16 * i + 4 ..][0..4], x[i][1 + 4 * d], .little);
Expand All @@ -242,7 +242,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type
while (degree >= d and i + 64 * d <= in.len) : (i += 64 * d) {
chacha20Core(x[0..], ctx);
contextFeedback(&x, ctx);
hashToBytes(d, buf[0 .. 64 * d], x);
hashToBytes(d, buf[0 .. 64 * d], &x);

var xout = out[i..];
const xin = in[i..];
Expand All @@ -266,7 +266,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type
if (i < in.len) {
chacha20Core(x[0..], ctx);
contextFeedback(&x, ctx);
hashToBytes(1, buf[0..64], x);
hashToBytes(1, buf[0..64], &x);

var xout = out[i..];
const xin = in[i..];
Expand All @@ -284,7 +284,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type
while (degree >= d and i + 64 * d <= out.len) : (i += 64 * d) {
chacha20Core(x[0..], ctx);
contextFeedback(&x, ctx);
hashToBytes(d, out[i..][0 .. 64 * d], x);
hashToBytes(d, out[i..][0 .. 64 * d], &x);
inline for (0..d) |d_| {
if (count64) {
const next = @addWithOverflow(ctx[3][4 * d_], d);
Expand All @@ -301,7 +301,7 @@ fn ChaChaVecImpl(comptime rounds_nb: usize, comptime degree: comptime_int) type
contextFeedback(&x, ctx);

var buf: [64]u8 = undefined;
hashToBytes(1, buf[0..], x);
hashToBytes(1, buf[0..], &x);
@memcpy(out[i..], buf[0 .. out.len - i]);
}
}
Expand Down Expand Up @@ -394,7 +394,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type {
}
}

fn hashToBytes(out: *[64]u8, x: BlockVec) void {
fn hashToBytes(out: *[64]u8, x: *const BlockVec) void {
for (0..4) |i| {
mem.writeInt(u32, out[16 * i + 0 ..][0..4], x[i * 4 + 0], .little);
mem.writeInt(u32, out[16 * i + 4 ..][0..4], x[i * 4 + 1], .little);
Expand All @@ -417,7 +417,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type {
while (i + 64 <= in.len) : (i += 64) {
chacha20Core(x[0..], ctx);
contextFeedback(&x, ctx);
hashToBytes(buf[0..], x);
hashToBytes(buf[0..], &x);

var xout = out[i..];
const xin = in[i..];
Expand All @@ -438,7 +438,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type {
if (i < in.len) {
chacha20Core(x[0..], ctx);
contextFeedback(&x, ctx);
hashToBytes(buf[0..], x);
hashToBytes(buf[0..], &x);

var xout = out[i..];
const xin = in[i..];
Expand All @@ -455,7 +455,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type {
while (i + 64 <= out.len) : (i += 64) {
chacha20Core(x[0..], ctx);
contextFeedback(&x, ctx);
hashToBytes(out[i..][0..64], x);
hashToBytes(out[i..][0..64], &x);
if (count64) {
const next = @addWithOverflow(ctx[12], 1);
ctx[12] = next[0];
Expand All @@ -469,7 +469,7 @@ fn ChaChaNonVecImpl(comptime rounds_nb: usize) type {
contextFeedback(&x, ctx);

var buf: [64]u8 = undefined;
hashToBytes(buf[0..], x);
hashToBytes(buf[0..], &x);
@memcpy(out[i..], buf[0 .. out.len - i]);
}
}
Expand Down
17 changes: 8 additions & 9 deletions lib/std/json/static.zig
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ pub fn innerParse(
switch (try source.peekNextTokenType()) {
.array_begin => {
// Typical array.
return internalParseArray(T, arrayInfo.child, arrayInfo.len, allocator, source, options);
return internalParseArray(T, arrayInfo.child, allocator, source, options);
},
.string => {
if (arrayInfo.child != u8) return error.UnexpectedToken;
Expand Down Expand Up @@ -440,10 +440,11 @@ pub fn innerParse(
}
},

.vector => |vecInfo| {
.vector => |vector_info| {
switch (try source.peekNextTokenType()) {
.array_begin => {
return internalParseArray(T, vecInfo.child, vecInfo.len, allocator, source, options);
const A = [vector_info.len]vector_info.child;
return try internalParseArray(A, vector_info.child, allocator, source, options);
},
else => return error.UnexpectedToken,
}
Expand Down Expand Up @@ -519,17 +520,15 @@ pub fn innerParse(
fn internalParseArray(
comptime T: type,
comptime Child: type,
comptime len: comptime_int,
allocator: Allocator,
source: anytype,
options: ParseOptions,
) !T {
assert(.array_begin == try source.next());

var r: T = undefined;
var i: usize = 0;
while (i < len) : (i += 1) {
r[i] = try innerParse(Child, allocator, source, options);
for (&r) |*elem| {
elem.* = try innerParse(Child, allocator, source, options);
}

if (.array_end != try source.next()) return error.UnexpectedToken;
Expand Down Expand Up @@ -569,12 +568,12 @@ pub fn innerParseFromValue(
if (@round(f) != f) return error.InvalidNumber;
if (f > @as(@TypeOf(f), @floatFromInt(std.math.maxInt(T)))) return error.Overflow;
if (f < @as(@TypeOf(f), @floatFromInt(std.math.minInt(T)))) return error.Overflow;
return @as(T, @intFromFloat(f));
return @intFromFloat(f);
},
.integer => |i| {
if (i > std.math.maxInt(T)) return error.Overflow;
if (i < std.math.minInt(T)) return error.Overflow;
return @as(T, @intCast(i));
return @intCast(i);
},
.number_string, .string => |s| {
return sliceToInt(T, s);
Expand Down
8 changes: 1 addition & 7 deletions lib/std/meta.zig
Original file line number Diff line number Diff line change
Expand Up @@ -742,13 +742,7 @@ pub fn eql(a: anytype, b: @TypeOf(a)) bool {
if (!eql(e, b[i])) return false;
return true;
},
.vector => |info| {
var i: usize = 0;
while (i < info.len) : (i += 1) {
if (!eql(a[i], b[i])) return false;
}
return true;
},
.vector => return @reduce(.And, a == b),
.pointer => |info| {
return switch (info.size) {
.one, .many, .c => a == b,
Expand Down
15 changes: 4 additions & 11 deletions lib/std/testing.zig
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,9 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {
.array => |array| try expectEqualSlices(array.child, &expected, &actual),

.vector => |info| {
var i: usize = 0;
while (i < info.len) : (i += 1) {
if (!std.meta.eql(expected[i], actual[i])) {
print("index {d} incorrect. expected {any}, found {any}\n", .{
i, expected[i], actual[i],
});
return error.TestExpectedEqual;
}
}
const expect_array: [info.len]info.child = expected;
const actual_array: [info.len]info.child = actual;
try expectEqualSlices(info.child, &expect_array, &actual_array);
},

.@"struct" => |structType| {
Expand Down Expand Up @@ -828,8 +822,7 @@ fn expectEqualDeepInner(comptime T: type, expected: T, actual: T) error{TestExpe
print("Vector len not the same, expected {d}, found {d}\n", .{ info.len, @typeInfo(@TypeOf(actual)).vector.len });
return error.TestExpectedEqual;
}
var i: usize = 0;
while (i < info.len) : (i += 1) {
inline for (0..info.len) |i| {
expectEqualDeep(expected[i], actual[i]) catch |e| {
print("index {d} incorrect. expected {any}, found {any}\n", .{
i, expected[i], actual[i],
Expand Down
36 changes: 20 additions & 16 deletions lib/std/zig/AstGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2728,12 +2728,12 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
.elem_ptr,
.elem_val,
.elem_ptr_node,
.elem_val_node,
.elem_ptr_load,
.elem_val_imm,
.field_ptr,
.field_val,
.field_ptr_load,
.field_ptr_named,
.field_val_named,
.field_ptr_named_load,
.func,
.func_inferred,
.func_fancy,
Expand Down Expand Up @@ -6160,7 +6160,7 @@ fn fieldAccess(
switch (ri.rl) {
.ref, .ref_coerced_ty => return addFieldAccess(.field_ptr, gz, scope, .{ .rl = .ref }, node),
else => {
const access = try addFieldAccess(.field_val, gz, scope, .{ .rl = .none }, node);
const access = try addFieldAccess(.field_ptr_load, gz, scope, .{ .rl = .ref }, node);
return rvalue(gz, ri, access, node);
},
}
Expand Down Expand Up @@ -6210,14 +6210,14 @@ fn arrayAccess(
},
else => {
const lhs_node, const rhs_node = tree.nodeData(node).node_and_node;
const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node);
const lhs = try expr(gz, scope, .{ .rl = .ref }, lhs_node);

const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);

const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, rhs_node);
try emitDbgStmt(gz, cursor);

return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node);
return rvalue(gz, ri, try gz.addPlNode(.elem_ptr_load, node, Zir.Inst.Bin{ .lhs = lhs, .rhs = rhs }), node);
},
}
}
Expand Down Expand Up @@ -9286,17 +9286,21 @@ fn builtinCall(
return rvalue(gz, ri, result, node);
},
.field => {
if (ri.rl == .ref or ri.rl == .ref_coerced_ty) {
return gz.addPlNode(.field_ptr_named, node, Zir.Inst.FieldNamed{
.lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]),
.field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .field_name),
});
switch (ri.rl) {
.ref, .ref_coerced_ty => {
return gz.addPlNode(.field_ptr_named, node, Zir.Inst.FieldNamed{
.lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]),
.field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .field_name),
});
},
else => {
const result = try gz.addPlNode(.field_ptr_named_load, node, Zir.Inst.FieldNamed{
.lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]),
.field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .field_name),
});
return rvalue(gz, ri, result, node);
},
}
const result = try gz.addPlNode(.field_val_named, node, Zir.Inst.FieldNamed{
.lhs = try expr(gz, scope, .{ .rl = .none }, params[0]),
.field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .field_name),
});
return rvalue(gz, ri, result, node);
},
.FieldType => {
const ty_inst = try typeExpr(gz, scope, params[0]);
Expand Down
Loading
Loading