diff --git a/lib/compiler/aro_translate_c/ast.zig b/lib/compiler/aro_translate_c/ast.zig index 9283ef5bbf..853fcb748c 100644 --- a/lib/compiler/aro_translate_c/ast.zig +++ b/lib/compiler/aro_translate_c/ast.zig @@ -1527,11 +1527,11 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { .c_pointer, .single_pointer => { const payload = @as(*Payload.Pointer, @alignCast(@fieldParentPtr("base", node.ptr_otherwise))).data; - const asterisk = if (node.tag() == .single_pointer) + const main_token = if (node.tag() == .single_pointer) try c.addToken(.asterisk, "*") else blk: { - _ = try c.addToken(.l_bracket, "["); - const res = try c.addToken(.asterisk, "*"); + const res = try c.addToken(.l_bracket, "["); + _ = try c.addToken(.asterisk, "*"); _ = try c.addIdentifier("c"); _ = try c.addToken(.r_bracket, "]"); break :blk res; @@ -1542,7 +1542,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { return c.addNode(.{ .tag = .ptr_type_aligned, - .main_token = asterisk, + .main_token = main_token, .data = .{ .lhs = 0, .rhs = elem_type, diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig index f50ec8305a..f55d78b6ce 100644 --- a/lib/std/zig/Ast.zig +++ b/lib/std/zig/Ast.zig @@ -729,19 +729,7 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { .ptr_type_sentinel, .ptr_type, .ptr_type_bit_range, - => { - const main_token = main_tokens[n]; - return switch (token_tags[main_token]) { - .asterisk, - .asterisk_asterisk, - => switch (token_tags[main_token -| 1]) { - .l_bracket => main_token -| 1, - else => main_token, - }, - .l_bracket => main_token, - else => unreachable, - } - end_offset; - }, + => return main_tokens[n] - end_offset, .switch_case_one => { if (datas[n].lhs == 0) { @@ -2159,12 +2147,11 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType const size: Size = switch (token_tags[info.main_token]) { .asterisk, .asterisk_asterisk, - => switch (token_tags[info.main_token + 1]) { - .r_bracket, .colon => .Many, - .identifier => if (token_tags[info.main_token -| 1] == .l_bracket) Size.C else .One, - else => .One, + => .One, + .l_bracket => switch (token_tags[info.main_token + 1]) { + .asterisk => if (token_tags[info.main_token + 2] == .identifier) Size.C else Size.Many, + else => Size.Slice, }, - .l_bracket => Size.Slice, else => unreachable, }; var result: full.PtrType = .{ @@ -2178,7 +2165,10 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType // here while looking for modifiers as that could result in false // positives. Therefore, start after a sentinel if there is one and // skip over any align node and bit range nodes. - var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else info.main_token; + var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else switch (size) { + .Many, .C => info.main_token + 1, + else => info.main_token, + }; const end = tree.firstToken(info.child_type); while (i < end) : (i += 1) { switch (token_tags[i]) { @@ -3147,24 +3137,28 @@ 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 lbracket if a slice + /// main_token is the asterisk if a single item pointer or the lbracket + /// if a slice, many-item pointer, or C-pointer /// main_token might be a ** token, which is shared with a parent/child /// pointer type and may require special handling. ptr_type_aligned, /// `[*:lhs]rhs`. lhs can be omitted. /// `*rhs`. /// `[:lhs]rhs`. - /// main_token is the asterisk if a pointer or the lbracket if a slice + /// main_token is the asterisk if a single item pointer or the lbracket + /// if a slice, many-item pointer, or C-pointer /// main_token might be a ** token, which is shared with a parent/child /// pointer type and may require special handling. ptr_type_sentinel, /// lhs is index into ptr_type. rhs is the element type expression. - /// main_token is the asterisk if a pointer or the lbracket if a slice + /// main_token is the asterisk if a single item pointer or the lbracket + /// if a slice, many-item pointer, or C-pointer /// main_token might be a ** token, which is shared with a parent/child /// pointer type and may require special handling. ptr_type, /// lhs is index into ptr_type_bit_range. rhs is the element type expression. - /// main_token is the asterisk if a pointer or the lbracket if a slice + /// main_token is the asterisk if a single item pointer or the lbracket + /// if a slice, many-item pointer, or C-pointer /// main_token might be a ** token, which is shared with a parent/child /// pointer type and may require special handling. ptr_type_bit_range, diff --git a/lib/std/zig/Parse.zig b/lib/std/zig/Parse.zig index 369e2ef125..c43868a7d4 100644 --- a/lib/std/zig/Parse.zig +++ b/lib/std/zig/Parse.zig @@ -1905,8 +1905,8 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { }, .l_bracket => switch (p.token_tags[p.tok_i + 1]) { .asterisk => { + const l_bracket = p.nextToken(); _ = p.nextToken(); - const asterisk = p.nextToken(); var sentinel: Node.Index = 0; if (p.eatToken(.identifier)) |ident| { const ident_slice = p.source[p.token_starts[ident]..p.token_starts[ident + 1]]; @@ -1923,7 +1923,7 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { if (sentinel == 0 and mods.addrspace_node == 0) { return p.addNode(.{ .tag = .ptr_type_aligned, - .main_token = asterisk, + .main_token = l_bracket, .data = .{ .lhs = mods.align_node, .rhs = elem_type, @@ -1932,7 +1932,7 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { } else if (mods.align_node == 0 and mods.addrspace_node == 0) { return p.addNode(.{ .tag = .ptr_type_sentinel, - .main_token = asterisk, + .main_token = l_bracket, .data = .{ .lhs = sentinel, .rhs = elem_type, @@ -1941,7 +1941,7 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { } else { return p.addNode(.{ .tag = .ptr_type, - .main_token = asterisk, + .main_token = l_bracket, .data = .{ .lhs = try p.addExtra(Node.PtrType{ .sentinel = sentinel, @@ -1955,7 +1955,7 @@ fn parseTypeExpr(p: *Parse) Error!Node.Index { } else { return p.addNode(.{ .tag = .ptr_type_bit_range, - .main_token = asterisk, + .main_token = l_bracket, .data = .{ .lhs = try p.addExtra(Node.PtrTypeBitRange{ .sentinel = sentinel, diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index ec53ab5046..5130ce4037 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -5915,6 +5915,15 @@ test "zig fmt: error for ptr mod on array child type" { }); } +test "zig fmt: pointer type syntax to index" { + try testCanonical( + \\test { + \\ _ = .{}[*0]; + \\} + \\ + ); +} + test "recovery: top level" { try testError( \\test "" {inline} diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 336f394211..177bd948d8 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -961,22 +961,22 @@ fn renderPtrType(r: *Render, ptr_type: Ast.full.PtrType, space: Space) Error!voi }, .Many => { if (ptr_type.ast.sentinel == 0) { - try renderToken(r, ptr_type.ast.main_token - 1, .none); // lbracket - try renderToken(r, ptr_type.ast.main_token, .none); // asterisk - try renderToken(r, ptr_type.ast.main_token + 1, .none); // rbracket + try renderToken(r, ptr_type.ast.main_token, .none); // lbracket + try renderToken(r, ptr_type.ast.main_token + 1, .none); // asterisk + try renderToken(r, ptr_type.ast.main_token + 2, .none); // rbracket } else { - try renderToken(r, ptr_type.ast.main_token - 1, .none); // lbracket - try renderToken(r, ptr_type.ast.main_token, .none); // asterisk - try renderToken(r, ptr_type.ast.main_token + 1, .none); // colon + try renderToken(r, ptr_type.ast.main_token, .none); // lbracket + try renderToken(r, ptr_type.ast.main_token + 1, .none); // asterisk + try renderToken(r, ptr_type.ast.main_token + 2, .none); // colon try renderExpression(r, ptr_type.ast.sentinel, .none); try renderToken(r, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket } }, .C => { - try renderToken(r, ptr_type.ast.main_token - 1, .none); // lbracket - try renderToken(r, ptr_type.ast.main_token, .none); // asterisk - try renderToken(r, ptr_type.ast.main_token + 1, .none); // c - try renderToken(r, ptr_type.ast.main_token + 2, .none); // rbracket + try renderToken(r, ptr_type.ast.main_token, .none); // lbracket + try renderToken(r, ptr_type.ast.main_token + 1, .none); // asterisk + try renderToken(r, ptr_type.ast.main_token + 2, .none); // c + try renderToken(r, ptr_type.ast.main_token + 3, .none); // rbracket }, .Slice => { if (ptr_type.ast.sentinel == 0) { diff --git a/test/cases/compile_errors/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig b/test/cases/compile_errors/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig index 45fa4c14f5..973290ea93 100644 --- a/test/cases/compile_errors/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig +++ b/test/cases/compile_errors/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig @@ -11,4 +11,4 @@ pub export fn entry() void { // // :5:14: error: expected type '[*:0]const u8', found '[*]const u8' // :5:14: note: destination pointer requires '0' sentinel -// :1:20: note: parameter type declared here +// :1:19: note: parameter type declared here diff --git a/test/cases/compile_errors/incompatible_sentinels.zig b/test/cases/compile_errors/incompatible_sentinels.zig index 169a69a75a..53bbf20b40 100644 --- a/test/cases/compile_errors/incompatible_sentinels.zig +++ b/test/cases/compile_errors/incompatible_sentinels.zig @@ -21,10 +21,10 @@ export fn entry4() void { // // :4:12: error: expected type '[*:0]u8', found '[*:255]u8' // :4:12: note: pointer sentinel '255' cannot cast into pointer sentinel '0' -// :3:35: note: function return type declared here +// :3:34: note: function return type declared here // :7:12: error: expected type '[*:0]u8', found '[*]u8' // :7:12: note: destination pointer requires '0' sentinel -// :6:31: note: function return type declared here +// :6:30: note: function return type declared here // :10:35: error: expected type '[2:0]u8', found '[2:255]u8' // :10:35: note: array sentinel '255' cannot cast into array sentinel '0' // :14:31: error: expected type '[2:0]u8', found '[2]u8' diff --git a/test/cases/compile_errors/issue_4207_coerce_from_non-terminated-slice_to_terminated-pointer.zig b/test/cases/compile_errors/issue_4207_coerce_from_non-terminated-slice_to_terminated-pointer.zig index dc5a709553..cc24cd00e6 100644 --- a/test/cases/compile_errors/issue_4207_coerce_from_non-terminated-slice_to_terminated-pointer.zig +++ b/test/cases/compile_errors/issue_4207_coerce_from_non-terminated-slice_to_terminated-pointer.zig @@ -9,4 +9,4 @@ export fn foo() [*:0]const u8 { // // :3:18: error: expected type '[*:0]const u8', found '*[64]u8' // :3:18: note: destination pointer requires '0' sentinel -// :1:18: note: function return type declared here +// :1:17: note: function return type declared here diff --git a/test/cases/compile_errors/using_an_unknown_len_ptr_type_instead_of_array.zig b/test/cases/compile_errors/using_an_unknown_len_ptr_type_instead_of_array.zig index c1f593b9bd..3eb594698f 100644 --- a/test/cases/compile_errors/using_an_unknown_len_ptr_type_instead_of_array.zig +++ b/test/cases/compile_errors/using_an_unknown_len_ptr_type_instead_of_array.zig @@ -10,4 +10,4 @@ comptime { // backend=stage2 // target=native // -// :1:22: error: type '[*][*]const u8' does not support array initialization syntax +// :1:21: error: type '[*][*]const u8' does not support array initialization syntax