Skip to content

Commit e2cfbe7

Browse files
barry3406Techatrix
authored andcommitted
preserve allowzero, align, volatile, and addrspace on pointer types
The `ptr_type` resolver in analysis.zig only read `const_token` from `ptr_info`, and `Data.createPointer` only set `is_const` on the `InternPool.pointer_type` flags. As a result, types like `*allowzero u8`, `*align(4) u8`, `*volatile u8` were collapsed to `*u8` in inlay hints (and any other surface that runs through `stringifyTypeOf`). Read `volatile_token`, `allowzero_token`, and the integer literal in `ast.align_node` from `ptr_info`, plumb them through `createPointerType` / `Data.createPointer` into the IP flags and the `.pointer` Data fallback, and update `rawStringify` so the fallback path matches the InternPool printer. Address-space resolution from arbitrary expressions still defers to `.generic`; only the literal alignment integer is read for now. Fixes #2603.
1 parent 1ebcc79 commit e2cfbe7

2 files changed

Lines changed: 100 additions & 14 deletions

File tree

src/analysis.zig

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,7 @@ pub fn resolveOrelseType(analyser: *Analyser, lhs: Type, rhs: Type) error{OutOfM
908908

909909
pub fn resolveAddressOf(analyser: *Analyser, is_const: bool, ty: Type) error{OutOfMemory}!Type {
910910
const elem_ty = try ty.typeOf(analyser);
911-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, elem_ty);
911+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, false, false, 0, .generic, elem_ty);
912912
return try pointer_ty.instanceUnchecked(analyser);
913913
}
914914

@@ -1231,12 +1231,12 @@ pub fn resolveBracketAccess(analyser: *Analyser, lhs_binding: Binding, rhs: Brac
12311231
switch (result) {
12321232
.array => |elem_count| {
12331233
const array_ty = try Type.createArrayType(analyser, elem_count, sentinel, elem_ty.*);
1234-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, array_ty);
1234+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, false, false, 0, .generic, array_ty);
12351235
const pointer_instance = try pointer_ty.instanceUnchecked(analyser);
12361236
return .{ .type = pointer_instance, .is_const = true };
12371237
},
12381238
.slice => {
1239-
const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, elem_ty.*);
1239+
const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, false, false, 0, .generic, elem_ty.*);
12401240
const slice_instance = try slice_ty.instanceUnchecked(analyser);
12411241
return .{ .type = slice_instance, .is_const = true };
12421242
},
@@ -2153,13 +2153,30 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error
21532153
const ptr_info = ast.fullPtrType(tree, node).?;
21542154
const size = ptr_info.size;
21552155
const is_const = ptr_info.const_token != null;
2156+
const is_volatile = ptr_info.volatile_token != null;
2157+
const is_allowzero = ptr_info.allowzero_token != null;
21562158

21572159
const sentinel = try analyser.resolveOptionalIPValue(ptr_info.ast.sentinel, handle);
21582160

2161+
const alignment: u16 = if (ptr_info.ast.align_node.unwrap()) |align_node|
2162+
try analyser.resolveIntegerLiteral(u16, .of(align_node, handle)) orelse 0
2163+
else
2164+
0;
2165+
21592166
const elem_ty = try analyser.resolveTypeOfNodeInternal(.of(ptr_info.ast.child_type, handle)) orelse return null;
21602167
if (!elem_ty.is_type_val) return null;
21612168

2162-
return try Type.createPointerType(analyser, size, sentinel, is_const, elem_ty);
2169+
return try Type.createPointerType(
2170+
analyser,
2171+
size,
2172+
sentinel,
2173+
is_const,
2174+
is_volatile,
2175+
is_allowzero,
2176+
alignment,
2177+
.generic,
2178+
elem_ty,
2179+
);
21632180
},
21642181
.array_type,
21652182
.array_type_sentinel,
@@ -2957,7 +2974,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error
29572974
elem_ty = try elem_ty.instanceUnchecked(analyser);
29582975
elem_ty = try analyser.resolveArrayMult(elem_ty, mult_lit) orelse return null;
29592976
elem_ty = try elem_ty.typeOf(analyser);
2960-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, elem_ty);
2977+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, false, false, 0, .generic, elem_ty);
29612978
return try pointer_ty.instanceUnchecked(analyser);
29622979
}
29632980

@@ -2979,7 +2996,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error
29792996
r_elem_ty = try r_elem_ty.instanceUnchecked(analyser);
29802997
var elem_ty = try analyser.resolveArrayCat(l_elem_ty, r_elem_ty) orelse return null;
29812998
elem_ty = try elem_ty.typeOf(analyser);
2982-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, elem_ty);
2999+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, false, false, 0, .generic, elem_ty);
29833000
return try pointer_ty.instanceUnchecked(analyser);
29843001
}
29853002

@@ -3184,6 +3201,11 @@ pub const Type = struct {
31843201
/// `.none` means no sentinel, `.unknown_unknown` means unknown sentinel
31853202
sentinel: InternPool.Index,
31863203
is_const: bool,
3204+
is_volatile: bool = false,
3205+
is_allowzero: bool = false,
3206+
/// `0` means default alignment.
3207+
alignment: u16 = 0,
3208+
address_space: std.builtin.AddressSpace = .generic,
31873209
elem_ty: *Type,
31883210
},
31893211

@@ -3290,6 +3312,10 @@ pub const Type = struct {
32903312
size: std.builtin.Type.Pointer.Size,
32913313
sentinel: InternPool.Index,
32923314
is_const: bool,
3315+
is_volatile: bool,
3316+
is_allowzero: bool,
3317+
alignment: u16,
3318+
address_space: std.builtin.AddressSpace,
32933319
elem_ty: Type,
32943320
) !Data {
32953321
std.debug.assert(elem_ty.is_type_val);
@@ -3302,6 +3328,10 @@ pub const Type = struct {
33023328
.flags = .{
33033329
.size = size,
33043330
.is_const = is_const,
3331+
.is_volatile = is_volatile,
3332+
.is_allowzero = is_allowzero,
3333+
.alignment = alignment,
3334+
.address_space = address_space,
33053335
},
33063336
},
33073337
});
@@ -3312,6 +3342,10 @@ pub const Type = struct {
33123342
.size = size,
33133343
.sentinel = sentinel,
33143344
.is_const = is_const,
3345+
.is_volatile = is_volatile,
3346+
.is_allowzero = is_allowzero,
3347+
.alignment = alignment,
3348+
.address_space = address_space,
33153349
.elem_ty = try analyser.allocType(elem_ty),
33163350
},
33173351
};
@@ -3666,11 +3700,18 @@ pub const Type = struct {
36663700
return t.data.resolveGeneric(analyser, bound_params, visiting);
36673701
},
36683702
.pointer => |info| {
3669-
const size = info.size;
3670-
const sentinel = info.sentinel;
3671-
const is_const = info.is_const;
36723703
const elem_ty = try analyser.resolveGenericTypeInternal(info.elem_ty.*, bound_params, visiting);
3673-
return try createPointer(analyser, size, sentinel, is_const, elem_ty);
3704+
return try createPointer(
3705+
analyser,
3706+
info.size,
3707+
info.sentinel,
3708+
info.is_const,
3709+
info.is_volatile,
3710+
info.is_allowzero,
3711+
info.alignment,
3712+
info.address_space,
3713+
elem_ty,
3714+
);
36743715
},
36753716
.array => |info| {
36763717
const elem_count = info.elem_count;
@@ -3769,10 +3810,24 @@ pub const Type = struct {
37693810
size: std.builtin.Type.Pointer.Size,
37703811
sentinel: InternPool.Index,
37713812
is_const: bool,
3813+
is_volatile: bool,
3814+
is_allowzero: bool,
3815+
alignment: u16,
3816+
address_space: std.builtin.AddressSpace,
37723817
elem_ty: Type,
37733818
) !Type {
37743819
return .{
3775-
.data = try Data.createPointer(analyser, size, sentinel, is_const, elem_ty),
3820+
.data = try Data.createPointer(
3821+
analyser,
3822+
size,
3823+
sentinel,
3824+
is_const,
3825+
is_volatile,
3826+
is_allowzero,
3827+
alignment,
3828+
address_space,
3829+
elem_ty,
3830+
),
37763831
.is_type_val = true,
37773832
};
37783833
}
@@ -4605,7 +4660,11 @@ pub const Type = struct {
46054660
},
46064661
.c => try writer.writeAll("[*c]"),
46074662
}
4663+
if (info.is_allowzero and info.size != .c) try writer.writeAll("allowzero ");
4664+
if (info.alignment != 0) try writer.print("align({d}) ", .{info.alignment});
4665+
if (info.address_space != .generic) try writer.print("addrspace(.{t}) ", .{info.address_space});
46084666
if (info.is_const) try writer.writeAll("const ");
4667+
if (info.is_volatile) try writer.writeAll("volatile ");
46094668
try info.elem_ty.rawStringify(writer, analyser, options);
46104669
},
46114670
.array => |info| {
@@ -4878,7 +4937,7 @@ fn resolveLangrefType(analyser: *Analyser, type_str: []const u8) Error!?Type {
48784937
elem_str = elem_str[6..];
48794938
const elem_instance = try analyser.resolveLangrefType(elem_str) orelse return null;
48804939
const elem_ty = try elem_instance.typeOf(analyser);
4881-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, elem_ty);
4940+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, false, false, 0, .generic, elem_ty);
48824941
return try pointer_ty.instanceUnchecked(analyser);
48834942
}
48844943

@@ -4914,7 +4973,7 @@ fn resolveLangrefType(analyser: *Analyser, type_str: []const u8) Error!?Type {
49144973
elem_str = elem_str[6..];
49154974
const elem_instance = try analyser.resolveLangrefType(elem_str) orelse return null;
49164975
const elem_ty = try elem_instance.typeOf(analyser);
4917-
const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, elem_ty);
4976+
const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, false, false, 0, .generic, elem_ty);
49184977
return try slice_ty.instanceUnchecked(analyser);
49194978
}
49204979

@@ -6018,7 +6077,7 @@ pub const DeclWithHandle = struct {
60186077
if (!self.isCaptureByRef()) return resolved_ty;
60196078

60206079
const elem_ty = try resolved_ty.typeOf(analyser);
6021-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, false, elem_ty);
6080+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, false, false, false, 0, .generic, elem_ty);
60226081
return try pointer_ty.instanceUnchecked(analyser);
60236082
}
60246083
};

tests/lsp_features/inlay_hints.zig

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,33 @@ test "var decl" {
286286
, .{ .kind = .Type });
287287
}
288288

289+
test "var decl - pointer modifiers" {
290+
try testInlayHints(
291+
\\const a: *u8 = undefined;
292+
\\const b<*u8> = a;
293+
, .{ .kind = .Type });
294+
try testInlayHints(
295+
\\const a: *allowzero u8 = undefined;
296+
\\const b<*allowzero u8> = a;
297+
, .{ .kind = .Type });
298+
try testInlayHints(
299+
\\const a: *align(4) u8 = undefined;
300+
\\const b<*align(4) u8> = a;
301+
, .{ .kind = .Type });
302+
try testInlayHints(
303+
\\const a: *volatile u8 = undefined;
304+
\\const b<*volatile u8> = a;
305+
, .{ .kind = .Type });
306+
try testInlayHints(
307+
\\const a: *allowzero align(8) const volatile u8 = undefined;
308+
\\const b<*allowzero align(8) const volatile u8> = a;
309+
, .{ .kind = .Type });
310+
try testInlayHints(
311+
\\const a: [*]allowzero u8 = undefined;
312+
\\const b<[*]allowzero u8> = a;
313+
, .{ .kind = .Type });
314+
}
315+
289316
test "comptime return types" {
290317
try testInlayHints(
291318
\\fn Box(comptime T: type) type {

0 commit comments

Comments
 (0)