authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-06-12 13:11:56-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-06-13 17:58:37+02:00
log3deb86bafdb2f622b9099c405e0e861f70c36a45
tree95b57acfe21742cc527d37ab166aef2ea6deb810
parent783a9df0b8f159062710a94bf5ee9a54002f59ed

AstGen: make local align expression implicitly comptime

Closes #35730

3 files changed, 73 insertions(+), 2 deletions(-)

lib/std/zig/AstGen.zig+2-2
......@@ -3130,7 +3130,7 @@ fn varDecl(
31303130 }
31313131
31323132 const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node.unwrap()) |align_node|
3133 try expr(gz, scope, coerced_align_ri, align_node)
3133 try comptimeExpr(gz, scope, coerced_align_ri, align_node, .@"align")
31343134 else
31353135 .none;
31363136
......@@ -3477,7 +3477,7 @@ fn assignDestructureMaybeDecls(
34773477 const this_variable_comptime = is_comptime or (is_const and value_is_comptime);
34783478
34793479 const align_inst: Zir.Inst.Ref = if (full_var_decl.ast.align_node.unwrap()) |align_node|
3480 try expr(gz, scope, coerced_align_ri, align_node)
3480 try comptimeExpr(gz, scope, coerced_align_ri, align_node, .@"align")
34813481 else
34823482 .none;
34833483
test/behavior/align.zig+25
......@@ -616,3 +616,28 @@ test "function pointer align mask" {
616616 const aligned: *align(16) const fn () callconv(.c) void = @alignCast(unaligned);
617617 try expect(@intFromPtr(aligned) == int);
618618}
619
620test "align expression is implicitly comptime" {
621 const S = struct {
622 fn alignment() usize {
623 return 4;
624 }
625
626 var global: [3]u8 align(alignment()) = @splat(0);
627 fn check() !void {
628 try std.testing.expect(@intFromPtr(&global) % alignment() == 0);
629 var local: [3]u8 align(alignment()) = @splat(0);
630 try std.testing.expect(@intFromPtr(&local) % alignment() == 0);
631 var de: [3]u8 align(alignment()), var structure: [3]u8 align(alignment()) = .{ @splat(0), @splat(0) };
632 try std.testing.expect(@intFromPtr(&de) % alignment() == 0);
633 try std.testing.expect(@intFromPtr(&structure) % alignment() == 0);
634 var @"struct": struct { field: [3]u8 align(alignment()) } = .{ .field = @splat(0) };
635 try std.testing.expect(@intFromPtr(&@"struct".field) % alignment() == 0);
636 var @"union": union { field: [3]u8 align(alignment()) } = .{ .field = @splat(0) };
637 try std.testing.expect(@intFromPtr(&@"union".field) % alignment() == 0);
638 const ptr: *align(alignment()) [3]u8 = &global;
639 try std.testing.expect(@intFromPtr(ptr) % alignment() == 0);
640 }
641 };
642 try S.check();
643}
test/cases/compile_errors/runtime_align.zig created+46
......@@ -0,0 +1,46 @@
1var alignment: u29 = 4;
2
3var global: u8 align(alignment) = 0;
4export fn globalWithRuntimeAlign() u8 {
5 return global;
6}
7
8export fn localWithRuntimeAlign() u8 {
9 const local: u8 align(alignment) = 0;
10 return local;
11}
12
13export fn destructureWithRuntimeAlign() u8 {
14 const de: u8 align(alignment), const structure align(alignment) = .{ 0, 0 };
15 return de | structure;
16}
17
18export fn structFieldWithRuntimeAlign() u8 {
19 const @"struct": struct { field: u8 align(alignment) } = .{ .field = 0 };
20 return @"struct".field;
21}
22
23export fn unionFieldWithRuntimeAlign() u8 {
24 const @"union": union { field: u8 align(alignment) } = .{ .field = 0 };
25 return @"union".field;
26}
27
28export fn pointerWithRuntimeAlign() u8 {
29 const ptr: *align(alignment) u8 = &global;
30 return ptr.*;
31}
32
33// error
34//
35// :3:22: error: unable to resolve comptime value
36// :3:22: note: alignment must be comptime-known
37// :9:27: error: unable to resolve comptime value
38// :9:27: note: alignment must be comptime-known
39// :14:24: error: unable to resolve comptime value
40// :14:24: note: alignment must be comptime-known
41// :19:47: error: unable to resolve comptime value
42// :19:47: note: alignment must be comptime-known
43// :24:45: error: unable to resolve comptime value
44// :24:45: note: alignment must be comptime-known
45// :29:23: error: unable to resolve comptime value
46// :29:23: note: alignment must be comptime-known