diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index 621b79b80f..8df99a640f 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -407,7 +407,9 @@ pub const Tree = struct { => { const main_token = main_tokens[n]; return switch (token_tags[main_token]) { - .Asterisk => switch (token_tags[main_token - 1]) { + .Asterisk, + .AsteriskAsterisk, + => switch (token_tags[main_token - 1]) { .LBracket => main_token - 1, else => main_token, }, @@ -1625,7 +1627,9 @@ pub const Tree = struct { // literals in some places here const Kind = full.PtrType.Kind; const kind: Kind = switch (token_tags[info.main_token]) { - .Asterisk => switch (token_tags[info.main_token + 1]) { + .Asterisk, + .AsteriskAsterisk, + => switch (token_tags[info.main_token + 1]) { .RBracket => .many, .Colon => .sentinel, .Identifier => if (token_tags[info.main_token - 1] == .LBracket) Kind.c else .one, @@ -2393,18 +2397,26 @@ pub const Node = struct { /// `[*]align(lhs) rhs`. lhs can be omitted. /// `*align(lhs) rhs`. lhs can be omitted. /// `[]rhs`. - /// main_token is the asterisk if a pointer or the lbrace if a slice + /// main_token is the asterisk if a pointer or the lbracket if a slice + /// main_token might be a ** token, which is shared with a parent/child + /// pointer type and may require special handling. PtrTypeAligned, /// `[*:lhs]rhs`. lhs can be omitted. /// `*rhs`. /// `[:lhs]rhs`. - /// main_token is the asterisk if a pointer or the lbrace if a slice + /// main_token is the asterisk if a pointer or the lbracket if a slice + /// main_token might be a ** token, which is shared with a parent/child + /// pointer type and may require special handling. PtrTypeSentinel, /// lhs is index into PtrType. rhs is the element type expression. - /// main_token is the asterisk if a pointer or the lbrace if a slice + /// main_token is the asterisk if a pointer or the lbracket if a slice + /// main_token might be a ** token, which is shared with a parent/child + /// pointer type and may require special handling. PtrType, /// lhs is index into PtrTypeBitRange. rhs is the element type expression. - /// main_token is the asterisk if a pointer or the lbrace if a slice + /// main_token is the asterisk if a pointer or the lbracket if a slice + /// main_token might be a ** token, which is shared with a parent/child + /// pointer type and may require special handling. PtrTypeBitRange, /// `lhs[rhs..]` /// main_token is the lbracket. diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 98478d68b7..e8e9c1a2e2 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -2318,27 +2318,27 @@ test "zig fmt: alignment" { ); } -//test "zig fmt: C main" { -// try testCanonical( -// \\fn main(argc: c_int, argv: **u8) c_int { -// \\ const a = b; -// \\} -// \\ -// ); -//} -// -//test "zig fmt: return" { -// try testCanonical( -// \\fn foo(argc: c_int, argv: **u8) c_int { -// \\ return 0; -// \\} -// \\ -// \\fn bar() void { -// \\ return; -// \\} -// \\ -// ); -//} +test "zig fmt: C main" { + try testCanonical( + \\fn main(argc: c_int, argv: **u8) c_int { + \\ const a = b; + \\} + \\ + ); +} + +test "zig fmt: return" { + try testCanonical( + \\fn foo(argc: c_int, argv: **u8) c_int { + \\ return 0; + \\} + \\ + \\fn bar() void { + \\ return; + \\} + \\ + ); +} test "zig fmt: function attributes" { try testCanonical( @@ -2356,27 +2356,40 @@ test "zig fmt: function attributes" { ); } -//test "zig fmt: pointer attributes" { -// try testCanonical( -// \\extern fn f1(s: *align(*u8) u8) c_int; -// \\extern fn f2(s: **align(1) *const *volatile u8) c_int; -// \\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int; -// \\extern fn f4(s: *align(1) const volatile u8) c_int; -// \\extern fn f5(s: [*:0]align(1) const volatile u8) c_int; -// \\ -// ); -//} -// -//test "zig fmt: slice attributes" { -// try testCanonical( -// \\extern fn f1(s: *align(*u8) u8) c_int; -// \\extern fn f2(s: **align(1) *const *volatile u8) c_int; -// \\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int; -// \\extern fn f4(s: *align(1) const volatile u8) c_int; -// \\extern fn f5(s: [*:0]align(1) const volatile u8) c_int; -// \\ -// ); -//} +test "zig fmt: nested pointers with ** tokens" { + try testCanonical( + \\const x: *u32 = undefined; + \\const x: **u32 = undefined; + \\const x: ***u32 = undefined; + \\const x: ****u32 = undefined; + \\const x: *****u32 = undefined; + \\const x: ******u32 = undefined; + \\const x: *******u32 = undefined; + \\ + ); +} + +test "zig fmt: pointer attributes" { + try testCanonical( + \\extern fn f1(s: *align(*u8) u8) c_int; + \\extern fn f2(s: **align(1) *const *volatile u8) c_int; + \\extern fn f3(s: *align(1) const *align(1) volatile *const volatile u8) c_int; + \\extern fn f4(s: *align(1) const volatile u8) c_int; + \\extern fn f5(s: [*:0]align(1) const volatile u8) c_int; + \\ + ); +} + +test "zig fmt: slice attributes" { + try testCanonical( + \\extern fn f1(s: []align(*u8) u8) c_int; + \\extern fn f2(s: []align(1) []const []volatile u8) c_int; + \\extern fn f3(s: []align(1) const [:0]align(1) volatile []const volatile u8) c_int; + \\extern fn f4(s: []align(1) const volatile u8) c_int; + \\extern fn f5(s: [:0]align(1) const volatile u8) c_int; + \\ + ); +} test "zig fmt: test declaration" { try testCanonical( diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index c27cce795a..1be114a6a1 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -699,6 +699,16 @@ fn renderPtrType( ) Error!void { switch (ptr_type.kind) { .one => { + // Since ** tokens exist and the same token is shared by two + // nested pointer types, we check to see if we are the parent + // in such a relationship. If so, skip rendering anything for + // this pointer type and rely on the child to render our asterisk + // as well when it renders the ** token. + if (tree.tokens.items(.tag)[ptr_type.ast.main_token] == .AsteriskAsterisk and + ptr_type.ast.main_token == tree.nodes.items(.main_token)[ptr_type.ast.child_type]) + { + return renderExpression(ais, tree, ptr_type.ast.child_type, space); + } try renderToken(ais, tree, ptr_type.ast.main_token, .None); // asterisk }, .many => {