# 0062 — generic function with a value-carrying `!` return miscompiles ## Symptom A generic function whose return type is a value-carrying failable in the generic type param — `wrap :: (T: type, …) -> (T, !E)` — does not substitute `T` in the failable return tuple during monomorphization. Observed two ways: - Consumed via `catch`: `LLVM verification failed: PHI node operands are not the same type as the result!` — the success branch carries `{}` (an unsubstituted / empty value) while the handler branch carries the real success type. - Consumed via destructure: the success value renders as `T{}` (the literal generic type name) instead of the concrete value, and the error slot is wrong. Expected: `T` is bound to the concrete monomorphization type (`s32`), the success value flows through as `7`, and the error slot is `0` on success. ## Reproduction ```sx #import "modules/std.sx"; E :: error { Bad } wrap :: (T: type, f: Closure() -> (T, !E)) -> (T, !E) { return try f(); } main :: () -> s32 { // catch form → LLVM phi type mismatch: r := wrap(s32, closure(() -> (s32, !E) { return 7; })) catch e -1; print("{}\n", r); // want 7 return 0; } ``` Destructure form (same root cause, different surfacing): ```sx r, err := wrap(s32, closure(() -> (s32, !E) { return 7; })); print("{} {}\n", r, xx err); // prints "T{} s64"; want "7 0" ``` ## Investigation prompt The bug is in monomorphizing a value-carrying failable return type in [src/ir/lower.zig](../src/ir/lower.zig). `monomorphizeFunction` (~10259) / `resolveReturnType2` (~8309) resolve the return type under `type_bindings` (`$T` → concrete). For a plain `-> T` this works; for `-> (T, !E)` the value slot `T` of the failable tuple appears NOT to be substituted — the success value stays the unsubstituted generic type (rendering as `T{}` / an empty `{}` in IR), so `lowerFailableSuccessReturn` / `extractSuccessValue` and the `try` success path produce a value of the wrong type, which the `catch` merge phi then rejects. Likely fix: ensure the failable-tuple return type is re-resolved through `type_bindings` during monomorphization (the tuple's value fields, not just a top-level `$T`), and that `failableSuccessType` / the `try`/`catch` success extraction use the substituted tuple. Verify with both repros above (catch → prints 7; destructure → prints "7 0"). This is ERR E5.1 sub-feature 8 (generic functions with `!` returns); the program-wide shape-union slice deliberately excluded generic shapes pending this fix.