From c6845524ce8aa7ea99b68c98fb0e1acf43b21e87 Mon Sep 17 00:00:00 2001 From: Kendall Condon Date: Mon, 28 Jul 2025 16:39:20 -0400 Subject: [PATCH] zig fmt: fix doc comments on fn paramaters without comma --- lib/std/zig/Ast/Render.zig | 29 ++++++++++++++++++++------ lib/std/zig/parser_test.zig | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/lib/std/zig/Ast/Render.zig b/lib/std/zig/Ast/Render.zig index 6752da2ae4..ccbaba1469 100644 --- a/lib/std/zig/Ast/Render.zig +++ b/lib/std/zig/Ast/Render.zig @@ -1617,6 +1617,27 @@ fn renderBuiltinCall( return renderParamList(r, builtin_token + 1, params, space); } +fn isOneLineFnProto( + tree: Ast, + fn_proto: Ast.full.FnProto, + lparen: Ast.TokenIndex, + rparen: Ast.TokenIndex, +) bool { + const trailing_comma = tree.tokenTag(rparen - 1) == .comma; + if (trailing_comma or hasComment(tree, lparen, rparen)) + return false; + + // Check that there are no doc comments + var after_last_param = lparen + 1; + for (fn_proto.ast.params) |expr| { + // Looking before each param is insufficient since anytype is not included in `params` + if (hasDocComment(tree, after_last_param, tree.firstToken(expr))) + return false; + after_last_param = tree.lastToken(expr) + 1; + } + return !hasDocComment(tree, after_last_param, rparen); +} + fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!void { const tree = r.tree; const ais = r.ais; @@ -1677,8 +1698,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi // The params list is a sparse set that does *not* include anytype or ... parameters. - const trailing_comma = tree.tokenTag(rparen - 1) == .comma; - if (!trailing_comma and !hasComment(tree, lparen, rparen)) { + if (isOneLineFnProto(tree, fn_proto, lparen, rparen)) { // Render all on one line, no trailing comma. try renderToken(r, lparen, .none); // ( @@ -1687,10 +1707,7 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi while (true) { last_param_token += 1; switch (tree.tokenTag(last_param_token)) { - .doc_comment => { - try renderToken(r, last_param_token, .newline); - continue; - }, + .doc_comment => unreachable, .ellipsis3 => { try renderToken(r, last_param_token, .none); // ... break; diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index f7b6d3ed2d..676ea0b03c 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -6448,6 +6448,47 @@ test "zig fmt: whitespace with multiline strings" { ); } +test "zig fmt: doc comments on fn parameters" { + try testTransform( + \\extern fn foo( + \\ /// Bitmap + \\ active: u64 + \\) void; + \\extern fn bar( + \\ bits: u6, + \\ /// Bitmap + \\ active: u64 + \\) void; + \\extern fn baz( + \\ /// Bitmap + \\ active: anytype + \\) void; + \\ + , + \\extern fn foo( + \\ /// Bitmap + \\ active: u64, + \\) void; + \\extern fn bar( + \\ bits: u6, + \\ /// Bitmap + \\ active: u64, + \\) void; + \\extern fn baz( + \\ /// Bitmap + \\ active: anytype, + \\) void; + \\ + ); + try testCanonical( + \\extern fn foo(x: struct { + \\ /// Bitmap + \\ active: u64, + \\}) void; + \\ + ); +} + test "recovery: top level" { try testError( \\test "" {inline}