aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/type.zig')
-rw-r--r--src/type.zig45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/type.zig b/src/type.zig
index 2403893133..d9a641474f 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -2191,6 +2191,44 @@ pub const Type = extern union {
};
}
+ pub fn isPtrAtRuntime(self: Type) bool {
+ switch (self.tag()) {
+ .c_const_pointer,
+ .c_mut_pointer,
+ .many_const_pointer,
+ .many_mut_pointer,
+ .manyptr_const_u8,
+ .manyptr_u8,
+ .optional_single_const_pointer,
+ .optional_single_mut_pointer,
+ .single_const_pointer,
+ .single_const_pointer_to_comptime_int,
+ .single_mut_pointer,
+ => return true,
+
+ .pointer => switch (self.castTag(.pointer).?.data.size) {
+ .Slice => return false,
+ .One, .Many, .C => return true,
+ },
+
+ .optional => {
+ var buf: Payload.ElemType = undefined;
+ const child_type = self.optionalChild(&buf);
+ // optionals of zero sized pointers behave like bools
+ if (!child_type.hasCodeGenBits()) return false;
+ if (child_type.zigTypeTag() != .Pointer) return false;
+
+ const info = child_type.ptrInfo().data;
+ switch (info.size) {
+ .Slice, .C => return false,
+ .Many, .One => return !info.@"allowzero",
+ }
+ },
+
+ else => return false,
+ }
+ }
+
/// Asserts that the type is an optional
pub fn isPtrLikeOptional(self: Type) bool {
switch (self.tag()) {
@@ -2203,8 +2241,13 @@ pub const Type = extern union {
const child_type = self.optionalChild(&buf);
// optionals of zero sized pointers behave like bools
if (!child_type.hasCodeGenBits()) return false;
+ if (child_type.zigTypeTag() != .Pointer) return false;
- return child_type.zigTypeTag() == .Pointer and !child_type.isCPtr();
+ const info = child_type.ptrInfo().data;
+ switch (info.size) {
+ .Slice, .C => return false,
+ .Many, .One => return !info.@"allowzero",
+ }
},
else => unreachable,
}