Goal
Converge codegen's 4 overlapping type-resolvers into one canonical lookup: ctx.typeOf(expr). Every codegen site reads types through one path that hits the pre-codegen annotator cache first, then falls through to the live resolver.
Why
Before convergence, codegen has 4 ways to ask "what type is this?":
typeInference.resolveExpressionType(expr) — flat base lookup
typeInference.resolveExpressionTypeRich(expr) — enriched with sourceKind/fields
getVariableType(register) — SSA-register-keyed (post-generation)
- pre-codegen annotator cache (filled by
semantic/type-annotator.ts)
Two codegen sites could ask at different moments and get different answers — silent-wrong native code. 397 real divergences measured before PR #580.
Plan
Per memory/refactor-plan-2026-04-19.md step 5 ("TypedAST annotator pass").
Shipped
Remaining
Done-when
- Zero callers of
typeInference.resolveExpressionType / resolveExpressionTypeRich outside type-inference.ts recursion and type-annotator.ts
getVariableType either deleted or used only for SSA-register lookup (not as a type resolver)
- Stage 2 native self-host green throughout
Goal
Converge codegen's 4 overlapping type-resolvers into one canonical lookup:
ctx.typeOf(expr). Every codegen site reads types through one path that hits the pre-codegen annotator cache first, then falls through to the live resolver.Why
Before convergence, codegen has 4 ways to ask "what type is this?":
typeInference.resolveExpressionType(expr)— flat base lookuptypeInference.resolveExpressionTypeRich(expr)— enriched with sourceKind/fieldsgetVariableType(register)— SSA-register-keyed (post-generation)semantic/type-annotator.ts)Two codegen sites could ask at different moments and get different answers — silent-wrong native code. 397 real divergences measured before PR #580.
Plan
Per
memory/refactor-plan-2026-04-19.mdstep 5 ("TypedAST annotator pass").Shipped
Remaining
llvm-generator.ts:4246-4251(resolveExpressionType+Rich) — no external consumers after refactor(codegen): migrate member.ts to typeOf() #594getVariableType(register)consumers totypeOf(expr)where the AST is available (per-site judgment)memory/sema-migration-blockers.mdresolveExpressionTypeRichcalls outsidetype-inference.tsinternal recursion andsemantic/type-annotator.ts(legitimate cache-filling sink)Done-when
typeInference.resolveExpressionType/resolveExpressionTypeRichoutsidetype-inference.tsrecursion andtype-annotator.tsgetVariableTypeeither deleted or used only for SSA-register lookup (not as a type resolver)