Logo Xantham

UsedTypars Module

Functions and values

Function or value Description

aliasKeepsTypars ctx typ

Full Usage: aliasKeepsTypars ctx typ

Parameters:
Returns: bool

True when the alias's emitted declaration keeps its declared typars: at least one declared typar is rendered by the body. All-or-nothing (fully-phantom prune only); partial (subset) pruning needs slot-wise arg alignment in the reference arms and is deliberately out of scope.

ctx : GeneratorContext
typ : TypeAlias
Returns: bool

literalMemberTyparNames ctx rt

Full Usage: literalMemberTyparNames ctx rt

Parameters:
Returns: Set<string>

Name-set convenience over `literalMemberTyparNodes` (the caseLiteralRef filter).

ctx : GeneratorContext
rt : ResolvedType
Returns: Set<string>

literalMemberTyparNodes ctx rt

Full Usage: literalMemberTyparNodes ctx rt

Parameters:
Returns: TypeParameter list

Free TypeParameter NODES referenced by a hoisted LITERAL's members, in first-encounter order, deduped by name — the HOME-side walk for the lambda-lift: unlike the decl oracle above (which excludes literal members where no lift renders them), a LIFTED home does render its members, so the home's declared typars come from exactly this set. Nodes (not just names) so the home decl can carry real TypeParameterRenders. Same reference-arm mirror, same guards.

ctx : GeneratorContext
rt : ResolvedType
Returns: TypeParameter list

usedTyparNames ctx body

Full Usage: usedTyparNames ctx body

Parameters:
Returns: Set<string>
 THE single emitted-typar oracle for type-alias declarations.

 A generic alias whose checker-collapsed body no longer RENDERS any of its declared type
 parameters (`type AgentNamespace<'Agentic> = option`) is a PHANTOM-TYPAR alias — F#
 rejects an abbreviation with unused typars. The decl-side prune (Render.TypeAlias) and the
 ref-side arity oracle (prerenderTypeAliases -> TypeAliasArity -> the cdc0108/general-args
 alignment) MUST agree, or the surface emits `Name` against `type Name = ...` (the
 511->707 reverted-regression class). Both sides therefore call THIS function — same
 computation, same instance — so they cannot diverge. There is deliberately NO path-keyed
 cache table: TypePath is not injective (lib.dom/workers twins, the Typescript-parent prune)
 and a keyed table reintroduces cross-alias clobber.

 The walk MIRRORS the prerender arms' rendering semantics — a typar counts as USED only where
 the render would actually emit it:
   - `ResolvedType.TypeParameter`         -> used (the bare-typar render arm emits it).
   - Union/Intersection/Tuple/Array/...   -> recurse (all components render).
   - `TypeReference` args                 -> used only where an APPLY arm would render them
     (the cdc0108 arm: remap-keyed alias body or generic Interface/Class head; the general
     args arm) and NOT where a DROP arm discards them (inner already-instantiated reference;
     resolved-body guard failure). Cross-alias truncation is over-approximated at DECLARED
     arity (never another alias's emitted arity — that would be a cross-alias fixpoint).
   - `TypeLiteral`/`Interface`/`Class` MEMBERS -> NOT used: a typar living only inside a
     hoisted structural body is SCRUBBED to `obj` at its emitted home today (the a5a2652
     anchor-stage orphan guard), so the alias decl never renders it. The stage-D lambda-lift
     flips this per-literal when a home actually abstracts over its free typars.

 FAIL-SAFE DIRECTIONS (why mirror drift cannot hard-break): counting an unused typar as used
 (over-keep) leaves the status-quo unused-typar diagnostic; missing a used one (over-prune)
 lets the body's typar occurrence hit the anchor-stage orphan scrub and erase to `obj`. Both
 are soft; the arity-agreement gate measures outcomes mechanically.

 ORDERING CONTRACT: the remap-keyed test consults `ctx.TypeAliasRemap`, so this must run only
 after prerenderTypeAliases PHASE 1 has registered EVERY alias remap (the two-phase split) —
 mid-registration consultation makes prune decisions enumeration-order-dependent.

 Cycle-safe (ReferenceEquality visited set; the interner never forces outgoing lazies at
 construction, so per-node forcing terminates) and dangling-key-guarded: a lazy whose TypeKey
 is missing from the type map (the lib.dom-twin class) throws on force — degrade that branch
 to "no typars used" with a diagnostic instead of crashing the generation.
ctx : GeneratorContext
body : ResolvedType
Returns: Set<string>

Type something to start searching.