`any_to_string` runs `type := type_of(val)`; for an `.any` operand
`type_of` lowers to `struct_get(val, 0)` to read the Any's tag. At
runtime a first-class Type value is the aggregate `{ tag=.any, value=tid }`
so the read succeeds, but the comptime interpreter stores a Type as a bare
`.type_tag(tid)` and the comptime `struct_get` arm had no case for it — it
raised `CannotEvalComptime`, which `runComptimeSideEffects` swallowed into
`void_val`, truncating the `#run` while still building with exit 0.
- interp.zig: comptime `struct_get` handles a `.type_tag(tid)` base by
mirroring the runtime Any-Type layout (field 0 -> `.any` tag, field 1 ->
the type id), so `type_of` of an Any-held Type evaluates as it does at
runtime and execution continues.
- emit_llvm.zig: `runComptimeSideEffects` no longer swallows a side-effect
bail; it prints a loud diagnostic and sets `comptime_failed`
(-> error.ComptimeError, non-zero exit), matching the const-init path.
A truncated `#run` can no longer ship a successful build.
Regression: examples/0613-comptime-print-any-type.sx (all five lines print,
exit 0). Resolves issue 0096.
33 lines
1.2 KiB
Plaintext
33 lines
1.2 KiB
Plaintext
// Comptime `#run` formatting of an `Any` that holds a `Type`.
|
|
//
|
|
// `print("{}", at)` where `at: Any` holds a `Type` value routes through
|
|
// `format` → `any_to_string`, whose `type := type_of(val)` lowers (for an
|
|
// `.any` operand) to `struct_get(val, 0)` — reading the Any-Type's tag.
|
|
// At runtime a `Type` value is the aggregate `{ tag=.any, value=tid }`,
|
|
// so the read works and the type's name prints. The comptime interpreter
|
|
// stores a first-class `Type` as a bare `.type_tag`, so the struct_get
|
|
// must mirror that same `{ .any, tid }` layout — otherwise it bails and
|
|
// the `#run` truncates. Reflection over the same `Any` (`type_name`,
|
|
// `type_is_unsigned`) already works; the value-print must match.
|
|
//
|
|
// Regression (issue 0096): a comptime `#run` print of an `Any`-held
|
|
// `Type` silently stopped (omitted `value=` + every later line) yet still
|
|
// built with exit 0.
|
|
|
|
#import "modules/std.sx";
|
|
|
|
ct_probe :: () {
|
|
print("before\n");
|
|
x : u64 = 1;
|
|
t : Type = type_of(x);
|
|
at : Any = t;
|
|
print("name={}\n", type_name(at));
|
|
print("unsigned={}\n", type_is_unsigned(at));
|
|
print("value={}\n", at);
|
|
print("after\n");
|
|
}
|
|
|
|
#run ct_probe();
|
|
|
|
main :: () {}
|