docs(specs,readme): narrow runtime Type-value support to type_name/type_is_unsigned [F0.8]

The 7 type-only builtins doc claimed all of them accept a runtime Type
value, but only type_name and type_is_unsigned do. The other five
(size_of, align_of, field_count, type_eq, is_flags) are compile-time-only
— a runtime Type value (type_of(x)) yields 'unresolved type' since
runtime reflection is deferred. Reword both docs to the accurate scope.

Verified: type_name(type_of(x))=u32, type_is_unsigned(type_of(x))=true;
size_of(type_of(x)) / align_of(type_of(x)) -> error: unresolved type.
This commit is contained in:
agra
2026-06-05 12:31:21 +03:00
parent 7d566d2d07
commit 136484f72f
2 changed files with 2 additions and 2 deletions

View File

@@ -2238,7 +2238,7 @@ Built-in functions are declared in `std.sx` with the `#builtin` suffix, which te
- `type_eq($A: Type, $B: Type) -> bool` — structural TypeId equality (`type_eq(s64, s64)` is `true`, distinct shapes are `false`); folds at compile time, so `inline if type_eq(...)` is comptime-decidable
- `type_is_unsigned($T: Type) -> bool` — `true` if `T` is an unsigned integer (`u8`/`u16`/`u32`/`u64`/`usize`); used by `{}` formatting to print unsigned integers as unsigned decimal
The seven type-only builtins — `size_of`, `align_of`, `field_count`, `type_name`, `type_eq`, `type_is_unsigned`, `is_flags` — strictly require a **type** argument: a spelled type (`s64`, `*u8`, `Point`), a generic type parameter (`T`), or a runtime `Type` value (`type_of(x)`, a `[]Type` element, a `Type`-typed local). Passing a value (`size_of(6)`, `type_is_unsigned(true)`) is a compile-time error — `<builtin> expects a type, got '<type>'` — not a silent reinterpretation of the value's bits as a type.
The seven type-only builtins — `size_of`, `align_of`, `field_count`, `type_name`, `type_eq`, `type_is_unsigned`, `is_flags` — strictly require a **type** argument. A spelled type (`s64`, `*u8`, `Point`) or a generic type parameter (`T`) is accepted by all seven. A runtime `Type` value (`type_of(x)`, a `[]Type` element, a `Type`-typed local) is currently supported by `type_name` and `type_is_unsigned` only; the other five (`size_of`, `align_of`, `field_count`, `type_eq`, `is_flags`) are compile-time-only — a runtime `Type` value is not yet supported there (runtime reflection is deferred to a future step). Passing a value (`size_of(6)`, `type_is_unsigned(true)`) is a compile-time error — `<builtin> expects a type, got '<type>'` — not a silent reinterpretation of the value's bits as a type.
An `Any` is accepted because it can hold either a value or a `Type`. `type_name` and `type_is_unsigned` consult the `Any`'s runtime type-tag, not its payload: an `Any` holding a *value* reports the type **of that value** (`av : Any = 6` → `type_name(av)` is `"s64"`), while an `Any` holding a *`Type` value* (e.g. `type_of(x)` stored in an `Any`) names the **held type**. This is the same tag the `{}` formatter reads, so `print(av)` and `type_name(av)` agree on what `av` is.