From 3deb86bafdb2f622b9099c405e0e861f70c36a45 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 12 Jun 2026 13:11:56 -0400 Subject: [PATCH] AstGen: make local align expression implicitly comptime Closes #35730 --- lib/std/zig/AstGen.zig | 4 +- test/behavior/align.zig | 25 +++++++++++ test/cases/compile_errors/runtime_align.zig | 46 +++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 test/cases/compile_errors/runtime_align.zig diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig index b9de0ee6ee2eead54e661e927e3d726033156a29..b9084412f3b71875e3257efa08a6633839a37e2a 100644 --- a/lib/std/zig/AstGen.zig +++ b/lib/std/zig/AstGen.zig @@ -3130,7 +3130,7 @@ fn varDecl( } const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node.unwrap()) |align_node| - try expr(gz, scope, coerced_align_ri, align_node) + try comptimeExpr(gz, scope, coerced_align_ri, align_node, .@"align") else .none; @@ -3477,7 +3477,7 @@ fn assignDestructureMaybeDecls( const this_variable_comptime = is_comptime or (is_const and value_is_comptime); const align_inst: Zir.Inst.Ref = if (full_var_decl.ast.align_node.unwrap()) |align_node| - try expr(gz, scope, coerced_align_ri, align_node) + try comptimeExpr(gz, scope, coerced_align_ri, align_node, .@"align") else .none; diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 3de3dd090670331c27e4856e90246483546a2432..9d4886ee954d42be8f7684091577305b568056be 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -616,3 +616,28 @@ test "function pointer align mask" { const aligned: *align(16) const fn () callconv(.c) void = @alignCast(unaligned); try expect(@intFromPtr(aligned) == int); } + +test "align expression is implicitly comptime" { + const S = struct { + fn alignment() usize { + return 4; + } + + var global: [3]u8 align(alignment()) = @splat(0); + fn check() !void { + try std.testing.expect(@intFromPtr(&global) % alignment() == 0); + var local: [3]u8 align(alignment()) = @splat(0); + try std.testing.expect(@intFromPtr(&local) % alignment() == 0); + var de: [3]u8 align(alignment()), var structure: [3]u8 align(alignment()) = .{ @splat(0), @splat(0) }; + try std.testing.expect(@intFromPtr(&de) % alignment() == 0); + try std.testing.expect(@intFromPtr(&structure) % alignment() == 0); + var @"struct": struct { field: [3]u8 align(alignment()) } = .{ .field = @splat(0) }; + try std.testing.expect(@intFromPtr(&@"struct".field) % alignment() == 0); + var @"union": union { field: [3]u8 align(alignment()) } = .{ .field = @splat(0) }; + try std.testing.expect(@intFromPtr(&@"union".field) % alignment() == 0); + const ptr: *align(alignment()) [3]u8 = &global; + try std.testing.expect(@intFromPtr(ptr) % alignment() == 0); + } + }; + try S.check(); +} diff --git a/test/cases/compile_errors/runtime_align.zig b/test/cases/compile_errors/runtime_align.zig new file mode 100644 index 0000000000000000000000000000000000000000..d9356f7a4169f16e37d2155c5a68869a3738eb12 --- /dev/null +++ b/test/cases/compile_errors/runtime_align.zig @@ -0,0 +1,46 @@ +var alignment: u29 = 4; + +var global: u8 align(alignment) = 0; +export fn globalWithRuntimeAlign() u8 { + return global; +} + +export fn localWithRuntimeAlign() u8 { + const local: u8 align(alignment) = 0; + return local; +} + +export fn destructureWithRuntimeAlign() u8 { + const de: u8 align(alignment), const structure align(alignment) = .{ 0, 0 }; + return de | structure; +} + +export fn structFieldWithRuntimeAlign() u8 { + const @"struct": struct { field: u8 align(alignment) } = .{ .field = 0 }; + return @"struct".field; +} + +export fn unionFieldWithRuntimeAlign() u8 { + const @"union": union { field: u8 align(alignment) } = .{ .field = 0 }; + return @"union".field; +} + +export fn pointerWithRuntimeAlign() u8 { + const ptr: *align(alignment) u8 = &global; + return ptr.*; +} + +// error +// +// :3:22: error: unable to resolve comptime value +// :3:22: note: alignment must be comptime-known +// :9:27: error: unable to resolve comptime value +// :9:27: note: alignment must be comptime-known +// :14:24: error: unable to resolve comptime value +// :14:24: note: alignment must be comptime-known +// :19:47: error: unable to resolve comptime value +// :19:47: note: alignment must be comptime-known +// :24:45: error: unable to resolve comptime value +// :24:45: note: alignment must be comptime-known +// :29:23: error: unable to resolve comptime value +// :29:23: note: alignment must be comptime-known -- 2.54.0