Project a pointer type to its target: `pointee(*X)` -> `X`. The one reflection primitive missing for the `race` result synthesis (`*Task(A)` -> `A` via `field_type(pointee(*Task(A)), 0)`) — reflection could read aggregate fields but was blind to a pointer's target type. Mirrors the `field_type` builtin: declared `#builtin` in std/core.sx, resolved as a lower-time type-call fold in resolveTypeCallWithBindings (src/ir/lower/generic.zig) so it composes in any type-arg slot. `.pointer` -> pointee, `.many_pointer` -> element; a non-pointer arg is a loud diagnostic + `.unresolved` sentinel (no silent fallback). Adversarially reviewed (SHIP). Locked by examples/comptime/0647-comptime-pointee-reflection.sx. Suite green (819/0). PLAN-RACE step 1 of 6.
27 lines
1.0 KiB
Plaintext
27 lines
1.0 KiB
Plaintext
// `pointee($P: Type) -> Type` — comptime reflection for a pointer's target type
|
|
// (`pointee(*X)` -> `X`). Folds at lower time like `field_type`, so it composes
|
|
// inside other type-arg slots — e.g. project a generic handle `*Box(A)` to its
|
|
// payload type `A` via `field_type(pointee(*Box(A)), 0)`. (Foundation for the
|
|
// `race` result synthesis, which projects `*Task(A)` -> `A`.)
|
|
#import "modules/std.sx";
|
|
|
|
Box :: struct ($R: Type) { value: R; tag: i64; }
|
|
|
|
// Project a pointer-to-Box to the Box's payload type: *Box(A) -> A.
|
|
Payload :: ($P: Type) -> Type { return field_type(pointee(P), 0); }
|
|
|
|
main :: () -> i32 {
|
|
// plain pointer
|
|
print("pointee(*i64) = {}\n", type_name(pointee(*i64)));
|
|
print("pointee(*bool) = {}\n", type_name(pointee(*bool)));
|
|
|
|
// pointer to a generic struct → the struct type
|
|
print("pointee(*Box(f64)) field0 = {}\n", type_name(field_type(pointee(*Box(f64)), 0)));
|
|
|
|
// composed projection, used as a real type
|
|
v : Payload(*Box(i64)) = 42;
|
|
print("Payload(*Box(i64)) value = {}\n", v);
|
|
|
|
return 0;
|
|
}
|