Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 97645f3

Browse files
committedMar 14, 2025··
std.zig.render: Fix multiple fmt invocations needed for array initializers with switch expressions
1 parent 1f92b39 commit 97645f3

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed
 

‎lib/std/zig/render.zig

+23-1
Original file line numberDiff line numberDiff line change
@@ -2076,8 +2076,9 @@ fn renderArrayInit(
20762076

20772077
const contains_comment = hasComment(tree, array_init.ast.lbrace, rbrace);
20782078
const contains_multiline_string = hasMultilineString(tree, array_init.ast.lbrace, rbrace);
2079+
const contains_switch = containsSwitch(tree, array_init.ast.elements);
20792080

2080-
if (!trailing_comma and !contains_comment and !contains_multiline_string) {
2081+
if (!trailing_comma and !contains_comment and !contains_multiline_string and !contains_switch) {
20812082
// Render all on one line, no trailing comma.
20822083
if (array_init.ast.elements.len == 1) {
20832084
// If there is only one element, we don't use spaces
@@ -2260,6 +2261,27 @@ fn renderArrayInit(
22602261
return renderToken(r, rbrace, space); // rbrace
22612262
}
22622263

2264+
/// Returns true if any array element is or contains a switch expression
2265+
fn containsSwitch(tree: Ast, elements: []const Ast.Node.Index) bool {
2266+
const tags = tree.nodes.items(.tag);
2267+
2268+
for (elements) |elem| {
2269+
const tag = tags[@intFromEnum(elem)];
2270+
2271+
if (tag == .switch_case or
2272+
tag == .switch_case_inline or
2273+
tag == .switch_case_one or
2274+
tag == .switch_case_inline_one or
2275+
tag == .@"switch" or
2276+
tag == .switch_comma)
2277+
{
2278+
return true;
2279+
}
2280+
}
2281+
2282+
return false;
2283+
}
2284+
22632285
fn renderContainerDecl(
22642286
r: *Render,
22652287
container_decl_node: Ast.Node.Index,

‎test/tests.zig

+44
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,50 @@ pub fn addCliTests(b: *std.Build) *Step {
12991299
});
13001300
check6.step.dependOn(&run6.step);
13011301

1302+
// Test `zig fmt` handling switch expressions in array initializers
1303+
const switch_in_array_code =
1304+
\\const bar = .{ .{ switch ({}) {
1305+
\\ else => {},
1306+
\\ } }, .{}, .{}, .{},
1307+
\\};
1308+
\\
1309+
;
1310+
1311+
const fmt7_path = b.pathJoin(&.{ tmp_path, "fmt7.zig" });
1312+
const write7 = b.addUpdateSourceFiles();
1313+
write7.addBytesToSource(switch_in_array_code, fmt7_path);
1314+
write7.step.dependOn(&check6.step);
1315+
1316+
// Test `zig fmt` handling switch expressions in array initializers
1317+
const run7 = b.addSystemCommand(&.{ b.graph.zig_exe, "fmt", "fmt7.zig" });
1318+
run7.setName("run zig fmt on array with switch");
1319+
run7.setCwd(.{ .cwd_relative = tmp_path });
1320+
run7.has_side_effects = true;
1321+
run7.expectStdOutEqual("fmt7.zig\n");
1322+
run7.step.dependOn(&write7.step);
1323+
1324+
// Check that the file is formatted correctly after a single fmt invocation
1325+
const check7 = b.addCheckFile(.{ .cwd_relative = fmt7_path }, .{
1326+
.expected_matches = &.{
1327+
"const bar = .{",
1328+
" .{switch ({}) {",
1329+
" else => {},",
1330+
" }},",
1331+
" .{},",
1332+
" .{},",
1333+
" .{},",
1334+
"};",
1335+
},
1336+
});
1337+
check7.step.dependOn(&run7.step);
1338+
1339+
// Run fmt again to verify that no further changes are made (idempotence)
1340+
const run8 = b.addSystemCommand(&.{ b.graph.zig_exe, "fmt", "fmt7.zig" });
1341+
run8.setName("run zig fmt again on array with switch");
1342+
run8.setCwd(.{ .cwd_relative = tmp_path });
1343+
run8.has_side_effects = true;
1344+
run8.step.dependOn(&check7.step);
1345+
13021346
const cleanup = b.addRemoveDirTree(.{ .cwd_relative = tmp_path });
13031347
cleanup.step.dependOn(&check6.step);
13041348

0 commit comments

Comments
 (0)
Please sign in to comment.