Skip to content

Commit 3cfe1a1

Browse files
committed
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 f391142 commit 3cfe1a1

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
},
@@ -2156,13 +2156,30 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error
21562156
const ptr_info = ast.fullPtrType(tree, node).?;
21572157
const size = ptr_info.size;
21582158
const is_const = ptr_info.const_token != null;
2159+
const is_volatile = ptr_info.volatile_token != null;
2160+
const is_allowzero = ptr_info.allowzero_token != null;
21592161

21602162
const sentinel = try analyser.resolveOptionalIPValue(ptr_info.ast.sentinel, handle);
21612163

2164+
const alignment: u16 = if (ptr_info.ast.align_node.unwrap()) |align_node|
2165+
try analyser.resolveIntegerLiteral(u16, .of(align_node, handle)) orelse 0
2166+
else
2167+
0;
2168+
21622169
const elem_ty = try analyser.resolveTypeOfNodeInternal(.of(ptr_info.ast.child_type, handle)) orelse return null;
21632170
if (!elem_ty.is_type_val) return null;
21642171

2165-
return try Type.createPointerType(analyser, size, sentinel, is_const, elem_ty);
2172+
return try Type.createPointerType(
2173+
analyser,
2174+
size,
2175+
sentinel,
2176+
is_const,
2177+
is_volatile,
2178+
is_allowzero,
2179+
alignment,
2180+
.generic,
2181+
elem_ty,
2182+
);
21662183
},
21672184
.array_type,
21682185
.array_type_sentinel,
@@ -2971,7 +2988,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error
29712988
elem_ty = try elem_ty.instanceUnchecked(analyser);
29722989
elem_ty = try analyser.resolveArrayMult(elem_ty, mult_lit) orelse return null;
29732990
elem_ty = try elem_ty.typeOf(analyser);
2974-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, elem_ty);
2991+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, false, false, 0, .generic, elem_ty);
29752992
return try pointer_ty.instanceUnchecked(analyser);
29762993
}
29772994

@@ -2993,7 +3010,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error
29933010
r_elem_ty = try r_elem_ty.instanceUnchecked(analyser);
29943011
var elem_ty = try analyser.resolveArrayCat(l_elem_ty, r_elem_ty) orelse return null;
29953012
elem_ty = try elem_ty.typeOf(analyser);
2996-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, elem_ty);
3013+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, false, false, 0, .generic, elem_ty);
29973014
return try pointer_ty.instanceUnchecked(analyser);
29983015
}
29993016

@@ -3198,6 +3215,11 @@ pub const Type = struct {
31983215
/// `.none` means no sentinel, `.unknown_unknown` means unknown sentinel
31993216
sentinel: InternPool.Index,
32003217
is_const: bool,
3218+
is_volatile: bool = false,
3219+
is_allowzero: bool = false,
3220+
/// `0` means default alignment.
3221+
alignment: u16 = 0,
3222+
address_space: std.builtin.AddressSpace = .generic,
32013223
elem_ty: *Type,
32023224
},
32033225

@@ -3304,6 +3326,10 @@ pub const Type = struct {
33043326
size: std.builtin.Type.Pointer.Size,
33053327
sentinel: InternPool.Index,
33063328
is_const: bool,
3329+
is_volatile: bool,
3330+
is_allowzero: bool,
3331+
alignment: u16,
3332+
address_space: std.builtin.AddressSpace,
33073333
elem_ty: Type,
33083334
) !Data {
33093335
std.debug.assert(elem_ty.is_type_val);
@@ -3316,6 +3342,10 @@ pub const Type = struct {
33163342
.flags = .{
33173343
.size = size,
33183344
.is_const = is_const,
3345+
.is_volatile = is_volatile,
3346+
.is_allowzero = is_allowzero,
3347+
.alignment = alignment,
3348+
.address_space = address_space,
33193349
},
33203350
},
33213351
});
@@ -3326,6 +3356,10 @@ pub const Type = struct {
33263356
.size = size,
33273357
.sentinel = sentinel,
33283358
.is_const = is_const,
3359+
.is_volatile = is_volatile,
3360+
.is_allowzero = is_allowzero,
3361+
.alignment = alignment,
3362+
.address_space = address_space,
33293363
.elem_ty = try analyser.allocType(elem_ty),
33303364
},
33313365
};
@@ -3680,11 +3714,18 @@ pub const Type = struct {
36803714
return t.data.resolveGeneric(analyser, bound_params, visiting);
36813715
},
36823716
.pointer => |info| {
3683-
const size = info.size;
3684-
const sentinel = info.sentinel;
3685-
const is_const = info.is_const;
36863717
const elem_ty = try analyser.resolveGenericTypeInternal(info.elem_ty.*, bound_params, visiting);
3687-
return try createPointer(analyser, size, sentinel, is_const, elem_ty);
3718+
return try createPointer(
3719+
analyser,
3720+
info.size,
3721+
info.sentinel,
3722+
info.is_const,
3723+
info.is_volatile,
3724+
info.is_allowzero,
3725+
info.alignment,
3726+
info.address_space,
3727+
elem_ty,
3728+
);
36883729
},
36893730
.array => |info| {
36903731
const elem_count = info.elem_count;
@@ -3783,10 +3824,24 @@ pub const Type = struct {
37833824
size: std.builtin.Type.Pointer.Size,
37843825
sentinel: InternPool.Index,
37853826
is_const: bool,
3827+
is_volatile: bool,
3828+
is_allowzero: bool,
3829+
alignment: u16,
3830+
address_space: std.builtin.AddressSpace,
37863831
elem_ty: Type,
37873832
) !Type {
37883833
return .{
3789-
.data = try Data.createPointer(analyser, size, sentinel, is_const, elem_ty),
3834+
.data = try Data.createPointer(
3835+
analyser,
3836+
size,
3837+
sentinel,
3838+
is_const,
3839+
is_volatile,
3840+
is_allowzero,
3841+
alignment,
3842+
address_space,
3843+
elem_ty,
3844+
),
37903845
.is_type_val = true,
37913846
};
37923847
}
@@ -4618,7 +4673,11 @@ pub const Type = struct {
46184673
},
46194674
.c => try writer.writeAll("[*c]"),
46204675
}
4676+
if (info.is_allowzero and info.size != .c) try writer.writeAll("allowzero ");
4677+
if (info.alignment != 0) try writer.print("align({d}) ", .{info.alignment});
4678+
if (info.address_space != .generic) try writer.print("addrspace(.{t}) ", .{info.address_space});
46214679
if (info.is_const) try writer.writeAll("const ");
4680+
if (info.is_volatile) try writer.writeAll("volatile ");
46224681
try info.elem_ty.rawStringify(writer, analyser, options);
46234682
},
46244683
.array => |info| {
@@ -4891,7 +4950,7 @@ fn resolveLangrefType(analyser: *Analyser, type_str: []const u8) Error!?Type {
48914950
elem_str = elem_str[6..];
48924951
const elem_instance = try analyser.resolveLangrefType(elem_str) orelse return null;
48934952
const elem_ty = try elem_instance.typeOf(analyser);
4894-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, elem_ty);
4953+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, false, false, 0, .generic, elem_ty);
48954954
return try pointer_ty.instanceUnchecked(analyser);
48964955
}
48974956

@@ -4927,7 +4986,7 @@ fn resolveLangrefType(analyser: *Analyser, type_str: []const u8) Error!?Type {
49274986
elem_str = elem_str[6..];
49284987
const elem_instance = try analyser.resolveLangrefType(elem_str) orelse return null;
49294988
const elem_ty = try elem_instance.typeOf(analyser);
4930-
const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, elem_ty);
4989+
const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, false, false, 0, .generic, elem_ty);
49314990
return try slice_ty.instanceUnchecked(analyser);
49324991
}
49334992

@@ -6037,7 +6096,7 @@ pub const DeclWithHandle = struct {
60376096
if (!self.isCaptureByRef()) return resolved_ty;
60386097

60396098
const elem_ty = try resolved_ty.typeOf(analyser);
6040-
const pointer_ty = try Type.createPointerType(analyser, .one, .none, false, elem_ty);
6099+
const pointer_ty = try Type.createPointerType(analyser, .one, .none, false, false, false, 0, .generic, elem_ty);
60416100
return try pointer_ty.instanceUnchecked(analyser);
60426101
}
60436102
};

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)