# 0064 — non-`$` `T: Type` function param used as a type silently yields `{}` ## Symptom A function parameter declared `T: Type` (or lowercase `T: type`) — i.e. WITHOUT the `$` generic-type-parameter sigil — that is then referenced in a type position (`-> T`, `Closure() -> T`, etc.) silently resolves `T` to a fabricated empty struct `{}` instead of the caller's argument type. The function "runs" but produces garbage (the value renders as `T{}`), with no diagnostic. ```sx idwrap :: (T: Type, f: Closure() -> T) -> T { return f(); } main :: () -> s32 { print("{}\n", idwrap(s32, closure(() -> s32 { return 7; }))); // prints "T{}", want 7 return 0; } ``` The correct, working form is the generic `$T: Type` (the `$` introduces the generic type parameter — see `specs.md` §"`$` generic type parameter introduction"). With `$T`, the binding is established and the result is `7`. So this is not a miscompile of a valid program — it's a **missing diagnostic** for a misuse: a non-generic `Type`-typed value param can't be used as a type, and should be rejected (or the `$` requirement explained), not silently turned into an empty struct. ## Reproduction See above. Compare `idwrap :: ($T: Type, …)` (works, prints 7) vs `idwrap :: (T: Type, …)` (prints `T{}`). ## Investigation prompt In [src/ir/lower.zig](../src/ir/lower.zig), `resolveTypeWithBindings` resolves a `.type_expr` named `T` by checking `type_bindings` (works for `$T`, which `buildTypeBindings` registers). For a non-`$` `T: Type` param there is no binding, so resolution falls through to `type_bridge.resolveAstType`, which fabricates an empty-struct stub for the unknown name `T` — the classic "silent empty struct" the CLAUDE.md REJECTED-PATTERNS warn about. Fix options: (1) at scan/sema time, reject referencing a non-`$` `Type`-typed param in a type position with a diagnostic ("type parameter must be introduced with `$` — write `$T: Type`"); or (2) make `resolveAstType` return `.unresolved` + a diagnostic for an unknown bare type name in a generic-eligible position, instead of stubbing `{}`. Deferred — orthogonal to ERR; the working `$T` idiom exists. Low priority but should not stay silent.