-
-
Notifications
You must be signed in to change notification settings - Fork 430
preserve allowzero, align, volatile, and addrspace on pointer types #3172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -908,7 +908,7 @@ pub fn resolveOrelseType(analyser: *Analyser, lhs: Type, rhs: Type) error{OutOfM | |||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| pub fn resolveAddressOf(analyser: *Analyser, is_const: bool, ty: Type) error{OutOfMemory}!Type { | ||||||||||||||||||||||||
| const elem_ty = try ty.typeOf(analyser); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, elem_ty); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, false, false, 0, .generic, elem_ty); | ||||||||||||||||||||||||
| return try pointer_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -1231,12 +1231,12 @@ pub fn resolveBracketAccess(analyser: *Analyser, lhs_binding: Binding, rhs: Brac | |||||||||||||||||||||||
| switch (result) { | ||||||||||||||||||||||||
| .array => |elem_count| { | ||||||||||||||||||||||||
| const array_ty = try Type.createArrayType(analyser, elem_count, sentinel, elem_ty.*); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, array_ty); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, false, false, 0, .generic, array_ty); | ||||||||||||||||||||||||
| const pointer_instance = try pointer_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| return .{ .type = pointer_instance, .is_const = true }; | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| .slice => { | ||||||||||||||||||||||||
| const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, elem_ty.*); | ||||||||||||||||||||||||
| const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, false, false, 0, .generic, elem_ty.*); | ||||||||||||||||||||||||
| const slice_instance = try slice_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| return .{ .type = slice_instance, .is_const = true }; | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
|
|
@@ -2153,13 +2153,30 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error | |||||||||||||||||||||||
| const ptr_info = ast.fullPtrType(tree, node).?; | ||||||||||||||||||||||||
| const size = ptr_info.size; | ||||||||||||||||||||||||
| const is_const = ptr_info.const_token != null; | ||||||||||||||||||||||||
| const is_volatile = ptr_info.volatile_token != null; | ||||||||||||||||||||||||
| const is_allowzero = ptr_info.allowzero_token != null; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const sentinel = try analyser.resolveOptionalIPValue(ptr_info.ast.sentinel, handle); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const alignment: u16 = if (ptr_info.ast.align_node.unwrap()) |align_node| | ||||||||||||||||||||||||
| try analyser.resolveIntegerLiteral(u16, .of(align_node, handle)) orelse 0 | ||||||||||||||||||||||||
| else | ||||||||||||||||||||||||
| 0; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const elem_ty = try analyser.resolveTypeOfNodeInternal(.of(ptr_info.ast.child_type, handle)) orelse return null; | ||||||||||||||||||||||||
| if (!elem_ty.is_type_val) return null; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return try Type.createPointerType(analyser, size, sentinel, is_const, elem_ty); | ||||||||||||||||||||||||
| return try Type.createPointerType( | ||||||||||||||||||||||||
| analyser, | ||||||||||||||||||||||||
| size, | ||||||||||||||||||||||||
| sentinel, | ||||||||||||||||||||||||
| is_const, | ||||||||||||||||||||||||
| is_volatile, | ||||||||||||||||||||||||
| is_allowzero, | ||||||||||||||||||||||||
| alignment, | ||||||||||||||||||||||||
| .generic, | ||||||||||||||||||||||||
| elem_ty, | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| .array_type, | ||||||||||||||||||||||||
| .array_type_sentinel, | ||||||||||||||||||||||||
|
|
@@ -2957,7 +2974,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error | |||||||||||||||||||||||
| elem_ty = try elem_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| elem_ty = try analyser.resolveArrayMult(elem_ty, mult_lit) orelse return null; | ||||||||||||||||||||||||
| elem_ty = try elem_ty.typeOf(analyser); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, elem_ty); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, false, false, 0, .generic, elem_ty); | ||||||||||||||||||||||||
| return try pointer_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -2979,7 +2996,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error | |||||||||||||||||||||||
| r_elem_ty = try r_elem_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| var elem_ty = try analyser.resolveArrayCat(l_elem_ty, r_elem_ty) orelse return null; | ||||||||||||||||||||||||
| elem_ty = try elem_ty.typeOf(analyser); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, elem_ty); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, true, false, false, 0, .generic, elem_ty); | ||||||||||||||||||||||||
| return try pointer_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -3184,6 +3201,11 @@ pub const Type = struct { | |||||||||||||||||||||||
| /// `.none` means no sentinel, `.unknown_unknown` means unknown sentinel | ||||||||||||||||||||||||
| sentinel: InternPool.Index, | ||||||||||||||||||||||||
| is_const: bool, | ||||||||||||||||||||||||
| is_volatile: bool = false, | ||||||||||||||||||||||||
| is_allowzero: bool = false, | ||||||||||||||||||||||||
| /// `0` means default alignment. | ||||||||||||||||||||||||
| alignment: u16 = 0, | ||||||||||||||||||||||||
| address_space: std.builtin.AddressSpace = .generic, | ||||||||||||||||||||||||
| elem_ty: *Type, | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -3290,6 +3312,10 @@ pub const Type = struct { | |||||||||||||||||||||||
| size: std.builtin.Type.Pointer.Size, | ||||||||||||||||||||||||
| sentinel: InternPool.Index, | ||||||||||||||||||||||||
| is_const: bool, | ||||||||||||||||||||||||
| is_volatile: bool, | ||||||||||||||||||||||||
| is_allowzero: bool, | ||||||||||||||||||||||||
| alignment: u16, | ||||||||||||||||||||||||
| address_space: std.builtin.AddressSpace, | ||||||||||||||||||||||||
| elem_ty: Type, | ||||||||||||||||||||||||
|
Comment on lines
3312
to
3319
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already have a type that can store most pointer attributes. So the number of function parameters can be reduced here:
Suggested change
|
||||||||||||||||||||||||
| ) !Data { | ||||||||||||||||||||||||
| std.debug.assert(elem_ty.is_type_val); | ||||||||||||||||||||||||
|
|
@@ -3302,6 +3328,10 @@ pub const Type = struct { | |||||||||||||||||||||||
| .flags = .{ | ||||||||||||||||||||||||
| .size = size, | ||||||||||||||||||||||||
| .is_const = is_const, | ||||||||||||||||||||||||
| .is_volatile = is_volatile, | ||||||||||||||||||||||||
| .is_allowzero = is_allowzero, | ||||||||||||||||||||||||
| .alignment = alignment, | ||||||||||||||||||||||||
| .address_space = address_space, | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
|
|
@@ -3312,6 +3342,10 @@ pub const Type = struct { | |||||||||||||||||||||||
| .size = size, | ||||||||||||||||||||||||
| .sentinel = sentinel, | ||||||||||||||||||||||||
| .is_const = is_const, | ||||||||||||||||||||||||
| .is_volatile = is_volatile, | ||||||||||||||||||||||||
| .is_allowzero = is_allowzero, | ||||||||||||||||||||||||
| .alignment = alignment, | ||||||||||||||||||||||||
| .address_space = address_space, | ||||||||||||||||||||||||
| .elem_ty = try analyser.allocType(elem_ty), | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
@@ -3666,11 +3700,18 @@ pub const Type = struct { | |||||||||||||||||||||||
| return t.data.resolveGeneric(analyser, bound_params, visiting); | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| .pointer => |info| { | ||||||||||||||||||||||||
| const size = info.size; | ||||||||||||||||||||||||
| const sentinel = info.sentinel; | ||||||||||||||||||||||||
| const is_const = info.is_const; | ||||||||||||||||||||||||
| const elem_ty = try analyser.resolveGenericTypeInternal(info.elem_ty.*, bound_params, visiting); | ||||||||||||||||||||||||
| return try createPointer(analyser, size, sentinel, is_const, elem_ty); | ||||||||||||||||||||||||
| return try createPointer( | ||||||||||||||||||||||||
| analyser, | ||||||||||||||||||||||||
| info.size, | ||||||||||||||||||||||||
| info.sentinel, | ||||||||||||||||||||||||
| info.is_const, | ||||||||||||||||||||||||
| info.is_volatile, | ||||||||||||||||||||||||
| info.is_allowzero, | ||||||||||||||||||||||||
| info.alignment, | ||||||||||||||||||||||||
| info.address_space, | ||||||||||||||||||||||||
| elem_ty, | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| .array => |info| { | ||||||||||||||||||||||||
| const elem_count = info.elem_count; | ||||||||||||||||||||||||
|
|
@@ -3769,10 +3810,24 @@ pub const Type = struct { | |||||||||||||||||||||||
| size: std.builtin.Type.Pointer.Size, | ||||||||||||||||||||||||
| sentinel: InternPool.Index, | ||||||||||||||||||||||||
| is_const: bool, | ||||||||||||||||||||||||
| is_volatile: bool, | ||||||||||||||||||||||||
| is_allowzero: bool, | ||||||||||||||||||||||||
| alignment: u16, | ||||||||||||||||||||||||
| address_space: std.builtin.AddressSpace, | ||||||||||||||||||||||||
| elem_ty: Type, | ||||||||||||||||||||||||
|
Comment on lines
3810
to
3817
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already have a type that can store most pointer attributes. So the number of function parameters can be reduced here:
Suggested change
|
||||||||||||||||||||||||
| ) !Type { | ||||||||||||||||||||||||
| return .{ | ||||||||||||||||||||||||
| .data = try Data.createPointer(analyser, size, sentinel, is_const, elem_ty), | ||||||||||||||||||||||||
| .data = try Data.createPointer( | ||||||||||||||||||||||||
| analyser, | ||||||||||||||||||||||||
| size, | ||||||||||||||||||||||||
| sentinel, | ||||||||||||||||||||||||
| is_const, | ||||||||||||||||||||||||
| is_volatile, | ||||||||||||||||||||||||
| is_allowzero, | ||||||||||||||||||||||||
| alignment, | ||||||||||||||||||||||||
| address_space, | ||||||||||||||||||||||||
| elem_ty, | ||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||
| .is_type_val = true, | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
@@ -4605,7 +4660,11 @@ pub const Type = struct { | |||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| .c => try writer.writeAll("[*c]"), | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| if (info.is_allowzero and info.size != .c) try writer.writeAll("allowzero "); | ||||||||||||||||||||||||
| if (info.alignment != 0) try writer.print("align({d}) ", .{info.alignment}); | ||||||||||||||||||||||||
| if (info.address_space != .generic) try writer.print("addrspace(.{t}) ", .{info.address_space}); | ||||||||||||||||||||||||
| if (info.is_const) try writer.writeAll("const "); | ||||||||||||||||||||||||
| if (info.is_volatile) try writer.writeAll("volatile "); | ||||||||||||||||||||||||
| try info.elem_ty.rawStringify(writer, analyser, options); | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| .array => |info| { | ||||||||||||||||||||||||
|
|
@@ -4878,7 +4937,7 @@ fn resolveLangrefType(analyser: *Analyser, type_str: []const u8) Error!?Type { | |||||||||||||||||||||||
| elem_str = elem_str[6..]; | ||||||||||||||||||||||||
| const elem_instance = try analyser.resolveLangrefType(elem_str) orelse return null; | ||||||||||||||||||||||||
| const elem_ty = try elem_instance.typeOf(analyser); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, elem_ty); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, is_const, false, false, 0, .generic, elem_ty); | ||||||||||||||||||||||||
| return try pointer_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -4914,7 +4973,7 @@ fn resolveLangrefType(analyser: *Analyser, type_str: []const u8) Error!?Type { | |||||||||||||||||||||||
| elem_str = elem_str[6..]; | ||||||||||||||||||||||||
| const elem_instance = try analyser.resolveLangrefType(elem_str) orelse return null; | ||||||||||||||||||||||||
| const elem_ty = try elem_instance.typeOf(analyser); | ||||||||||||||||||||||||
| const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, elem_ty); | ||||||||||||||||||||||||
| const slice_ty = try Type.createPointerType(analyser, .slice, sentinel, is_const, false, false, 0, .generic, elem_ty); | ||||||||||||||||||||||||
| return try slice_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
|
|
@@ -6018,7 +6077,7 @@ pub const DeclWithHandle = struct { | |||||||||||||||||||||||
| if (!self.isCaptureByRef()) return resolved_ty; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const elem_ty = try resolved_ty.typeOf(analyser); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, false, elem_ty); | ||||||||||||||||||||||||
| const pointer_ty = try Type.createPointerType(analyser, .one, .none, false, false, false, 0, .generic, elem_ty); | ||||||||||||||||||||||||
| return try pointer_ty.instanceUnchecked(analyser); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -286,6 +286,33 @@ test "var decl" { | |
| , .{ .kind = .Type }); | ||
| } | ||
|
|
||
| test "var decl - pointer modifiers" { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These tests shouldn't need to go through inlay hints. Instead, add new tests to Example: diff --git a/tests/analysis/pointer.zig b/tests/analysis/pointer.zig
index 4086f8d4..5aa7acab 100644
--- a/tests/analysis/pointer.zig
+++ b/tests/analysis/pointer.zig
@@ -270,6 +270,9 @@ const ManyPointerWithSentinel = [*:.{}]addrspace(.generic) const packed struct {
// ^ (packed struct {})()
// ^^^^^^^^ (AddressSpace)()
+const VolatilePointer = *volatile u32;
+// ^^^^^^^^^^^^^^^ (type)(*volatile u32)
+
var runtime_index: usize = 5;
var runtime_u8: u8 = 1;
var runtime_i8: i8 = -1;
|
||
| try testInlayHints( | ||
| \\const a: *u8 = undefined; | ||
| \\const b<*u8> = a; | ||
| , .{ .kind = .Type }); | ||
| try testInlayHints( | ||
| \\const a: *allowzero u8 = undefined; | ||
| \\const b<*allowzero u8> = a; | ||
| , .{ .kind = .Type }); | ||
| try testInlayHints( | ||
| \\const a: *align(4) u8 = undefined; | ||
| \\const b<*align(4) u8> = a; | ||
| , .{ .kind = .Type }); | ||
| try testInlayHints( | ||
| \\const a: *volatile u8 = undefined; | ||
| \\const b<*volatile u8> = a; | ||
| , .{ .kind = .Type }); | ||
| try testInlayHints( | ||
| \\const a: *allowzero align(8) const volatile u8 = undefined; | ||
| \\const b<*allowzero align(8) const volatile u8> = a; | ||
| , .{ .kind = .Type }); | ||
| try testInlayHints( | ||
| \\const a: [*]allowzero u8 = undefined; | ||
| \\const b<[*]allowzero u8> = a; | ||
| , .{ .kind = .Type }); | ||
| } | ||
|
|
||
| test "comptime return types" { | ||
| try testInlayHints( | ||
| \\fn Box(comptime T: type) type { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have a type that can store most pointer attributes.