Commit 8c4f3e5a31
Changed files (3)
lib
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.
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(
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 => {