zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 89a9cabafd745034871ea014b06bd3bad0505f4a (tree)
parent 0cc9d68b77b31c6502da80ce7e6dabaf9316ca48
Author: mlugg <mlugg@mlugg.co.uk>
Date:   Wed, 15 Jan 2025 16:57:04 +0000

std.builtin.Type: improve ergonomics of `*const anyopaque` fields

For representing struct field default values and array/pointer type
sentinel values, we use `*const anyopaque`, since there is no way for
`std.builtin.Type.StructField` etc to refer back to its `type` field.
However, when introspecting a type, this is quite awkward due to the
pointer casts necessary.

As such, this commit renames the `sentinel` fields to `sentinel_ptr`,
and the `default_value` field to `default_value_ptr`, and introduces
helper methods `sentinel()` and `defaultValue()` to load the values.
These methods are marked as `inline` because their return value, which
is always comptime-known, is very often required at comptime by use
sites, so this avoids having to annotate such calls with `comptime`.

This is a breaking change, although note that 0.14.0 is already a
breaking release for all users of `std.builtin.Type` due to the union
fields being renamed.

Diffstat:
Mlib/std/builtin.zig | 37++++++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)

diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig @@ -607,8 +607,16 @@ pub const Type = union(enum) { /// The type of the sentinel is the element type of the pointer, which is /// the value of the `child` field in this struct. However there is no way - /// to refer to that type here, so we use pointer to `anyopaque`. - sentinel: ?*const anyopaque, + /// to refer to that type here, so we use `*const anyopaque`. + /// See also: `sentinel` + sentinel_ptr: ?*const anyopaque, + + /// Loads the pointer type's sentinel value from `sentinel_ptr`. + /// Returns `null` if the pointer type has no sentinel. + pub inline fn sentinel(comptime ptr: Pointer) ?ptr.child { + const sp: *const ptr.child = @ptrCast(@alignCast(ptr.sentinel_ptr orelse return null)); + return sp.*; + } /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. @@ -628,8 +636,16 @@ pub const Type = union(enum) { /// The type of the sentinel is the element type of the array, which is /// the value of the `child` field in this struct. However there is no way - /// to refer to that type here, so we use pointer to `anyopaque`. - sentinel: ?*const anyopaque, + /// to refer to that type here, so we use `*const anyopaque`. + /// See also: `sentinel`. + sentinel_ptr: ?*const anyopaque, + + /// Loads the array type's sentinel value from `sentinel_ptr`. + /// Returns `null` if the array type has no sentinel. + pub inline fn sentinel(comptime arr: Array) ?arr.child { + const sp: *const arr.child = @ptrCast(@alignCast(arr.sentinel_ptr orelse return null)); + return sp.*; + } }; /// This data structure is used by the Zig language code generation and @@ -645,9 +661,20 @@ pub const Type = union(enum) { pub const StructField = struct { name: [:0]const u8, type: type, - default_value: ?*const anyopaque, + /// The type of the default value is the type of this struct field, which + /// is the value of the `type` field in this struct. However there is no + /// way to refer to that type here, so we use `*const anyopaque`. + /// See also: `defaultValue`. + default_value_ptr: ?*const anyopaque, is_comptime: bool, alignment: comptime_int, + + /// Loads the field's default value from `default_value_ptr`. + /// Returns `null` if the field has no default value. + pub inline fn defaultValue(comptime sf: StructField) ?sf.type { + const dp: *const sf.type = @ptrCast(@alignCast(sf.default_value_ptr orelse return null)); + return dp.*; + } }; /// This data structure is used by the Zig language code generation and