feat: pointee($P: Type) -> Type comptime reflection builtin
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.
This commit is contained in:
@@ -1424,6 +1424,27 @@ pub fn resolveTypeCallWithBindings(self: *Lowering, cl: *const ast.Call) TypeId
|
||||
};
|
||||
return self.fieldTypeOf(t, idx, cl.callee.span);
|
||||
}
|
||||
// pointee($P) -> Type — comptime reflection: the target type of a pointer
|
||||
// (`pointee(*X)` -> `X`). Folds at lower time like `field_type` so it
|
||||
// composes inside any type-arg slot. A non-pointer arg is a loud error.
|
||||
if (std.mem.eql(u8, callee_name, "pointee")) {
|
||||
if (cl.args.len != 1) {
|
||||
if (self.diagnostics) |d|
|
||||
d.addFmt(.err, cl.callee.span, "pointee takes one type: pointee($P)", .{});
|
||||
return .unresolved;
|
||||
}
|
||||
const t = self.resolveTypeArg(cl.args[0]);
|
||||
if (t == .unresolved) return .unresolved;
|
||||
return switch (self.module.types.get(t)) {
|
||||
.pointer => |p| p.pointee,
|
||||
.many_pointer => |p| p.element,
|
||||
else => blk: {
|
||||
if (self.diagnostics) |d|
|
||||
d.addFmt(.err, cl.callee.span, "pointee: '{s}' is not a pointer type", .{self.formatTypeName(t)});
|
||||
break :blk .unresolved;
|
||||
},
|
||||
};
|
||||
}
|
||||
// Built-in: Vector(N, T)
|
||||
if (std.mem.eql(u8, callee_name, "Vector") and cl.args.len == 2) {
|
||||
const length = self.resolveVectorLane(cl.args[0]) orelse return .unresolved;
|
||||
|
||||
Reference in New Issue
Block a user