diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig index 8620df51fa0dea04e3c075951bf0df0c161dd363..7c73c3d4d762b94c69914875d237b167eb2929de 100644 --- a/lib/std/zig/Ast.zig +++ b/lib/std/zig/Ast.zig @@ -2136,10 +2136,12 @@ 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.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) { - .many, .c => info.main_token + 1, - else => info.main_token, - }; + var i = (if (info.sentinel.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) { + .one => info.main_token, + .slice => info.main_token + 1, + .many => info.main_token + 2, + .c => info.main_token + 3, + }) + 1; const end = tree.firstToken(info.child_type); while (i < end) : (i += 1) { switch (tree.tokenTag(i)) { @@ -2147,15 +2149,15 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType .keyword_const => result.const_token = i, .keyword_volatile => result.volatile_token = i, .keyword_align => { - const align_node = info.align_node.unwrap().?; if (info.bit_range_end.unwrap()) |bit_range_end| { assert(info.bit_range_start != .none); i = tree.lastToken(bit_range_end) + 1; - } else { + } else if (info.align_node.unwrap()) |align_node| { i = tree.lastToken(align_node) + 1; - } + } else unreachable; }, - else => {}, + .keyword_addrspace => i = tree.lastToken(info.addrspace_node.unwrap().?) + 1, + else => unreachable, } } return result; diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index af26c82957275a921d8f12c9ca398c13cf59b7d9..226c6da270a06c6785e2aa2b68d493832b43f5b3 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -6973,6 +6973,23 @@ test "ampersand" { , &.{}); } +test "Ast: pointer types with subexprs containing qualifiers" { + var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]); + const allocator = fixed_allocator.allocator(); + var tree = try std.zig.Ast.parse(allocator, "**addrspace(*align(1)T)T", .zon); + defer tree.deinit(allocator); + + const regular_ptr_node = tree.nodeData(.root).node; + const full_regular_ptr = tree.fullPtrType(regular_ptr_node) orelse return error.TestFailed; + try std.testing.expect(full_regular_ptr.ast.addrspace_node == .none); + try std.testing.expect(full_regular_ptr.ast.align_node == .none); + + const special_ptr_node = full_regular_ptr.ast.child_type; + const full_special_ptr = tree.fullPtrType(special_ptr_node) orelse return error.TestFailed; + try std.testing.expect(full_special_ptr.ast.addrspace_node != .none); + try std.testing.expect(full_special_ptr.ast.align_node == .none); +} + var fixed_buffer_mem: [100 * 1024]u8 = undefined; fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_changed: *bool) ![]u8 {