mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-07 08:33:50 +08:00
Key bound alias instances by the declared alias
The compiler compiles itself, and a Map keyed by another Map is outside the key domains it compiles (SC2009 in the self-hosted frontend). The Lowerer's table is now keyed by the declared alias reference: each entry lists the instances that instantiate it with their ts-level bindings maps, and the resolver picks the current instance's by identity.
This commit is contained in:
@@ -1041,11 +1041,12 @@ function unifySignatureBindings(
|
||||
iAliasArgs.length === dAliasArgs.length
|
||||
) {
|
||||
if (tsBindings && declared !== inst) {
|
||||
let pairs = lowerer.boundAliasInstances.get(tsBindings);
|
||||
if (!pairs) lowerer.boundAliasInstances.set(tsBindings, (pairs = new Map()));
|
||||
let entries = lowerer.boundAliasInstances.get(declared);
|
||||
if (!entries) lowerer.boundAliasInstances.set(declared, (entries = []));
|
||||
// A body forwarding its own alias (`inner(g)` returning `Catalog<G,
|
||||
// "x">` inside an instance) resolves through the enclosing one.
|
||||
if (!pairs.has(declared)) pairs.set(declared, lowerer.boundAliasTsResolver(inst) ?? inst);
|
||||
if (!entries.some((entry) => entry.tsBindings === tsBindings))
|
||||
entries.push({ tsBindings, instance: lowerer.boundAliasTsResolver(inst) ?? inst });
|
||||
}
|
||||
dAliasArgs.forEach((da, i) => {
|
||||
const ia = iAliasArgs[i];
|
||||
|
||||
@@ -2233,16 +2233,19 @@ export class Lowerer {
|
||||
* the body needs — indexed accesses (`T[K]` needs K's literal key) and
|
||||
* keyed record reads (`o[k]` where k's type is a literal-bound K). */
|
||||
typeParamTsBindings: Map<ts.Symbol, ts.Type> | null = null;
|
||||
/** Generic alias references of a call-keyed instance's declared signature
|
||||
* (`Catalog<G, P>`), each paired with the same alias as the call's
|
||||
* resolved signature instantiates it (`Catalog<{ g1: … }, "acme">`),
|
||||
* keyed by the instance's ts-level bindings (typeParamTsBindings). The
|
||||
* checker keeps the alias symbolic inside the generic body and offers no
|
||||
* way to instantiate it with the bound arguments, but alias
|
||||
* instantiations are interned: the body's `x as Catalog<G, P>` is the
|
||||
* very type the signature declares, so the pair recorded during binding
|
||||
* unification is that re-instantiation. */
|
||||
readonly boundAliasInstances = new Map<Map<ts.Symbol, ts.Type>, Map<ts.Type, ts.Type>>();
|
||||
/** Generic alias references of call-keyed instances' declared signatures
|
||||
* (`Catalog<G, P>`), each with the same alias as every call's resolved
|
||||
* signature instantiates it (`Catalog<{ g1: … }, "acme">`), together with
|
||||
* that instance's ts-level bindings map (typeParamTsBindings), which every
|
||||
* scope that lowers the instance installs. The checker keeps the alias
|
||||
* symbolic inside the generic body and offers no way to instantiate it
|
||||
* with the bound arguments, but alias instantiations are interned: the
|
||||
* body's `x as Catalog<G, P>` is the very type the signature declares, so
|
||||
* the pair recorded during unification is that re-instantiation. */
|
||||
readonly boundAliasInstances = new Map<
|
||||
ts.Type,
|
||||
{ tsBindings: Map<ts.Symbol, ts.Type>; instance: ts.Type }[]
|
||||
>();
|
||||
/** Non-null while an IMPLICIT-ANY instance body lowers (npm-static JS;
|
||||
* see generic-functions.ts): bound param symbol →
|
||||
* the call site's checker type, consulted by typeOf for identifier
|
||||
@@ -9563,10 +9566,15 @@ export class Lowerer {
|
||||
|
||||
/** The concrete instantiation of a generic alias reference (`Catalog<G,
|
||||
* P>`) the current call-keyed instance's signature declares
|
||||
* (boundAliasInstances). Inert outside generic function instantiation. */
|
||||
* (boundAliasInstances), or null when its signature never instantiated
|
||||
* that reference. Inert outside generic function instantiation. */
|
||||
readonly boundAliasTsResolver = (t: ts.Type): ts.Type | null => {
|
||||
if (!this.typeParamTsBindings || t.getAliasTypeArguments().length === 0) return null;
|
||||
return this.boundAliasInstances.get(this.typeParamTsBindings)?.get(t) ?? null;
|
||||
const tsBindings = this.typeParamTsBindings;
|
||||
return (
|
||||
this.boundAliasInstances.get(t)?.find((entry) => entry.tsBindings === tsBindings)?.instance ??
|
||||
null
|
||||
);
|
||||
};
|
||||
|
||||
irTypeOf(node: ts.Node): IrType {
|
||||
|
||||
Reference in New Issue
Block a user