aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/type.zig')
-rw-r--r--src/type.zig82
1 files changed, 79 insertions, 3 deletions
diff --git a/src/type.zig b/src/type.zig
index 853a4b7914..f9385e90bc 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -58,7 +58,7 @@ pub const Type = extern union {
.bool => return .Bool,
.void => return .Void,
.type => return .Type,
- .error_set, .error_set_single, .anyerror => return .ErrorSet,
+ .error_set, .error_set_single, .anyerror, .error_set_inferred => return .ErrorSet,
.comptime_int => return .ComptimeInt,
.comptime_float => return .ComptimeFloat,
.noreturn => return .NoReturn,
@@ -689,7 +689,15 @@ pub const Type = extern union {
.optional_single_mut_pointer,
.optional_single_const_pointer,
.anyframe_T,
- => return self.copyPayloadShallow(allocator, Payload.ElemType),
+ => {
+ const payload = self.cast(Payload.ElemType).?;
+ const new_payload = try allocator.create(Payload.ElemType);
+ new_payload.* = .{
+ .base = .{ .tag = payload.base.tag },
+ .data = try payload.data.copy(allocator),
+ };
+ return Type{ .ptr_otherwise = &new_payload.base };
+ },
.int_signed,
.int_unsigned,
@@ -756,6 +764,7 @@ pub const Type = extern union {
});
},
.error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),
+ .error_set_inferred => return self.copyPayloadShallow(allocator, Payload.ErrorSetInferred),
.error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),
.empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope),
.@"struct" => return self.copyPayloadShallow(allocator, Payload.Struct),
@@ -1031,6 +1040,10 @@ pub const Type = extern union {
const error_set = ty.castTag(.error_set).?.data;
return writer.writeAll(std.mem.spanZ(error_set.owner_decl.name));
},
+ .error_set_inferred => {
+ const func = ty.castTag(.error_set_inferred).?.data;
+ return writer.print("(inferred error set of {s})", .{func.owner_decl.name});
+ },
.error_set_single => {
const name = ty.castTag(.error_set_single).?.data;
return writer.print("error{{{s}}}", .{name});
@@ -1144,6 +1157,7 @@ pub const Type = extern union {
.anyerror_void_error_union,
.error_set,
.error_set_single,
+ .error_set_inferred,
.manyptr_u8,
.manyptr_const_u8,
.atomic_ordering,
@@ -1161,6 +1175,9 @@ pub const Type = extern union {
.@"struct" => {
// TODO introduce lazy value mechanism
const struct_obj = self.castTag(.@"struct").?.data;
+ assert(struct_obj.status == .have_field_types or
+ struct_obj.status == .layout_wip or
+ struct_obj.status == .have_layout);
for (struct_obj.fields.values()) |value| {
if (value.ty.hasCodeGenBits())
return true;
@@ -1348,6 +1365,7 @@ pub const Type = extern union {
.error_set_single,
.anyerror_void_error_union,
.anyerror,
+ .error_set_inferred,
=> return 2, // TODO revisit this when we have the concept of the error tag type
.array, .array_sentinel => return self.elemType().abiAlignment(target),
@@ -1580,6 +1598,7 @@ pub const Type = extern union {
.error_set_single,
.anyerror_void_error_union,
.anyerror,
+ .error_set_inferred,
=> return 2, // TODO revisit this when we have the concept of the error tag type
.int_signed, .int_unsigned => {
@@ -1744,6 +1763,7 @@ pub const Type = extern union {
.error_set_single,
.anyerror_void_error_union,
.anyerror,
+ .error_set_inferred,
=> return 16, // TODO revisit this when we have the concept of the error tag type
.int_signed, .int_unsigned => self.cast(Payload.Bits).?.data,
@@ -1863,6 +1883,48 @@ pub const Type = extern union {
};
}
+ pub fn slicePtrFieldType(self: Type, buffer: *Payload.ElemType) Type {
+ switch (self.tag()) {
+ .const_slice_u8 => return Type.initTag(.manyptr_const_u8),
+
+ .const_slice => {
+ const elem_type = self.castTag(.const_slice).?.data;
+ buffer.* = .{
+ .base = .{ .tag = .many_const_pointer },
+ .data = elem_type,
+ };
+ return Type.initPayload(&buffer.base);
+ },
+ .mut_slice => {
+ const elem_type = self.castTag(.mut_slice).?.data;
+ buffer.* = .{
+ .base = .{ .tag = .many_mut_pointer },
+ .data = elem_type,
+ };
+ return Type.initPayload(&buffer.base);
+ },
+
+ .pointer => {
+ const payload = self.castTag(.pointer).?.data;
+ assert(payload.size == .Slice);
+ if (payload.mutable) {
+ buffer.* = .{
+ .base = .{ .tag = .many_mut_pointer },
+ .data = payload.pointee_type,
+ };
+ } else {
+ buffer.* = .{
+ .base = .{ .tag = .many_const_pointer },
+ .data = payload.pointee_type,
+ };
+ }
+ return Type.initPayload(&buffer.base);
+ },
+
+ else => unreachable,
+ }
+ }
+
pub fn isConstPtr(self: Type) bool {
return switch (self.tag()) {
.single_const_pointer,
@@ -1915,7 +1977,10 @@ pub const Type = extern union {
/// Asserts that the type is an optional
pub fn isPtrLikeOptional(self: Type) bool {
switch (self.tag()) {
- .optional_single_const_pointer, .optional_single_mut_pointer => return true,
+ .optional_single_const_pointer,
+ .optional_single_mut_pointer,
+ => return true,
+
.optional => {
var buf: Payload.ElemType = undefined;
const child_type = self.optionalChild(&buf);
@@ -2400,6 +2465,7 @@ pub const Type = extern union {
.error_union,
.error_set,
.error_set_single,
+ .error_set_inferred,
.@"opaque",
.var_args_param,
.manyptr_u8,
@@ -2892,6 +2958,8 @@ pub const Type = extern union {
anyframe_T,
error_set,
error_set_single,
+ /// The type is the inferred error set of a specific function.
+ error_set_inferred,
empty_struct,
@"opaque",
@"struct",
@@ -2989,6 +3057,7 @@ pub const Type = extern union {
=> Payload.Bits,
.error_set => Payload.ErrorSet,
+ .error_set_inferred => Payload.ErrorSetInferred,
.array, .vector => Payload.Array,
.array_sentinel => Payload.ArraySentinel,
@@ -3081,6 +3150,13 @@ pub const Type = extern union {
data: *Module.ErrorSet,
};
+ pub const ErrorSetInferred = struct {
+ pub const base_tag = Tag.error_set_inferred;
+
+ base: Payload = Payload{ .tag = base_tag },
+ data: *Module.Fn,
+ };
+
pub const Pointer = struct {
pub const base_tag = Tag.pointer;