aboutsummaryrefslogtreecommitdiff
path: root/src/value.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-04-06 17:43:56 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-04-06 18:17:37 -0700
commitb40d36c90ba894a12f2de4e6c881642edffad3ed (patch)
tree79bf2079c932adda3a904dcc2b1ac28a9d13acb2 /src/value.zig
parentec212c82bef3cbf01517eece67a8599348c7ac86 (diff)
downloadzig-b40d36c90ba894a12f2de4e6c881642edffad3ed.tar.gz
zig-b40d36c90ba894a12f2de4e6c881642edffad3ed.zip
stage2: implement simple enums
A simple enum is an enum which has an automatic integer tag type, all tag values automatically assigned, and no top level declarations. Such enums are created directly in AstGen and shared by all the generic/comptime instantiations of the surrounding ZIR code. This commit implements, but does not yet add any test cases for, simple enums. A full enum is an enum for which any of the above conditions are not true. Full enums are created in Sema, and therefore will create a unique type per generic/comptime instantiation. This commit does not implement full enums. However the `enum_decl_nonexhaustive` ZIR instruction is added and the respective Type functions are filled out. This commit makes an improvement to ZIR code, removing the decls array and removing the decl_map from AstGen. Instead, decl_ref and decl_val ZIR instructions index into the `owner_decl.dependencies` ArrayHashMap. We already need this dependencies array for incremental compilation purposes, and so repurposing it to also use it for ZIR decl indexes makes for efficient memory usage. Similarly, this commit fixes up incorrect memory management by removing the `const` ZIR instruction. The two places it was used stored memory in the AstGen arena, which may get freed after Sema. Now it properly sets up a new anonymous Decl for error sets and uses a normal decl_val instruction. The other usage of `const` ZIR instruction was float literals. These are now changed to use `float` ZIR instruction when the value fits inside `zir.Inst.Data` and `float128` otherwise. AstGen + Sema: implement int_to_enum and enum_to_int. No tests yet; I expect to have to make some fixes before they will pass tests. Will do that in the branch before merging. AstGen: fix struct astgen incorrectly counting decls as fields. Type/Value: give up on trying to exhaustively list every tag all the time. This makes the file more manageable. Also found a bug with i128/u128 this way, since the name of the function was more obvious when looking at the tag values. Type: implement abiAlignment and abiSize for structs. This will need to get more sophisticated at some point, but for now it is progress. Value: add new `enum_field_index` tag. Value: add hash_u32, needed when using ArrayHashMap.
Diffstat (limited to 'src/value.zig')
-rw-r--r--src/value.zig837
1 files changed, 57 insertions, 780 deletions
diff --git a/src/value.zig b/src/value.zig
index 4170b005bf..66a23692c1 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -103,6 +103,8 @@ pub const Value = extern union {
float_64,
float_128,
enum_literal,
+ /// A specific enum tag, indicated by the field index (declaration order).
+ enum_field_index,
@"error",
error_union,
/// This is a special value that tracks a set of types that have been stored
@@ -186,6 +188,8 @@ pub const Value = extern union {
.enum_literal,
=> Payload.Bytes,
+ .enum_field_index => Payload.U32,
+
.ty => Payload.Ty,
.int_type => Payload.IntType,
.int_u64 => Payload.U64,
@@ -394,6 +398,7 @@ pub const Value = extern union {
};
return Value{ .ptr_otherwise = &new_payload.base };
},
+ .enum_field_index => return self.copyPayloadShallow(allocator, Payload.U32),
.@"error" => return self.copyPayloadShallow(allocator, Payload.Error),
.error_union => {
const payload = self.castTag(.error_union).?;
@@ -416,6 +421,8 @@ pub const Value = extern union {
return Value{ .ptr_otherwise = &new_payload.base };
}
+ /// TODO this should become a debug dump() function. In order to print values in a meaningful way
+ /// we also need access to the type.
pub fn format(
self: Value,
comptime fmt: []const u8,
@@ -506,6 +513,7 @@ pub const Value = extern union {
},
.empty_array => return out_stream.writeAll(".{}"),
.enum_literal => return out_stream.print(".{}", .{std.zig.fmtId(self.castTag(.enum_literal).?.data)}),
+ .enum_field_index => return out_stream.print("(enum field {d})", .{self.castTag(.enum_field_index).?.data}),
.bytes => return out_stream.print("\"{}\"", .{std.zig.fmtEscapes(self.castTag(.bytes).?.data)}),
.repeated => {
try out_stream.writeAll("(repeated) ");
@@ -626,6 +634,7 @@ pub const Value = extern union {
.float_64,
.float_128,
.enum_literal,
+ .enum_field_index,
.@"error",
.error_union,
.empty_struct_value,
@@ -638,76 +647,6 @@ pub const Value = extern union {
/// Asserts the value is an integer.
pub fn toBigInt(self: Value, space: *BigIntSpace) BigIntConst {
switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .null_value,
- .function,
- .extern_fn,
- .variable,
- .ref_val,
- .decl_ref,
- .elem_ptr,
- .bytes,
- .repeated,
- .float_16,
- .float_32,
- .float_64,
- .float_128,
- .void_value,
- .unreachable_value,
- .empty_array,
- .enum_literal,
- .error_union,
- .@"error",
- .empty_struct_value,
- .inferred_alloc,
- .abi_align_default,
- => unreachable,
-
- .undef => unreachable,
-
.zero,
.bool_false,
=> return BigIntMutable.init(&space.limbs, 0).toConst(),
@@ -720,82 +659,15 @@ pub const Value = extern union {
.int_i64 => return BigIntMutable.init(&space.limbs, self.castTag(.int_i64).?.data).toConst(),
.int_big_positive => return self.castTag(.int_big_positive).?.asBigInt(),
.int_big_negative => return self.castTag(.int_big_negative).?.asBigInt(),
+
+ .undef => unreachable,
+ else => unreachable,
}
}
/// Asserts the value is an integer and it fits in a u64
pub fn toUnsignedInt(self: Value) u64 {
switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .null_value,
- .function,
- .extern_fn,
- .variable,
- .ref_val,
- .decl_ref,
- .elem_ptr,
- .bytes,
- .repeated,
- .float_16,
- .float_32,
- .float_64,
- .float_128,
- .void_value,
- .unreachable_value,
- .empty_array,
- .enum_literal,
- .@"error",
- .error_union,
- .empty_struct_value,
- .inferred_alloc,
- .abi_align_default,
- => unreachable,
-
- .undef => unreachable,
-
.zero,
.bool_false,
=> return 0,
@@ -808,82 +680,15 @@ pub const Value = extern union {
.int_i64 => return @intCast(u64, self.castTag(.int_i64).?.data),
.int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().to(u64) catch unreachable,
.int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().to(u64) catch unreachable,
+
+ .undef => unreachable,
+ else => unreachable,
}
}
/// Asserts the value is an integer and it fits in a i64
pub fn toSignedInt(self: Value) i64 {
switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .null_value,
- .function,
- .extern_fn,
- .variable,
- .ref_val,
- .decl_ref,
- .elem_ptr,
- .bytes,
- .repeated,
- .float_16,
- .float_32,
- .float_64,
- .float_128,
- .void_value,
- .unreachable_value,
- .empty_array,
- .enum_literal,
- .@"error",
- .error_union,
- .empty_struct_value,
- .inferred_alloc,
- .abi_align_default,
- => unreachable,
-
- .undef => unreachable,
-
.zero,
.bool_false,
=> return 0,
@@ -896,6 +701,9 @@ pub const Value = extern union {
.int_i64 => return self.castTag(.int_i64).?.data,
.int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().to(i64) catch unreachable,
.int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().to(i64) catch unreachable,
+
+ .undef => unreachable,
+ else => unreachable,
}
}
@@ -929,75 +737,6 @@ pub const Value = extern union {
/// Returns the number of bits the value requires to represent stored in twos complement form.
pub fn intBitCountTwosComp(self: Value) usize {
switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .null_value,
- .function,
- .extern_fn,
- .variable,
- .ref_val,
- .decl_ref,
- .elem_ptr,
- .bytes,
- .undef,
- .repeated,
- .float_16,
- .float_32,
- .float_64,
- .float_128,
- .void_value,
- .unreachable_value,
- .empty_array,
- .enum_literal,
- .@"error",
- .error_union,
- .empty_struct_value,
- .inferred_alloc,
- .abi_align_default,
- => unreachable,
-
.zero,
.bool_false,
=> return 0,
@@ -1016,80 +755,14 @@ pub const Value = extern union {
},
.int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().bitCountTwosComp(),
.int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().bitCountTwosComp(),
+
+ else => unreachable,
}
}
/// Asserts the value is an integer, and the destination type is ComptimeInt or Int.
pub fn intFitsInType(self: Value, ty: Type, target: Target) bool {
switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .null_value,
- .function,
- .extern_fn,
- .variable,
- .ref_val,
- .decl_ref,
- .elem_ptr,
- .bytes,
- .repeated,
- .float_16,
- .float_32,
- .float_64,
- .float_128,
- .void_value,
- .unreachable_value,
- .empty_array,
- .enum_literal,
- .@"error",
- .error_union,
- .empty_struct_value,
- .inferred_alloc,
- .abi_align_default,
- => unreachable,
-
.zero,
.undef,
.bool_false,
@@ -1144,6 +817,8 @@ pub const Value = extern union {
.ComptimeInt => return true,
else => unreachable,
},
+
+ else => unreachable,
}
}
@@ -1180,77 +855,6 @@ pub const Value = extern union {
/// Asserts the value is a float
pub fn floatHasFraction(self: Value) bool {
return switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .bool_true,
- .bool_false,
- .null_value,
- .function,
- .extern_fn,
- .variable,
- .ref_val,
- .decl_ref,
- .elem_ptr,
- .bytes,
- .repeated,
- .undef,
- .int_u64,
- .int_i64,
- .int_big_positive,
- .int_big_negative,
- .empty_array,
- .void_value,
- .unreachable_value,
- .enum_literal,
- .@"error",
- .error_union,
- .empty_struct_value,
- .inferred_alloc,
- .abi_align_default,
- => unreachable,
-
.zero,
.one,
=> false,
@@ -1260,76 +864,13 @@ pub const Value = extern union {
.float_64 => @rem(self.castTag(.float_64).?.data, 1) != 0,
// .float_128 => @rem(self.castTag(.float_128).?.data, 1) != 0,
.float_128 => @panic("TODO lld: error: undefined symbol: fmodl"),
+
+ else => unreachable,
};
}
pub fn orderAgainstZero(lhs: Value) std.math.Order {
return switch (lhs.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .null_value,
- .function,
- .extern_fn,
- .variable,
- .ref_val,
- .decl_ref,
- .elem_ptr,
- .bytes,
- .repeated,
- .undef,
- .void_value,
- .unreachable_value,
- .empty_array,
- .enum_literal,
- .@"error",
- .error_union,
- .empty_struct_value,
- .inferred_alloc,
- .abi_align_default,
- => unreachable,
-
.zero,
.bool_false,
=> .eq,
@@ -1347,6 +888,8 @@ pub const Value = extern union {
.float_32 => std.math.order(lhs.castTag(.float_32).?.data, 0),
.float_64 => std.math.order(lhs.castTag(.float_64).?.data, 0),
.float_128 => std.math.order(lhs.castTag(.float_128).?.data, 0),
+
+ else => unreachable,
};
}
@@ -1396,10 +939,12 @@ pub const Value = extern union {
}
pub fn eql(a: Value, b: Value) bool {
- if (a.tag() == b.tag()) {
- if (a.tag() == .void_value or a.tag() == .null_value) {
+ const a_tag = a.tag();
+ const b_tag = b.tag();
+ if (a_tag == b_tag) {
+ if (a_tag == .void_value or a_tag == .null_value) {
return true;
- } else if (a.tag() == .enum_literal) {
+ } else if (a_tag == .enum_literal) {
const a_name = a.castTag(.enum_literal).?.data;
const b_name = b.castTag(.enum_literal).?.data;
return std.mem.eql(u8, a_name, b_name);
@@ -1416,6 +961,10 @@ pub const Value = extern union {
return compare(a, .eq, b);
}
+ pub fn hash_u32(self: Value) u32 {
+ return @truncate(u32, self.hash());
+ }
+
pub fn hash(self: Value) u64 {
var hasher = std.hash.Wyhash.init(0);
@@ -1493,11 +1042,18 @@ pub const Value = extern union {
.zero, .bool_false => std.hash.autoHash(&hasher, @as(u64, 0)),
.one, .bool_true => std.hash.autoHash(&hasher, @as(u64, 1)),
- .float_16, .float_32, .float_64, .float_128 => {},
+ .float_16, .float_32, .float_64, .float_128 => {
+ @panic("TODO implement Value.hash for floats");
+ },
+
.enum_literal => {
const payload = self.castTag(.enum_literal).?;
hasher.update(payload.data);
},
+ .enum_field_index => {
+ const payload = self.castTag(.enum_field_index).?;
+ std.hash.autoHash(&hasher, payload.data);
+ },
.bytes => {
const payload = self.castTag(.bytes).?;
hasher.update(payload.data);
@@ -1573,80 +1129,6 @@ pub const Value = extern union {
/// Returns error.AnalysisFail if the pointer points to a Decl that failed semantic analysis.
pub fn pointerDeref(self: Value, allocator: *Allocator) error{ AnalysisFail, OutOfMemory }!Value {
return switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .zero,
- .one,
- .bool_true,
- .bool_false,
- .null_value,
- .function,
- .extern_fn,
- .variable,
- .int_u64,
- .int_i64,
- .int_big_positive,
- .int_big_negative,
- .bytes,
- .undef,
- .repeated,
- .float_16,
- .float_32,
- .float_64,
- .float_128,
- .void_value,
- .unreachable_value,
- .empty_array,
- .enum_literal,
- .@"error",
- .error_union,
- .empty_struct_value,
- .inferred_alloc,
- .abi_align_default,
- => unreachable,
-
.ref_val => self.castTag(.ref_val).?.data,
.decl_ref => self.castTag(.decl_ref).?.data.value(),
.elem_ptr => {
@@ -1654,6 +1136,8 @@ pub const Value = extern union {
const array_val = try elem_ptr.array_ptr.pointerDeref(allocator);
return array_val.elemValue(allocator, elem_ptr.index);
},
+
+ else => unreachable,
};
}
@@ -1661,86 +1145,14 @@ pub const Value = extern union {
/// or an unknown-length pointer, and returns the element value at the index.
pub fn elemValue(self: Value, allocator: *Allocator, index: usize) error{OutOfMemory}!Value {
switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .zero,
- .one,
- .bool_true,
- .bool_false,
- .null_value,
- .function,
- .extern_fn,
- .variable,
- .int_u64,
- .int_i64,
- .int_big_positive,
- .int_big_negative,
- .undef,
- .elem_ptr,
- .ref_val,
- .decl_ref,
- .float_16,
- .float_32,
- .float_64,
- .float_128,
- .void_value,
- .unreachable_value,
- .enum_literal,
- .@"error",
- .error_union,
- .empty_struct_value,
- .inferred_alloc,
- .abi_align_default,
- => unreachable,
-
.empty_array => unreachable, // out of bounds array index
.bytes => return Tag.int_u64.create(allocator, self.castTag(.bytes).?.data[index]),
// No matter the index; all the elements are the same!
.repeated => return self.castTag(.repeated).?.data,
+
+ else => unreachable,
}
}
@@ -1766,161 +1178,18 @@ pub const Value = extern union {
/// Valid for all types. Asserts the value is not undefined and not unreachable.
pub fn isNull(self: Value) bool {
return switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .zero,
- .one,
- .empty_array,
- .bool_true,
- .bool_false,
- .function,
- .extern_fn,
- .variable,
- .int_u64,
- .int_i64,
- .int_big_positive,
- .int_big_negative,
- .ref_val,
- .decl_ref,
- .elem_ptr,
- .bytes,
- .repeated,
- .float_16,
- .float_32,
- .float_64,
- .float_128,
- .void_value,
- .enum_literal,
- .@"error",
- .error_union,
- .empty_struct_value,
- .abi_align_default,
- => false,
-
.undef => unreachable,
.unreachable_value => unreachable,
.inferred_alloc => unreachable,
.null_value => true,
+
+ else => false,
};
}
/// Valid for all types. Asserts the value is not undefined and not unreachable.
pub fn getError(self: Value) ?[]const u8 {
return switch (self.tag()) {
- .ty,
- .int_type,
- .u8_type,
- .i8_type,
- .u16_type,
- .i16_type,
- .u32_type,
- .i32_type,
- .u64_type,
- .i64_type,
- .u128_type,
- .i128_type,
- .usize_type,
- .isize_type,
- .c_short_type,
- .c_ushort_type,
- .c_int_type,
- .c_uint_type,
- .c_long_type,
- .c_ulong_type,
- .c_longlong_type,
- .c_ulonglong_type,
- .c_longdouble_type,
- .f16_type,
- .f32_type,
- .f64_type,
- .f128_type,
- .c_void_type,
- .bool_type,
- .void_type,
- .type_type,
- .anyerror_type,
- .comptime_int_type,
- .comptime_float_type,
- .noreturn_type,
- .null_type,
- .undefined_type,
- .fn_noreturn_no_args_type,
- .fn_void_no_args_type,
- .fn_naked_noreturn_no_args_type,
- .fn_ccc_void_no_args_type,
- .single_const_pointer_to_comptime_int_type,
- .const_slice_u8_type,
- .enum_literal_type,
- .zero,
- .one,
- .null_value,
- .empty_array,
- .bool_true,
- .bool_false,
- .function,
- .extern_fn,
- .variable,
- .int_u64,
- .int_i64,
- .int_big_positive,
- .int_big_negative,
- .ref_val,
- .decl_ref,
- .elem_ptr,
- .bytes,
- .repeated,
- .float_16,
- .float_32,
- .float_64,
- .float_128,
- .void_value,
- .enum_literal,
- .empty_struct_value,
- .abi_align_default,
- => null,
-
.error_union => {
const data = self.castTag(.error_union).?.data;
return if (data.tag() == .@"error")
@@ -1932,6 +1201,8 @@ pub const Value = extern union {
.undef => unreachable,
.unreachable_value => unreachable,
.inferred_alloc => unreachable,
+
+ else => null,
};
}
/// Valid for all types. Asserts the value is not undefined.
@@ -2021,6 +1292,7 @@ pub const Value = extern union {
.float_128,
.void_value,
.enum_literal,
+ .enum_field_index,
.@"error",
.error_union,
.empty_struct_value,
@@ -2038,6 +1310,11 @@ pub const Value = extern union {
pub const Payload = struct {
tag: Tag,
+ pub const U32 = struct {
+ base: Payload,
+ data: u32,
+ };
+
pub const U64 = struct {
base: Payload,
data: u64,