From 136484f72fa00ee73d022304ff4358ef91bbd85c Mon Sep 17 00:00:00 2001 From: agra Date: Fri, 5 Jun 2026 12:31:21 +0300 Subject: [PATCH] docs(specs,readme): narrow runtime Type-value support to type_name/type_is_unsigned [F0.8] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- readme.md | 2 +- specs.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index a9f272d..a0def48 100644 --- a/readme.md +++ b/readme.md @@ -432,7 +432,7 @@ The standard library (`modules/std.sx`) provides: - **Strings**: `concat`, `substr`, `int_to_string`, `uint_to_string`, `float_to_string`, `cstring` - **Memory**: `Allocator` protocol, `GPA` (general purpose), `Arena` (bump allocator) - **Math**: `sqrt`, `sin`, `cos` -- **Introspection**: `type_of`, `type_name`, `type_is_unsigned`, `type_eq`, `field_count`, `field_name`, `field_value`, `size_of`, `align_of`, `is_flags` — the type-only builtins (`size_of`, `align_of`, `field_count`, `type_name`, `type_eq`, `type_is_unsigned`, `is_flags`) require a type argument (a spelled type, a generic `T`, or a runtime `Type` value); passing a value is a compile-time error +- **Introspection**: `type_of`, `type_name`, `type_is_unsigned`, `type_eq`, `field_count`, `field_name`, `field_value`, `size_of`, `align_of`, `is_flags` — the type-only builtins (`size_of`, `align_of`, `field_count`, `type_name`, `type_eq`, `type_is_unsigned`, `is_flags`) require a type argument (a spelled type or a generic `T`); passing a value is a compile-time error. A runtime `Type` value (`type_of(x)`) is currently accepted by `type_name` and `type_is_unsigned` only — the other five are compile-time-only (runtime reflection is deferred) ### Command-line interface (`modules/std/cli.sx`) diff --git a/specs.md b/specs.md index 7514ad6..03a516d 100644 --- a/specs.md +++ b/specs.md @@ -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 — ` expects a type, got ''` — 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 — ` expects a type, got ''` — 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.