Draft / Experimental: Zith documentation describes a language under active development. Check Implementation Status before relying on a feature.
Last updated: 2026-09-04.
This document is the single source of truth for what the compiler supports today. Status reflects actual compiler behaviour at baseline a5f3716. Each feature was verified by running build/zithc check against a standalone test file, with source inspection where a status depends on internal structure. Status reflects actual compiler behaviour, not spec intent.
Implementation work that is incomplete or needs review is tracked in implementation-debt.md.
| Label | Meaning |
|---|---|
| Working | Accepted by parser and sema. Lowers through HIR to LLVM codegen. |
| Check only | Passes zithc check but semantics are incidental (parsed as Name / Binary). No dedicated AST node, HIR, or codegen. |
| Parse skipped | Declaration accepted; body entirely skipped by skipDelimited('{', '}'). No semantics. |
| Parse error | The parser itself rejects this construct. Does not reach sema. |
| Parse-level in progress | Parser lowers the construct into a frontend declaration, but the feature's semantics or full lowering are not complete. |
| Spec only | No compiler implementation. |
| Stub | CLI subcommand exists but returns "not implemented yet". |
| Stage | Status | Notes | ||
|---|---|---|---|---|
| Lexer | Working | Hand-written, character-at-a-time. Longest-first maximal munch for all multi-char operators. .. and ... lex as one Dots token, distinguished by lexeme. &&, ` |
, ++ and --` are rejected with a dedicated error |
|
| Parser | Working | Recursive-descent. Function decls, expressions, imports. | ||
| Formatter | Working | Round-trip stable for all 17 ExprKind nodes including Index, OptionalProp, Field, Arrow, StructLiteral, and WhenGuard |
||
| Import resolution | Working | import path, import path as name, from path, export path, and selectors; platform variants are resolved as foo.<arch>.<os>.zith, foo.<arch>.zith, foo.<os>.zith, then generic foo.zith; qualified access works in expressions, types, constructors and methods. export injects the target's public symbols and creates one qualified namespace alias per exported prefix so shared-prefix facades fan out to every submodule |
||
| Name resolution | Working | Scope-chained lookupBinding. Per-scope DuplicateDecl. |
||
| Type checking | Working | All ExprKind nodes. Optional/null validation. Index bounds. |
||
| Generic instantiation | Working | Generic fn, struct, alias, enum, union, and implement blocks are monomorphized before HIR. Calls and named types resolve concrete instances; reified structs keep concrete type arguments as structural metadata, so nested generics such as Entry<K, V> inside HashMap<K, V> keep the correct slots. Enum/union templates accept inline fn methods and generic implement as Trait blocks alongside their positional variants/members. Generic inference considers implicit optional coercions, so ?T/??T parameters can infer T from a bare or partially-optional argument while non-optional parameters remain exact. T: A + B bounds are parsed, stored, and enforced at generic call sites; trait-bound method calls type-check through the declared trait method while GenericBinding remains the source of truth for bounds |
||
| Comptime / Solve | Reserved | Macro expansion happens in frontend; the solver remains a compatibility stub. Generic monomorphization now runs before NRA/HIR in step-04 | ||
| NRA / Reference Analysis | In progress | NRA is the full Zith reference/ownership analysis. Zith-- implements a partial simplified version: residual facts are accumulated and consumed before final lowering. The &local/@ptrOf(local) use-after-move slice now marks moved slots as consumed in HirAttrs without HIR ownership nodes; the full alive/dead/lent state machine and four-rule proof remain to be completed. Internal names such as NraFacts and nraStage keep the historical NRA spelling |
||
| HIR lowering | Working | Covers all working features; residual ownership facts attach to side tables without introducing ownership HIR nodes | ||
| LLVM codegen | Working | x86-64 and WebAssembly targets | ||
| Cache | Working | Object and artifact caching persist/load .zirl files, validate canonical mappings, and hydrate cached artifacts |
||
| Stdlib I/O | Working | print/println/input, Formatable, ParseInput, and InputLine.cast<T> type-check and lower; runtime parsing verification is manual for now |
||
| Stdlib allocation | Working | std/memory ships the strict DAG with in-place, allocator, heap, and new; imported InPlace conformance and qualified trait calls are deterministically covered by tests/test-interface-satisfaction.cpp and tests/test-generic-hashmap.cpp. std/alloc remains as a legacy compatibility module. The generic new/delete/make/release helpers remain proposed until return-only inference and opaque pack dispatch are supported |
||
| Stdlib collections | Working | std/collections/hash_map_u64 ships a concrete u64 -> u64 open-addressed map with reserve, put, contains, get, len, and destroy. std/collections/hash_map ships a checked generic HashMap<K, V>, Entry<K, V>, and Hashable module that passes zithc check and is covered by tests/test-generic-hashmap.cpp |
| Feature | Status | Notes |
|---|---|---|
fn |
Working | Parameters, return type, body. The return type is written fn f(x: T): R or fn f(x: T) -> R; both spellings parse. Overloading by parameter count and types (F-33); linkage names are qualified as <module>.<Owner>.<name>(<params>), except extern fn and main |
| Call-result statements | Working | Non-void call/dock results used as expression statements must be consumed or explicitly discarded with _ = expr; (E2026). Void calls and value-producing uses (binding, assignment, return, argument, condition, binary operand, field/index operand, method dispatch) remain legal |
generic parameter lists <T, U> |
Working (step 04/05) | Accepted on fn, struct, type alias, enum, union and trait declarations. Generic calls and concrete type uses instantiate monomorphically, including inferred type arguments and generic methods. Cache artifacts carry an instantiation summary. T: A + B bounds are parsed and enforced with E3009 (trait) or E2024 (interface) when an argument does not satisfy a bound |
state machine |
Working | state declarations, dock State(args) expressions, and jump Next(args) terminating transitions are parsed, typed, and lowered. States in one machine share a return type but may have different parameter lists; a state without a written return type is void and is not inferred from the body. State functions and calls use LLVM tailcc; transitions emit direct musttail tailcc calls followed by ret; old flow fn/marker syntax is rejected. state(params): ret is a value type that accepts a real matching state declaration and supports dock S(args) indirect calls |
| Function return termination | Working | Non-void functions reject paths that can fall through without a value. Implicit final-value bodies, complete if/else or when with a default, state jump, and unbounded for loops without a direct break are accepted; otherwise the body reports a missing-return diagnostic |
raw fn |
Working | Parsed and lowers |
const fn |
Parse-level in progress | Parsed as a function declaration with FunctionKind::Const; compile-time evaluation is not implemented |
extern fn |
Working | C ABI interop |
let, var, const, global |
Working | All binding forms. const means immutable, not comptime |
| Feature | Status | Notes | ||
|---|---|---|---|---|
bool, char |
Working | |||
i8–i128, u8–u128 |
Working | Arithmetic between matching widths only; no implicit promotion | ||
f32, f64 |
Working | Same-width arithmetic only | ||
?T (optional) |
Working | null → ?T and T → ?T coercions, including nested ??T accepting ?T or bare T; ? postfix propagation with operand/return validation. Generic inference uses the optional coercion as a fallback, so fn wrap<T>(x: ?T): ?T accepts wrap(3) and infers T = i32. Any ?T expression is implicitly boolean in conditions (if (x) means x != null). null is rejected for non-optional *T |
||
T! (result) |
Spec only | Full-Zith result/error type; not part of the Zith-- type surface | ||
*T (pointer) |
Working | Non-nullable pointer object: null requires ?T. p deref, &x addr-of, and -> arrow all work. &x is a logical move (E4001 on later reads, direct rebind revives) and &x/@ptrOf(local) may not escape their storage scope (E4008). void is rejected (use raw opaque). Pointers imported from C are ?T, narrowed by is null/not (is null); deref, arrow, index, and coercions expect proof and report E3005 otherwise |
||
raw opaque |
Working | Dedicated TypeExprKind::Opaque, lowered to pointer-to-void (untagged C-style void). Castable to and from any T via as; raw opaque as T reinterprets without a tag check |
||
opaque |
Working | Bare opaque is a tagged open union stored as { *void, u32 } (typeId) and is always a view. T as opaque spills the concrete value to a stable local; opaque is T compares the tagged typeId; opaque as T returns ?T (extraction in a call or other non-optional result is handled as a checked optional). Values exported and imported across modules retain the declaring module's canonical tag, and cached artifacts hydrate canonical_mappings so the tag stays stable across sessions. This iteration has no heap copy, vtable or dynamic calls |
||
[N]T (array), []T (slice) |
Working | Arrays coerce to slices as zero-copy views; a[lo..hi] and a[i] return optionals with static/dynamic bounds checks. raw a[lo..hi]/raw a[i] emit unchecked views/indexing |
||
| ` | T, U | ` (pack) | Working | Heterogeneous pack literals, named pack types, positional compile-time indexing, and [a, b] binding destructuring lower as concrete aggregates. Packs can coerce positionally to named pack types with matching arity and member types |
[...]T (variadic slice) |
Working | Last parameter only. Auto-collects a homogeneous tail into a temporary slice; accepts an explicit final []T/[N]T and an empty tail. Supported for free functions, methods, dyn trait/interface methods, generic inference, states/dock/jump and overloads; fixed-arity overloads are preferred |
||
fn(...): R (function value) |
Working | Parses as a type value, type-checks non-generic function references, and lowers/calls through C function-pointer ABI. No closures or captures | ||
dyn Trait / dyn Interface |
Working (methods) | Concrete values coerce to fat pointers (HirMakeDyn) with per-type vtables (HirVTable); method calls lower to HirDynCall. Zith-- exposes only methods through dyn; interface fields remain available on concrete types and generic bounds, and a.x on dyn Interface reports E3001 |
||
struct, component, enum, union |
Working | Declarations parse and resolve. Generic enum/union templates support inline methods, concrete instantiation for HIR/codegen, and trait conformance (implement Enum<T> as Trait / implement Union<T> as Trait) |
||
trait, interface |
Working (conformance) | Declaration bodies store trait method requirements/default methods and interface fields plus declaration-only method requirements. Single (x: T) and grouped ([x, y]: T) interface fields are equivalent. Trait implementations are verified against required signatures with Self substitution; duplicate implementations are rejected (E2027). Interfaces satisfy structurally by checking fields and compatible method signatures, generic interface bounds expose those members, and explicit interface implementation is rejected (E2025) |
||
implement T as Trait {} |
Working | Records a verified nominal conformance edge and resolves calls to concrete trait defaults. The canonical syntax is implement T as Trait; the legacy for Trait spelling remains parsed |
||
type |
Working (Zith-- cast-based) | type Name = T creates a nominal one-field wrapper distinct from T; T as Name constructs it and Name as T extracts the underlying value. alias stays transparent |
||
alias |
Working | Transparent alias: alias Name = T re-exports the same type |
||
memory qualifiers (mut, lend, view, own, share, belong) |
Working (lend/view slice) | lend T/view T parameters lower to pointers and require call-site annotations for default bindings (E4005); invalid call annotations are rejected (E4007); same-binding conflicts in one call are rejected; view writes report E4004; LLVM adds readonly for view and nocapture for lend/view. own/share/belong/mut as type prefixes remain rejected or legacy-only. NRA residual facts are attached before HIR (F-34, partial F-14) |
| Feature | Status | Notes | |||
|---|---|---|---|---|---|
literals (42, 0xFF, 0c17, 0b101, 3.14, true, false, null, strings, chars) |
Working | Explicit radix prefixes (0x hex, 0c octal, 0b binary) are typed and lowered to their value; a literal wider than 64 bits reports E0004. Digit separators (1_000) are unsupported. C-like escapes decoded in string and char literals; \# is an accepted escape producing a literal #; unknown escapes report E0001 |
|||
unary -, not |
Working | not is the only boolean negation; prefix ! is not recognized and stays reserved for a future postfix form |
|||
unary ~ |
Working | Bitwise NOT; integer operand only, lowers to HirUnaryOp::BitNot |
|||
binary + - * / % == != < > <= >= |
Working | ||||
bitwise &. ` |
. ^.` |
Working | Spec spellings keep the .. Both operands must be integers of the same type; share HirBinaryOp::And/Or/Xor with the and/or/xor keywords |
||
assignment = |
Working | Right-associative, yields a value | |||
compound assignment += -= *= /= %= <<= >>= &= ` |
= ^=` |
Working | Desugared in the parser to Assign(Binary(base)), so they yield a value like = and inherit its coercion and view checks. The bitwise compounds drop the . of their base spelling. No new HIR node |
||
&&, ` |
` | Parse error | Lexed as single tokens purely to report a dedicated error pointing at and / or; exactly one diagnostic, no cascade |
||
++, -- |
Parse error | Lexed as single tokens purely to reject increment/decrement; the diagnostic points to explicit assignment. Prefix and postfix forms both report E2010 |
|||
field access x.field |
Working | Dot access on struct values. Struct fields are private by default; pub name: T opens a field, and mod/mod(N)/mod(..) apply the existing module-depth rule. Invisible fields are rejected for access and in cross-module struct literals |
|||
dereference *p |
Working | Pointer dereference via unary * |
|||
address-of &x |
Working | Address-of via unary & |
|||
p->field |
Working | Arrow access on struct pointers | |||
| ` | > / do` pipeline |
Working | ` | > requires exactly one explicit ..; do accepts zero or one .., keeps the chain value and may run effects without it. No automatic injection or ?/!/tag propagation; |
>` replaces the chain value |
index a[i] |
Working | On arrays, slices, pointers; array/slice reads return ?T with bounds checks. raw a[i] skips bounds handling and returns T |
|||
? postfix propagation |
Working | Requires optional operand in an optional-returning function. ?T conditions are implicit (if (x)), so x? is propagation only and is rejected in condition position unless the enclosing function propagates |
|||
must / raw optional extraction |
Working | must x extracts a ?T payload and terminates with runtime panic R10003 on null; raw x extracts the payload without a null check. is null remains the only flow-narrowing mechanism |
|||
as cast |
Working | Dedicated ExprKind::Cast -> HirCast -> LLVM conversion. Numeric pairs plus raw opaque <-> *T (classifyCast); pointer-to-pointer between concrete pointees, integer/pointer mixes and user-defined casts stay rejected. Tagged-union member extraction outside a narrowed/checked context requires raw; raw-union member casts remain free. Narrowing literal, - literal and integer-const operands are checked at compile time; variable operands and float-to-int still lack runtime checks |
|||
is null |
Working | Dedicated ExprKind::IsNull. Requires an optional operand; ?*T uses the nullptr niche, ?T reads the discriminant |
|||
is <type> |
Working (tagged unions + opaque) | Tagged-union member tests lower to a runtime tag check; inside if/when they narrow the tested local to the member type. opaque is T compares the bare opaque typeId and returns bool |
|||
range 1..5, 1>..5, 1..<5, 1>..<5 |
Working | Dedicated ExprKind::Range with raw bounds and open-at-lo/hi flags. in lowers ranges and any contains(self, value): bool method; for (x in int_range) iterates with implicit step 1. Float ranges are valid with in and rejected in for. Boundary semantics are documented and covered, including empty ranges and single-value closed ranges |
|||
in (value in rhs) |
Working | Binary operator returning bool; resolves literal ranges and the Contains protocol without changing the existing Iterator protocol |
|||
struct literal Foo { x: 1, y: 2 } |
Working | Struct literal with named fields via {} syntax. Inaccessible private/mod fields are rejected except in the file that declares the struct |
|||
@sizeOf, @offsetOf, @alignOf |
Working | @ parses in expression position. @sizeOf(T) accepts any complete type and types as u64; @offsetOf(S, field) and @alignOf(S) are struct-only and type as i32. @sizeOf(void) reports E3001 ("requires a complete type") |
|||
@canonicalType |
Working | Returns a stable u128 derived from module namespace, canonical field order, and type name; lowers to HirCanonicalType and is serialized through the artifact cache. |
| Feature | Status | Notes |
|---|---|---|
if / else / else (cond) / else if |
Working | Conditions accept bool or ?T; ?T is tested implicitly as non-null. else (cond) is the preferred chained spelling; else if is deprecated with W1008 but still lowers |
while |
Deprecated | Still lowers correctly, emits W1008 suggesting for (cond) { }, and accepts ?T as an implicit non-null condition |
break, continue |
Working | Unlabeled forms target the innermost active loop. Labels accept outer: for, break outer;, and continue outer;; unknown or duplicate active labels are rejected |
return (void and typed) |
Working | |
for (cond) { }, for { } |
Working | Conditional and infinite loop forms lower to the same CFG as while; labels are supported on both forms. ?T conditions are tested implicitly as non-null |
for (init, cond, step) { } |
Working | Flat and parenthesized clause forms are accepted. init and step are both optional; continue still runs the step before the next test. Labels are stored on the real For node |
for (x in xs) |
Working | Duck-typed iterator over a struct with next(self); the canonical next(self): ?T returns null for the iteration end and a payload for each element. ??T iterators bind the loop variable as ?T so null elements are distinguishable from the end. The legacy tagged-union { T, End } protocol remains accepted during migration. Labels are supported |
when / match pattern match |
Working | Arms are written (pattern) body, comma-separated; optional later islands are boolean guards ((pattern) and (guard) body). match is a parser synonym for when. Equality, boolean and range (1..3) patterns lower through HIR to codegen, and the first island may combine non-boolean patterns with and/or/xor. An (f is Member) arm narrows f for that arm's body. (_) must be the sole island of the last arm; a value-producing when without a default reports non-exhaustive. Legacy ~> stays accepted but emits W1008. Covered by runtime tests |
state / jump |
Working | state Name(params): ReturnType declares a state with the machine return type; jump Next(args) terminates the current block and validates arity/types against the target's own parameters before a direct musttail tailcc transfer |
dock |
Working | dock State(args) is a tailcc call expression that returns the machine's final state return value; the old dock { ... } block form is rejected |
defer expr; scope guards |
Working | defer expr; and defer { ... } register cleanup on the nearest lexical block and run in reverse registration order on normal exit, return, break, continue, and state jump. A defer may capture same-block bindings declared later; exits before initializing a captured binding are rejected. The deferred body is cleanup-only and rejects return/break/continue/jump |
drop cleanup hooks |
Planned (Zith--) | Reserved keyword only, no parser branch consumes it yet. F-41 is the next Zith-- cleanup feature after defer; plan and scope split live in docs/plans/defer-drop.md |
| Feature | Status | Notes |
|---|---|---|
prefix, suffix, infix, nop decls |
Parse skipped | Body skipped via skipDelimited |
context declarations |
Parse skipped | Body skipped |
use statements |
Parse skipped | Body skipped |
macro / raw macro declarations and @name(...) calls |
Working | Normal macros rename template-local bindings hygienically and resolve other template names through the call-site scope (globals/imports visible when not shadowed). raw macro splices literally into the call-site scope and names resolve there before module/global fallback. Templates are not analysed as code; resolution is keyed by node id |
tag calls (formerly tag macro) |
Parse reported / full Zith | <Section ...> ... </Section> and named attributes parse, but the declaration is rejected in the Zith-- pipeline with E2010; tag is a full-Zith item, not a Zith-- macro. Use normal or raw macro in Zith-- |
| word call expressions | Parse error | No parser support |
| word sequence expressions | Parse error | No parser support |
| Feature | Status | Notes |
|---|---|---|
import, from, export |
Working | import path exposes only the full dotted namespace (std.io.console.println), import path as name exposes name.symbol, from path injects public symbols, and export path re-exports the namespace plus public symbols |
c/... supported runtime surface |
Working / Partial | c/io, c/stdlib, and c/string provide the common declarations used by the shipped stdlib; native LLVM, no-LLVM VM, and WASM backend resolution remains target-specific |
alias |
Working | |
pub, mod |
Working | |
mod(..), mod(N) |
Working | Module-depth visibility is applied to declarations and to struct fields; mod(..) is unlimited and mod(N) allows N directory levels below the owner |
| C header imports | Working (validated C) | libclang only; variadic functions, array-decayed parameters, va_list, and function-pointer parameters supported. Object-like scalar macros are imported as constants and verified through the CLI. Simple records passed/returned by value are imported only after libclang proves their layout for the configured target triple; scalar, pointer, nested validated-record, two-adjacent-i32, and two-adjacent-i64 fields are supported. Function-like macros, strings, globals, bitfields, packed/anonymous records, flexible arrays, mixed-width records, long double, and __int128 remain unimported with explicit skips |
| Feature | Spec chapter |
|---|---|
| NRA ownership analysis (full alive/dead/lent state machine and four-rule proof; the call-annotation borrow slice is implemented) | 07-memory-model.md |
comptime evaluation |
11-comptime.md |
const fn evaluation |
11-comptime.md |
try / try ... or / fail / with / catch / must(cond) assertion / throw |
08-error-handling.md |
Assets (ZithProject.toml asset paths) |
12-assets.md |
.zirl binary format |
01-overview (§1.5) |
@appendField, @removeField, @appendMethod |
11-comptime.md |
dyn dispatch |
14-polymorphism.md |
| Surface | Current behaviour | Notes |
|---|---|---|
async fn |
Parse skipped | Legacy parser affordance only. Concurrency is being documented as stdlib/runtime APIs, not a function kind |
yield |
Reserved token | Not a core statement |
fork, merge, spawn |
Spec only (full Zith) | Draft thread protocol; no frontend/HIR contract exists yet. See docs/plans/branch-protocol.md |
await |
Reserved token | Not a core statement |
| Command | Status | Notes |
|---|---|---|
zithc build |
Working | Links an executable into target/ by default; --emit obj/ir/asm/hir stop earlier; --cache-stats prints object-cache hit/miss counts |
zithc run |
Working | Compiles + executes in one step; the program's stdout/stderr is forwarded to zithc's stdout, compiler diagnostics stay on stderr |
zithc check |
Working | Type-checks without emitting. Errors forwarded from frontend snapshot |
zithc fmt |
Working | Round-trip tested for Index and OptionalProp |
zithc create <name> |
Working | |
zithc clean |
Working | |
zithc execute <file> |
Working | |
zithc test <path> |
Working | Discovers and runs test files under the given path |
zithc repl |
Stub | |
zithc deps list |
Working | Reads ZithProject.toml and lists declared dependencies |
zithc deps add, deps remove |
Stub | |
zithc docs |
Working | Generates documentation from source |
Codes are grouped by pipeline stage. E0000 remains the generic user-reported diagnostic.
| Range | Stage | Codes |
|---|---|---|
| 0001-0005 | Lexical | E0001 UnknownToken, E0002 UnclosedString, E0003 InvalidEscape, E0004 InvalidIntLiteral, E0005 UnclosedComment |
| 1001-1009 | Import/parse | E1001 ExpectedExpr, E1002 ExpectedSemicolon, E1003 UnclosedParen, E1004 ExpectedIdent, E1005 InvalidImportDepth, E1006 ImportError, E1007 TopLevelLetNotAllowed, W1008 DeprecatedSyntax (while -> for (cond); else if -> else (cond); ~> in when arms), E1009 CircularImport |
| 2001-2010 | Semantic | E2001 UndefinedIdent, E2002 DuplicateDecl, E2003 WrongArity, E2004 UnusedDecl, E2005 NotNamespace, E2006 NoMember, E2007 NoMatchingFn, E2008 AmbiguousCall, E2009 NotImplemented, E2010 UnsupportedSyntax |
| 2021-2025 | Frontend/interface | Trait requirement/signature checks (E2021/E2022), E2023 NotATrait, E2024 InterfaceNotSatisfied, E2025 explicit implement for an interface, E2027 DuplicateImplementation |
| 3001-3009 | Types | E3001 TypeMismatch, E3002 CannotInfer, E3003 InvalidCast, E3004 CyclicType, E3005 NullDerefUnproven, E3006 CoercionFailure, E3007 WidthMismatch, E3008 OptionalViolation, E3009 ConstraintNotSatisfied |
| 4001-4008 | NRA / ownership | E4001 UseAfterMove (logical receiver or &x move in sema), E4002 BorrowConflict, E4003 DoubleBorrow, E4004 WriteThroughView, E4005 OwnershipCoercionRequired, E4007 InvalidCallOwnership, E4008 PointerEscapesScope — call annotations, borrow conflicts and views are checked in sema; direct pointer-local rebinds clear the old alias state; E4004 remains emitted for views |
| 5001-5002 | Lowering | E5001 InvalidIR, E5002 Unreachable |
| 10001-10004 | Runtime | R10001 IndexOutOfBounds, R10002 DivisionByZero, R10003 NullDeref, R10004 Panic |
All statuses above were verified against the binary built from commit a5f3716, by running zithc check on standalone files per feature and by inspecting the source where a status depends on internal structure (pipeline boundaries, linkage naming, diagnostic ranges).
Recorded deliberately. Each item is a follow-up, not an unknown.
| Item | Notes |
|---|---|
| Non-literal narrowing conversions need runtime checks | Compile-time as checks cover literal, - literal and integer-const operands; variable operands and numeric-literal adaptation remain unchecked |
Bodyless for (literal..literal){} |
Rejected in sema before HIR/codegen with a targeted diagnostic; a literal range is not a boolean condition and requires in or a loop binding |
?*T pointer narrowing is local-only |
Non-null proof currently follows a nullable-pointer local through is null/not (is null) branches and early-return checks; derived field/index/arrow expressions and cross-function proofs are not yet tracked |
Formatter re-prints for (cond) as while |
for (cond) desugars to ExprKind::While; the formatter prints while (...), so the spelling is not round-trip faithful |
is outside null/tagged-union contexts |
Non-union is Type remains unsupported and reports a dedicated diagnostic |
| User-defined casts | To be added as a new branch in classifyCast |
| C struct-by-value ABI limited to verified simple records | struct parameters/results are imported only when libclang proves layout/alignment for scalars, plain pointers, nested verified records, and two adjacent 64-bit fields on the target used by the parse. Clang passes/returns that pair as two 64-bit scalars on x86-64 and AArch64 Linux; mixed-width or edge-case records are skipped before lowering |
Imported/cached bare opaque values |
Bare opaque values exported from module A and consumed in module B are accepted; the canonical tagged typeId is recorded when the value is erased and restored from cached artifacts. There is no cross-module registry object, but canonical tags are deterministic and persisted by the existing canonical_mappings path |
.. / ... |
Intentionally one Dots token; .. is the range/pipe/import token and ... is the variadic marker. Not a debt |
++ / -- |
Intentionally rejected in Zith--; update values with explicit assignment. Not a debt |
| Ownership proof still happens after premature lowering in places | The stable order is sema -> comptime/solve -> NTA/NRA -> HIR; residual facts are now attached before final lowering, while some paths still need the full NRA proof before emitting their final form |
When a feature moves from one status to another, update this table and re-verify.