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(...@@ -3130,7 +3130,7 @@ fn varDecl(
3130 }3130 }
31313131
3132 const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node.unwrap()) |align_node|3132 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")
3134 else3134 else
3135 .none;3135 .none;
31363136
...@@ -3477,7 +3477,7 @@ fn assignDestructureMaybeDecls(...@@ -3477,7 +3477,7 @@ fn assignDestructureMaybeDecls(
3477 const this_variable_comptime = is_comptime or (is_const and value_is_comptime);3477 const this_variable_comptime = is_comptime or (is_const and value_is_comptime);
34783478
3479 const align_inst: Zir.Inst.Ref = if (full_var_decl.ast.align_node.unwrap()) |align_node|3479 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")
3481 else3481 else
3482 .none;3482 .none;
34833483
test/behavior/align.zig+25
...@@ -616,3 +616,28 @@ test "function pointer align mask" {...@@ -616,3 +616,28 @@ test "function pointer align mask" {
616 const aligned: *align(16) const fn () callconv(.c) void = @alignCast(unaligned);616 const aligned: *align(16) const fn () callconv(.c) void = @alignCast(unaligned);
617 try expect(@intFromPtr(aligned) == int);617 try expect(@intFromPtr(aligned) == int);
618}618}
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