authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-15 16:57:04+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-16 12:49:58+00:00
log89a9cabafd745034871ea014b06bd3bad0505f4a
tree3d731785b1c66bbbd947911802f6f1c4837490b7
parent0cc9d68b77b31c6502da80ce7e6dabaf9316ca48
signaturelock-open Commit is signed but in an unrecognized format.

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.

1 files changed, 32 insertions(+), 5 deletions(-)

lib/std/builtin.zig+32-5
......@@ -607,8 +607,16 @@ pub const Type = union(enum) {
607607
608608 /// The type of the sentinel is the element type of the pointer, which is
609609 /// the value of the `child` field in this struct. However there is no way
610 /// to refer to that type here, so we use pointer to `anyopaque`.
611 sentinel: ?*const anyopaque,
610 /// to refer to that type here, so we use `*const anyopaque`.
611 /// See also: `sentinel`
612 sentinel_ptr: ?*const anyopaque,
613
614 /// Loads the pointer type's sentinel value from `sentinel_ptr`.
615 /// Returns `null` if the pointer type has no sentinel.
616 pub inline fn sentinel(comptime ptr: Pointer) ?ptr.child {
617 const sp: *const ptr.child = @ptrCast(@alignCast(ptr.sentinel_ptr orelse return null));
618 return sp.*;
619 }
612620
613621 /// This data structure is used by the Zig language code generation and
614622 /// therefore must be kept in sync with the compiler implementation.
......@@ -628,8 +636,16 @@ pub const Type = union(enum) {
628636
629637 /// The type of the sentinel is the element type of the array, which is
630638 /// the value of the `child` field in this struct. However there is no way
631 /// to refer to that type here, so we use pointer to `anyopaque`.
632 sentinel: ?*const anyopaque,
639 /// to refer to that type here, so we use `*const anyopaque`.
640 /// See also: `sentinel`.
641 sentinel_ptr: ?*const anyopaque,
642
643 /// Loads the array type's sentinel value from `sentinel_ptr`.
644 /// Returns `null` if the array type has no sentinel.
645 pub inline fn sentinel(comptime arr: Array) ?arr.child {
646 const sp: *const arr.child = @ptrCast(@alignCast(arr.sentinel_ptr orelse return null));
647 return sp.*;
648 }
633649 };
634650
635651 /// This data structure is used by the Zig language code generation and
......@@ -645,9 +661,20 @@ pub const Type = union(enum) {
645661 pub const StructField = struct {
646662 name: [:0]const u8,
647663 type: type,
648 default_value: ?*const anyopaque,
664 /// The type of the default value is the type of this struct field, which
665 /// is the value of the `type` field in this struct. However there is no
666 /// way to refer to that type here, so we use `*const anyopaque`.
667 /// See also: `defaultValue`.
668 default_value_ptr: ?*const anyopaque,
649669 is_comptime: bool,
650670 alignment: comptime_int,
671
672 /// Loads the field's default value from `default_value_ptr`.
673 /// Returns `null` if the field has no default value.
674 pub inline fn defaultValue(comptime sf: StructField) ?sf.type {
675 const dp: *const sf.type = @ptrCast(@alignCast(sf.default_value_ptr orelse return null));
676 return dp.*;
677 }
651678 };
652679
653680 /// This data structure is used by the Zig language code generation and