@scriptc/compiler 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/backend/emission/emit-exprs.js +47 -1
  2. package/dist/backend/emission/emit-exprs.js.map +1 -1
  3. package/dist/backend/emission/emit-island.js +9 -1
  4. package/dist/backend/emission/emit-island.js.map +1 -1
  5. package/dist/backend/emission/emit-stmts.js +3 -1
  6. package/dist/backend/emission/emit-stmts.js.map +1 -1
  7. package/dist/backend/emission/emit-walkers.js +22 -8
  8. package/dist/backend/emission/emit-walkers.js.map +1 -1
  9. package/dist/backend/emission/emitter.js +12 -1
  10. package/dist/backend/emission/emitter.js.map +1 -1
  11. package/dist/backend/emission/may-throw.js +4 -3
  12. package/dist/backend/emission/may-throw.js.map +1 -1
  13. package/dist/backend/llvm/emitter.js +105 -9
  14. package/dist/backend/llvm/emitter.js.map +1 -1
  15. package/dist/diagnostics/diagnostic.d.ts +49 -1
  16. package/dist/diagnostics/diagnostic.js +119 -5
  17. package/dist/diagnostics/diagnostic.js.map +1 -1
  18. package/dist/frontend/lib-contract.d.ts +114 -0
  19. package/dist/frontend/lib-contract.js +372 -0
  20. package/dist/frontend/lib-contract.js.map +1 -0
  21. package/dist/frontend/lowering/lower-builtins.js +16 -1
  22. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  23. package/dist/frontend/lowering/lower-calls.d.ts +47 -7
  24. package/dist/frontend/lowering/lower-calls.js +560 -36
  25. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  26. package/dist/frontend/lowering/lower-classes.d.ts +14 -1
  27. package/dist/frontend/lowering/lower-classes.js +85 -15
  28. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  29. package/dist/frontend/lowering/lower-containers.js +43 -1
  30. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  31. package/dist/frontend/lowering/lower-emitter.js +1 -1
  32. package/dist/frontend/lowering/lower-emitter.js.map +1 -1
  33. package/dist/frontend/lowering/lower-exprs.d.ts +26 -3
  34. package/dist/frontend/lowering/lower-exprs.js +474 -44
  35. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  36. package/dist/frontend/lowering/lower-island.d.ts +7 -0
  37. package/dist/frontend/lowering/lower-island.js +71 -10
  38. package/dist/frontend/lowering/lower-island.js.map +1 -1
  39. package/dist/frontend/lowering/lower-mixins.d.ts +1 -1
  40. package/dist/frontend/lowering/lower-mixins.js +1 -1
  41. package/dist/frontend/lowering/lower-modules.js +95 -4
  42. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  43. package/dist/frontend/lowering/lower-stmts.js +430 -44
  44. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  45. package/dist/frontend/lowering/lowerer.d.ts +19 -3
  46. package/dist/frontend/lowering/lowerer.js +188 -11
  47. package/dist/frontend/lowering/lowerer.js.map +1 -1
  48. package/dist/frontend/types.d.ts +28 -1
  49. package/dist/frontend/types.js +300 -8
  50. package/dist/frontend/types.js.map +1 -1
  51. package/dist/index.d.ts +11 -2
  52. package/dist/index.js +96 -7
  53. package/dist/index.js.map +1 -1
  54. package/dist/ir/nodes.d.ts +48 -2
  55. package/dist/ir/nodes.js +103 -3
  56. package/dist/ir/nodes.js.map +1 -1
  57. package/dist/ir/validate.js +35 -6
  58. package/dist/ir/validate.js.map +1 -1
  59. package/dist/library/profile.d.ts +53 -3
  60. package/dist/library/profile.js +143 -12
  61. package/dist/library/profile.js.map +1 -1
  62. package/dist/library/sidecar-validate.d.ts +4 -0
  63. package/dist/library/sidecar-validate.js +506 -0
  64. package/dist/library/sidecar-validate.js.map +1 -0
  65. package/dist/library/sidecar.d.ts +191 -0
  66. package/dist/library/sidecar.js +687 -0
  67. package/dist/library/sidecar.js.map +1 -0
  68. package/dist/library/trap-teaching.d.ts +11 -0
  69. package/dist/library/trap-teaching.js +49 -0
  70. package/dist/library/trap-teaching.js.map +1 -0
  71. package/dist/library/wyhash.d.ts +12 -0
  72. package/dist/library/wyhash.js +116 -0
  73. package/dist/library/wyhash.js.map +1 -0
  74. package/package.json +2 -2
  75. package/surface-manifest.json +37 -2
@@ -41,6 +41,8 @@ export type WidthLift = {
41
41
  how: "objWidth";
42
42
  } | {
43
43
  how: "clsWidth";
44
+ } | {
45
+ how: "narrow";
44
46
  };
45
47
  export declare class PoisonError extends Error {
46
48
  }
@@ -355,6 +357,12 @@ export declare class Lowerer {
355
357
  /** Non-null while an instance body lowers: type-parameter symbol →
356
358
  * concrete IR type, consulted inside mapType's recursion. */
357
359
  typeParamBindings: Map<ts.Symbol, IrType> | null;
360
+ /** The ts-level twin of typeParamBindings, non-null while a CALL-keyed
361
+ * instance body lowers: type-parameter symbol → the bound CHECKER type,
362
+ * consulted where the mapped IrType has already widened away information
363
+ * the body needs — indexed accesses (`T[K]` needs K's literal key) and
364
+ * keyed record reads (`o[k]` where k's type is a literal-bound K). */
365
+ typeParamTsBindings: Map<ts.Symbol, ts.Type> | null;
358
366
  /** Non-null while an IMPLICIT-ANY instance body lowers (npm-static JS —
359
367
  * lower-calls' implicit-monomorphization section): bound param symbol →
360
368
  * the call site's checker type, consulted by typeOf for identifier
@@ -880,6 +888,12 @@ export declare class Lowerer {
880
888
  * (`T`, `T[]`, `{ v: T }`, `(x: T) => T` all resolve). Inert outside
881
889
  * generic instantiation. */
882
890
  readonly typeParamResolver: (t: ts.Type) => IrType | null;
891
+ /** The ts-level twin of typeParamResolver: the bound CHECKER type of a
892
+ * type parameter in the current instantiation (typeParamTsBindings), for
893
+ * the resolutions where mapType's widening already dropped what the body
894
+ * needs (indexed accesses over literal-bound keys). Inert outside
895
+ * call-keyed generic instantiation. */
896
+ readonly typeParamTsResolver: (t: ts.Type) => ts.Type | null;
883
897
  irTypeOf(node: ts.Node): IrType;
884
898
  /** Exact-shape enforcement (SC2002). Records are monomorphic structs, so
885
899
  * everywhere a value flows into a typed slot (call arg, initializer,
@@ -1370,7 +1384,7 @@ export declare class Lowerer {
1370
1384
  genericFnOf(ident: ts.Identifier): GenericFnInfo | null;
1371
1385
  lowerGenericCall(expr: ts.CallExpression, info: GenericFnInfo): IrExpr;
1372
1386
  lowerGenericFnValue(ref: ts.Expression, info: GenericFnInfo): IrExpr;
1373
- inferTypeParamBindings(expr: ts.CallExpression, info: GenericFnInfo, rsig: ts.Signature): Map<ts.Symbol, IrType>;
1387
+ inferTypeParamBindings(expr: ts.CallExpression, info: GenericFnInfo, rsig: ts.Signature, tsBindings?: Map<ts.Symbol, ts.Type>): Map<ts.Symbol, IrType>;
1374
1388
  lowerGenericInstance(info: GenericFnInfo, inst: GenericInstance): IrFunction;
1375
1389
  collectClassShape(decl: ts.ClassDeclaration): void;
1376
1390
  collectClassShapeInner(decl: ts.ClassLikeDeclaration, jsNameOverride?: string, inst?: {
@@ -1610,9 +1624,11 @@ export declare class Lowerer {
1610
1624
  isStdlibSymbol(symbol: ts.Symbol | undefined): boolean;
1611
1625
  isStdlibGlobal(expr: ts.Expression, name: string): boolean;
1612
1626
  stdlibGlobalMember(access: ts.PropertyAccessExpression, name: string): string | null;
1613
- lowerArrayLiteral(expr: ts.ArrayLiteralExpression, expected?: IrType & {
1627
+ lowerArrayLiteral(expr: ts.ArrayLiteralExpression, expected?: (IrType & {
1614
1628
  kind: "array";
1615
- }): IrExpr;
1629
+ }) | (IrType & {
1630
+ kind: "record";
1631
+ })): IrExpr;
1616
1632
  lowerObjectLiteral(expr: ts.ObjectLiteralExpression): IrExpr;
1617
1633
  lowerShorthandValue(prop: ts.ShorthandPropertyAssignment): IrExpr;
1618
1634
  rejectThisInObjectMethod(node: ts.Node): void;
@@ -14,11 +14,11 @@
14
14
  */
15
15
  import { isRelativeSpecifier } from "../shared.js";
16
16
  import * as ts from "../ts7/adapter.js";
17
- import { anyOpRequiresDynamicDiag, blockedBindingUseDiag, checkerPanicDiag, isCheckerPanic, genericSignatureTypeDiag, indexSignatureTypeDiag, noLoweringDiag, recordShapeMismatchDiag, requiresDynamicApiDiag, requiresDynamicPackageDiag, requiresDynamicTypeDiag, unionMismatchDiag, unsupportedDiag, unsupportedTypeDiag, } from "../../diagnostics/diagnostic.js";
17
+ import { anyOpRequiresDynamicDiag, blockedBindingUseDiag, checkerPanicDiag, componentTypeDiag, isCheckerPanic, genericSignatureTypeDiag, indexSignatureTypeDiag, intersectionTypeDiag, noLoweringDiag, overloadedSignatureTypeDiag, recordShapeMismatchDiag, requiresDynamicApiDiag, requiresDynamicPackageDiag, requiresDynamicTypeDiag, unionMismatchDiag, unsupportedDiag, unsupportedTypeDiag, } from "../../diagnostics/diagnostic.js";
18
18
  import { arrayOf, BOOL, canAdaptDynFuncTo, canConvertToDyn, canCrossIslandBoundary, canExitIslandToType, canMarshalTypedFuncIntoIsland, DYN, F64, isJsonSafeType, isUndefinedArmedUnion, isUnitType, JSVAL, RUNTIME_ERROR_CLASSES, STRING, typeEquals, UNDEFINED_T, VOID } from "../../ir/nodes.js";
19
19
  import { provenanceActive } from "../provenance-registry.js";
20
20
  import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
21
- import { containsRecord, containsUnion, formatIrType, ISLAND_AMBIENT_TYPES, isUnitOnlyTsType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../types.js";
21
+ import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, ISLAND_AMBIENT_TYPES, isUnitOnlyTsType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../types.js";
22
22
  import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtinModuleConstOf, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalMember, nodeTypesOnlySymbol } from "./surfaces.js";
23
23
  import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules } from "./lower-modules.js";
24
24
  import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, findGenericMethodOn, findGenericStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorMessageArg, lowerNew, accessorCall } from "./lower-classes.js";
@@ -27,7 +27,7 @@ import { bindingNeverReassigned, bodyReadsArguments, isThisParameter, paramShape
27
27
  import { lowerArrayMethodCall, lowerBufferStaticCall, lowerBytesMethodCall, lowerBytesNew, lowerMapMethodCall, lowerMapForEachCall, buildMapForEachFn, lowerRecordOvfCaptureHelper, lowerEnvToPairsHelper, lowerSetMethodCall, lowerSetForEachCall, buildSetForEachFn, lowerRegexMethodCall, lowerStringMethodCall } from "./lower-containers.js";
28
28
  import { lowerStreamModuleCall } from "./lower-stream.js";
29
29
  import { builtinImportOf, lowerBuiltinModuleCall, lowerChildArgsArg, lowerSpawnSyncCall, lowerSpawnCall, lowerExecSyncCall, recordToEnvPairs, lowerJsonMethodCall, fencedBuiltinImportOf, lowerCryptoComposedCall, lowerUrlMethodCall, lowerSearchParamsMethodCall, lowerStatsMethodCall, lowerChildMethodCall, lowerAtomicsCall, lowerBuiltinExtraProperty, promisifiedExecFileDecl, lowerExecFileAsyncCall, execFileAsyncHelper, lowerStringDecoderMethodCall, strdecHelper, lowerReadlineMethodCall, lowerDcChannelMethodCall, lowerDcChannelProperty, lowerAlsMethodCall, lowerDcTracingChannelMethodCall, lowerDcTracingChannelProperty, lowerJsonProperty, lowerErrorCodeProperty, lowerProcessProperty, isProcessEnv, envValueType, lowerProcessEnvGet, lowerProcessMethodCall, lowerProcessOptionalMethodCall, lowerTimeoutMethodCall, envSnapshotHelper, isConsoleLog, consoleCallMember, lowerNumberStaticCall, lowerNumberStaticProperty, lowerDateCall, lowerTextCodecCall, lowerFsConstantsProperty, lowerHttp2ConstantsProperty, http2ConstantBindingOf, http2ConstantsDestructureDecl, lowerProcessStreamProperty, lowerStringStaticCall, lowerStringLastIndexOfCall, lowerPromiseStaticCall } from "./lower-builtins.js";
30
- import { isIslandExpr, islandRegexpOf, jsvalIn, requireDynamicApi, islandGlobalFnOf, lowerDynamicImportCall, lowerFetchCall, lowerIslandMethodCall, lowerMathProperty, npmPackageOf, npmMemberFence, npmPackageOfSymbol } from "./lower-island.js";
30
+ import { isIslandExpr, islandFuncValueFence, islandRegexpOf, jsvalIn, requireDynamicApi, islandGlobalFnOf, lowerDynamicImportCall, lowerFetchCall, lowerIslandMethodCall, lowerMathProperty, npmPackageOf, npmMemberFence, npmPackageOfSymbol } from "./lower-island.js";
31
31
  import { lowerHttpHeadersElement, lowerNetModuleCall, lowerServerMethodCall, lowerServerProperty } from "./lower-server.js";
32
32
  import { lowerDgramDnsModuleCall, lowerDgramMethodCall } from "./lower-dgram.js";
33
33
  import { lowerNodeTestModuleCall, lowerTestDirectCall, lowerTestMethodCall, lowerTestCtxProperty } from "./lower-test.js";
@@ -35,7 +35,7 @@ import { lowerAssertModuleCall, lowerAssertDirectCall } from "./lower-assert.js"
35
35
  import { lowerUtilModuleCall } from "./lower-inspect.js";
36
36
  import { lowerComptime, comptimeBakeable, rejectComptimeCaptures, comptimeValueToIr } from "./lower-comptime.js";
37
37
  import { lowerStmts, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, rejectJumpCrossingFinally, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, lowerJsvalBindingPattern, checkBindingElement, bindPatternTarget, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement } from "./lower-stmts.js";
38
- import { lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerOptionalChain, finishOptionalChain, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerObjectLiteral, lowerShorthandValue, rejectThisInObjectMethod, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf, foldedStringKeyOf } from "./lower-exprs.js";
38
+ import { lowerDynObjectLiteral, lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerOptionalChain, finishOptionalChain, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerObjectLiteral, lowerShorthandValue, rejectThisInObjectMethod, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf, foldedStringKeyOf } from "./lower-exprs.js";
39
39
  import { lowerRecordFieldCall, lowerObjectMethodCall } from "./lower-calls.js";
40
40
  import { fenceCrossBlockNsRef, nsPathPrefix } from "./lower-namespaces.js";
41
41
  /** Entry function name. '%' cannot appear in a TS identifier, so a user
@@ -468,6 +468,12 @@ export class Lowerer {
468
468
  /** Non-null while an instance body lowers: type-parameter symbol →
469
469
  * concrete IR type, consulted inside mapType's recursion. */
470
470
  typeParamBindings = null;
471
+ /** The ts-level twin of typeParamBindings, non-null while a CALL-keyed
472
+ * instance body lowers: type-parameter symbol → the bound CHECKER type,
473
+ * consulted where the mapped IrType has already widened away information
474
+ * the body needs — indexed accesses (`T[K]` needs K's literal key) and
475
+ * keyed record reads (`o[k]` where k's type is a literal-bound K). */
476
+ typeParamTsBindings = null;
471
477
  /** Non-null while an IMPLICIT-ANY instance body lowers (npm-static JS —
472
478
  * lower-calls' implicit-monomorphization section): bound param symbol →
473
479
  * the call site's checker type, consulted by typeOf for identifier
@@ -811,6 +817,7 @@ export class Lowerer {
811
817
  unions: this.unions,
812
818
  classNamer: this.classNamer,
813
819
  resolveTypeParam: this.typeParamResolver,
820
+ resolveTypeParamTs: this.typeParamTsResolver,
814
821
  genericClassInstance: (decl, ref) => this.genericClassInstanceType(decl, ref),
815
822
  mixinClassInstance: (decl) => this.mixinTypeContext && this.mixinTypeContext.classNode === decl
816
823
  ? { kind: "object", className: this.mixinTypeContext.className }
@@ -1904,6 +1911,59 @@ export class Lowerer {
1904
1911
  this.pushDiag(requiresDynamicTypeDiag(this.checker.typeToString(type), locOf(node)));
1905
1912
  throw new PoisonError();
1906
1913
  }
1914
+ // STANDARD-LIBRARY nominal provenance, decided once: interface/class
1915
+ // declarations in the lib's own files (Date, ArrayBuffer, WeakMap, the
1916
+ // iterator/constructor interfaces). Such types report the SC2020 story
1917
+ // below — the same one the index-signature-carrying lib types above
1918
+ // tell — rather than an overload/record claim no user can act on.
1919
+ const stdlibOwnSym = widened.getSymbol();
1920
+ const stdlibNominal = stdlibOwnSym !== undefined &&
1921
+ this.checker.declarationsOf(stdlibOwnSym).some((d) => (ts.isInterfaceDeclaration(d) || ts.isClassDeclaration(d)) &&
1922
+ this.isStdlibFile(d.getSourceFile()));
1923
+ // OVERLOADED call signatures (SC2007) — after the generic branch, so a
1924
+ // generic overload set keeps the monomorphization story: a value of a
1925
+ // multi-signature type has no single compiled signature to hold.
1926
+ if (!stdlibNominal && this.checker.getCallSignatures(widened).length > 1) {
1927
+ this.pushDiag(overloadedSignatureTypeDiag(this.checker.typeToString(type), locOf(node)));
1928
+ throw new PoisonError();
1929
+ }
1930
+ // INTERSECTIONS that resolved to no lowering (SC2008). The ones that
1931
+ // compile never get here: member intersections intern through the
1932
+ // record path, callable hybrids map to '%call' records, and pinned
1933
+ // mixin instantiations resolve by chain structure.
1934
+ if (widened.isIntersectionType()) {
1935
+ this.pushDiag(intersectionTypeDiag(this.checker.typeToString(type), locOf(node)));
1936
+ throw new PoisonError();
1937
+ }
1938
+ // SUPPORTED shapes over a component outside its slot (SC2009): the
1939
+ // Map/Set domains, array/tuple elements, union arms, function
1940
+ // parameters/returns. The container is not the blocker — name the
1941
+ // component instead of reciting the supported set. Checked BEFORE the
1942
+ // lib claim so Map/Set/Promise instantiation failures keep their
1943
+ // component story (describeComponentBlocker always answers for those
1944
+ // heads).
1945
+ {
1946
+ const detail = describeComponentBlocker(widened, this.typeCtx);
1947
+ if (detail !== null) {
1948
+ this.pushDiag(componentTypeDiag(this.checker.typeToString(type), detail, locOf(node)));
1949
+ throw new PoisonError();
1950
+ }
1951
+ }
1952
+ // STANDARD-LIBRARY nominal types with no lowering at all: the SC2020
1953
+ // story, naming the type.
1954
+ if (stdlibNominal) {
1955
+ this.pushDiag(noLoweringDiag(this.checker.typeToString(type), locOf(node)));
1956
+ throw new PoisonError();
1957
+ }
1958
+ // USER record shapes blocked by ONE member (SC2009's record arm):
1959
+ // name the member and its type.
1960
+ {
1961
+ const detail = describeRecordMemberBlocker(widened, this.typeCtx);
1962
+ if (detail !== null) {
1963
+ this.pushDiag(componentTypeDiag(this.checker.typeToString(type), detail, locOf(node)));
1964
+ throw new PoisonError();
1965
+ }
1966
+ }
1907
1967
  this.pushDiag(unsupportedTypeDiag(this.checker.typeToString(type), locOf(node)));
1908
1968
  throw new PoisonError();
1909
1969
  }
@@ -2051,6 +2111,17 @@ export class Lowerer {
2051
2111
  const sym = t.getSymbol();
2052
2112
  return (sym && this.typeParamBindings.get(sym)) ?? null;
2053
2113
  };
2114
+ /** The ts-level twin of typeParamResolver: the bound CHECKER type of a
2115
+ * type parameter in the current instantiation (typeParamTsBindings), for
2116
+ * the resolutions where mapType's widening already dropped what the body
2117
+ * needs (indexed accesses over literal-bound keys). Inert outside
2118
+ * call-keyed generic instantiation. */
2119
+ typeParamTsResolver = (t) => {
2120
+ if (!this.typeParamTsBindings || !(t.flags & ts.TypeFlags.TypeParameter))
2121
+ return null;
2122
+ const sym = t.getSymbol();
2123
+ return (sym && this.typeParamTsBindings.get(sym)) ?? null;
2124
+ };
2054
2125
  irTypeOf(node) {
2055
2126
  const t = this.typeOf(node);
2056
2127
  // A never-tainted JS type (neverTaintedJsType) maps — never rides as
@@ -2667,6 +2738,15 @@ export class Lowerer {
2667
2738
  return null;
2668
2739
  return { how: "liftWrap", tag: candidates[0].tag, arm: candidates[0].arm };
2669
2740
  }
2741
+ // A UNION source into a slot that is ONE of its arms (a width copy
2742
+ // whose target field narrowed — the option-table choices shape:
2743
+ // `value: boolean | string` copying into a `value: string` slot the
2744
+ // checker approved): the CHECKED extraction — narrowedArmHelper,
2745
+ // exactly `x!`'s machinery — the proven arm's payload comes out, any
2746
+ // other arm throws the catchable TypeError (divergence 38's stance).
2747
+ if (src.kind === "union" && !isUnitType(dst) && dst.kind !== "void" && this.armTag(src.unionId, dst) >= 0) {
2748
+ return { how: "narrow" };
2749
+ }
2670
2750
  if (dst.kind === "record" && src.kind === "record") {
2671
2751
  return this.recordWidthPlan(src.shapeId, dst.shapeId) !== null ? { how: "width" } : null;
2672
2752
  }
@@ -2786,6 +2866,14 @@ export class Lowerer {
2786
2866
  throw new Error("lowerer bug: planned clsWidth lift failed to intern");
2787
2867
  return { kind: "call", callee: helper, args: [value], type: dst, loc };
2788
2868
  }
2869
+ case "narrow": {
2870
+ if (value.type.kind !== "union")
2871
+ throw new Error("lowerer bug: narrow lift on a non-union");
2872
+ const helper = this.narrowedArmHelper(value.type.unionId, dst, loc);
2873
+ if (!helper)
2874
+ throw new Error("lowerer bug: planned narrow lift failed to intern");
2875
+ return { kind: "call", callee: helper, args: [value], type: dst, loc };
2876
+ }
2789
2877
  default: {
2790
2878
  const _exhaustive = lift;
2791
2879
  void _exhaustive;
@@ -3503,8 +3591,14 @@ export class Lowerer {
3503
3591
  return this.boundaryExitSafe(dst);
3504
3592
  if (dst.kind === "dyn")
3505
3593
  return src.kind !== "dyn" && this.dynConvertible(src);
3506
- if (src.kind === "dyn")
3507
- return this.jsonSafe(dst);
3594
+ if (src.kind === "dyn") {
3595
+ // The checked-dynamic function boundary's OUT direction joins the
3596
+ // mechanical set: a dyn result landing in an adaptable func slot
3597
+ // takes dynCheck's per-target shim (coerceToExpected's funcOk rule
3598
+ // — the production/development function-choice ternary shape).
3599
+ return (this.jsonSafe(dst) ||
3600
+ (dst.kind === "func" && canAdaptDynFuncTo(dst, (id) => this.shapes.get(id), (id) => this.unions.get(id))));
3601
+ }
3508
3602
  if (dst.kind === "union") {
3509
3603
  if (src.kind === "union")
3510
3604
  return this.unionRetagMappable(src.unionId, dst.unionId);
@@ -3552,10 +3646,19 @@ export class Lowerer {
3552
3646
  strandParams = true;
3553
3647
  }
3554
3648
  let voidRet = null;
3649
+ let strandRet = false;
3555
3650
  if (toT.ret.kind !== "void" && !this.coercibleValue(fromT.ret, toT.ret)) {
3556
- if (fromT.ret.kind !== "void")
3557
- return null;
3558
- voidRet = toT.ret.kind === "dyn" ? "dyn" : toT.ret.kind === "jsval" ? "jsval" : "strand";
3651
+ if (fromT.ret.kind !== "void") {
3652
+ // A RESULT that cannot convert — the strandParams stance, result
3653
+ // side (the production/development function-choice ternary: the
3654
+ // untaken arm's result shape never lands in the slot's): the
3655
+ // assignment compiles, INVOKING the slot runs the function and
3656
+ // throws the stranded TypeError where its result would convert.
3657
+ strandRet = true;
3658
+ }
3659
+ else {
3660
+ voidRet = toT.ret.kind === "dyn" ? "dyn" : toT.ret.kind === "jsval" ? "jsval" : "strand";
3661
+ }
3559
3662
  }
3560
3663
  if (toT.ret.kind === "void" && fromT.ret.kind === "jsval")
3561
3664
  return null;
@@ -3623,6 +3726,12 @@ export class Lowerer {
3623
3726
  strandThrow(`a void result where the '${this.fmt(toT)}' slot promises '${this.fmt(toT.ret)}' (a thrower typed 'never' never reaches this; a genuinely void function has no result to hand over)`),
3624
3727
  ];
3625
3728
  }
3729
+ else if (strandRet) {
3730
+ body = [
3731
+ { kind: "exprStmt", expr: call, loc },
3732
+ strandThrow(`a '${this.fmt(fromT)}' function invoked through a '${this.fmt(toT)}' slot (the result cannot convert to '${this.fmt(toT.ret)}' — the checker's loose function compatibility admitted the assignment, but the call has no exact lowering)`),
3733
+ ];
3734
+ }
3626
3735
  else {
3627
3736
  const result = this.coerceToExpected(call, toT.ret);
3628
3737
  if (!typeEquals(result.type, toT.ret))
@@ -4646,6 +4755,25 @@ export class Lowerer {
4646
4755
  e = { kind: "call", callee: helper, args: [e], type: expected, loc: e.loc };
4647
4756
  }
4648
4757
  }
4758
+ // A JS FUNC value outside the island marshal set flowing into a
4759
+ // jsval slot (`withPlugins(getSupportInfoWithoutPlugins, 0)` — a
4760
+ // wrapper built at module init around a function the run may never
4761
+ // call): the crossing defers to a call-time fence closure instead of
4762
+ // stopping the statement — jsvalIn's deferral, the implicit-coercion
4763
+ // spelling.
4764
+ if (expected.kind === "jsval" && e.type.kind === "func" && !typeEquals(e.type, expected)) {
4765
+ const diagsBefore = this.diags.length;
4766
+ try {
4767
+ this.requireExactShape(node, e.type, expected);
4768
+ }
4769
+ catch (err) {
4770
+ const fence = islandFuncValueFence(this, err, diagsBefore, node);
4771
+ if (fence)
4772
+ return fence;
4773
+ throw err;
4774
+ }
4775
+ return e;
4776
+ }
4649
4777
  this.requireExactShape(node, e.type, expected);
4650
4778
  return e;
4651
4779
  }
@@ -4732,6 +4860,55 @@ export class Lowerer {
4732
4860
  return this.coerceInto(node, this.lowerArrayLiteral(x, expected), expected);
4733
4861
  }
4734
4862
  }
4863
+ // An OBJECT LITERAL against a checked-dynamic slot in a JS file (the
4864
+ // getSupportInfo options argument — a dyn-ABI param): the value's
4865
+ // world IS the DOM — build the DOM literal directly, before the
4866
+ // island gate could claim the checker's `any` context (an island
4867
+ // build could never land in the slot: no engine→DOM crossing).
4868
+ if (expected?.kind === "dyn") {
4869
+ let x = node;
4870
+ while (ts.isParenthesizedExpression(x))
4871
+ x = x.expression;
4872
+ if (ts.isObjectLiteralExpression(x) && isJsSourceFile(x.getSourceFile())) {
4873
+ return lowerDynObjectLiteral(this, x);
4874
+ }
4875
+ }
4876
+ // An ARRAY LITERAL against a UNION slot whose own type has no static
4877
+ // home (the JS dyn fallback — the checker gave no usable context):
4878
+ // when the union has exactly ONE array-family arm — an array, or an
4879
+ // arity-matching tuple (the option-table `default: [{ value: [] }]`
4880
+ // shape) — build AS that arm and wrap; the IR-directed twin of
4881
+ // lowerArrayLiteral's contextual-union rule.
4882
+ if (expected?.kind === "union") {
4883
+ let x = node;
4884
+ while (ts.isParenthesizedExpression(x))
4885
+ x = x.expression;
4886
+ if (ts.isArrayLiteralExpression(x)) {
4887
+ const own = this.mapTypeOf(this.checker.getContextualType(x) ?? this.typeOf(x));
4888
+ // Elements beyond bare null/undefined literals can never live in
4889
+ // a unit-only-element array — a checker type that degraded to one
4890
+ // (`[]`-flavored inference over a populated literal) carries no
4891
+ // element information.
4892
+ const nonUnitElems = x.elements.some((el) => !ts.isOmittedExpression(el) &&
4893
+ el.kind !== ts.SyntaxKind.NullKeyword &&
4894
+ !(ts.isIdentifier(el) && el.text === "undefined"));
4895
+ if (own === null || own.kind === "dyn" || own.kind === "jsval" ||
4896
+ (own.kind === "array" && nonUnitElems && this.unitOnlyElem(own.elem)) ||
4897
+ this.widthLiftPlan(own, expected) === null) {
4898
+ const def = this.unions.get(expected.unionId);
4899
+ const arms = (def?.arms ?? []).filter((a) => (a.kind === "array" && !(nonUnitElems && this.unitOnlyElem(a.elem))) ||
4900
+ (a.kind === "record" &&
4901
+ !!this.shapes.get(a.shapeId)?.tuple &&
4902
+ this.shapes.get(a.shapeId).fields.length === x.elements.length &&
4903
+ !x.elements.some(ts.isSpreadElement)));
4904
+ if (arms.length === 1) {
4905
+ const arm = arms[0];
4906
+ const built = this.lowerArrayLiteral(x, arm);
4907
+ return this.coerceInto(node, built, expected);
4908
+ }
4909
+ }
4910
+ }
4911
+ }
4735
4912
  const e = this.lowerExpr(node);
4736
4913
  return expected ? this.coerceInto(node, e, expected) : e;
4737
4914
  }
@@ -4999,8 +5176,8 @@ export class Lowerer {
4999
5176
  lowerGenericFnValue(ref, info) {
5000
5177
  return lowerGenericFnValue(this, ref, info);
5001
5178
  }
5002
- inferTypeParamBindings(expr, info, rsig) {
5003
- return inferTypeParamBindings(this, expr, info, rsig);
5179
+ inferTypeParamBindings(expr, info, rsig, tsBindings) {
5180
+ return inferTypeParamBindings(this, expr, info, rsig, tsBindings);
5004
5181
  }
5005
5182
  lowerGenericInstance(info, inst) {
5006
5183
  return lowerGenericInstance(this, info, inst);