mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-12 03:20:56 -06:00
Cache instantiation expression types early enough to prevent reentrancy during printback (#59931)
This commit is contained in:
parent
88809467e8
commit
e24cc01b08
@ -37401,9 +37401,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (exprType === silentNeverType || isErrorType(exprType) || !some(typeArguments)) {
|
||||
return exprType;
|
||||
}
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.instantiationExpressionTypes) {
|
||||
links.instantiationExpressionTypes = new Map();
|
||||
}
|
||||
if (links.instantiationExpressionTypes.has(exprType.id)) {
|
||||
return links.instantiationExpressionTypes.get(exprType.id)!;
|
||||
}
|
||||
let hasSomeApplicableSignature = false;
|
||||
let nonApplicableType: Type | undefined;
|
||||
const result = getInstantiatedType(exprType);
|
||||
links.instantiationExpressionTypes.set(exprType.id, result);
|
||||
const errorType = hasSomeApplicableSignature ? nonApplicableType : exprType;
|
||||
if (errorType) {
|
||||
diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable, typeToString(errorType)));
|
||||
|
||||
@ -6239,6 +6239,7 @@ export interface NodeLinks {
|
||||
potentialReflectCollisions?: Node[];
|
||||
potentialUnusedRenamedBindingElementsInTypes?: BindingElement[];
|
||||
externalHelpersModule?: Symbol; // Resolved symbol for the external helpers module
|
||||
instantiationExpressionTypes?: Map<number, Type>; // Cache of instantiation expression types for the node
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
instantiationExpressionErrorNoCrash.ts(15,38): error TS2344: Type 'typeof createCacheReducer<QR>' does not satisfy the constraint '(...args: any) => any'.
|
||||
Type 'typeof createCacheReducer<QR>' provides no match for the signature '(...args: any): any'.
|
||||
instantiationExpressionErrorNoCrash.ts(15,64): error TS2635: Type '<N extends string, QR>(queries: { [QK in keyof QR]: any; }) => (state?: { queries: QR; }) => { queries: QR; }' has no signatures for which the type argument list is applicable.
|
||||
|
||||
|
||||
==== instantiationExpressionErrorNoCrash.ts (2 errors) ====
|
||||
const createCacheReducer = <N extends string, QR>(
|
||||
queries: Cache<N, QR>["queries"],
|
||||
) => {
|
||||
const queriesMap = {} as QR;
|
||||
|
||||
const initialState = {
|
||||
queries: queriesMap,
|
||||
};
|
||||
|
||||
return (state = initialState) => state;
|
||||
};
|
||||
|
||||
export type Cache<N extends string, QR> = {
|
||||
queries: {
|
||||
[QK in keyof QR]: ReturnType<typeof createCacheReducer<QR>>;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2344: Type 'typeof createCacheReducer<QR>' does not satisfy the constraint '(...args: any) => any'.
|
||||
!!! error TS2344: Type 'typeof createCacheReducer<QR>' provides no match for the signature '(...args: any): any'.
|
||||
~~
|
||||
!!! error TS2635: Type '<N extends string, QR>(queries: { [QK in keyof QR]: any; }) => (state?: { queries: QR; }) => { queries: QR; }' has no signatures for which the type argument list is applicable.
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,34 @@
|
||||
//// [tests/cases/compiler/instantiationExpressionErrorNoCrash.ts] ////
|
||||
|
||||
//// [instantiationExpressionErrorNoCrash.ts]
|
||||
const createCacheReducer = <N extends string, QR>(
|
||||
queries: Cache<N, QR>["queries"],
|
||||
) => {
|
||||
const queriesMap = {} as QR;
|
||||
|
||||
const initialState = {
|
||||
queries: queriesMap,
|
||||
};
|
||||
|
||||
return (state = initialState) => state;
|
||||
};
|
||||
|
||||
export type Cache<N extends string, QR> = {
|
||||
queries: {
|
||||
[QK in keyof QR]: ReturnType<typeof createCacheReducer<QR>>;
|
||||
};
|
||||
};
|
||||
|
||||
//// [instantiationExpressionErrorNoCrash.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var createCacheReducer = function (queries) {
|
||||
var queriesMap = {};
|
||||
var initialState = {
|
||||
queries: queriesMap,
|
||||
};
|
||||
return function (state) {
|
||||
if (state === void 0) { state = initialState; }
|
||||
return state;
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,52 @@
|
||||
//// [tests/cases/compiler/instantiationExpressionErrorNoCrash.ts] ////
|
||||
|
||||
=== instantiationExpressionErrorNoCrash.ts ===
|
||||
const createCacheReducer = <N extends string, QR>(
|
||||
>createCacheReducer : Symbol(createCacheReducer, Decl(instantiationExpressionErrorNoCrash.ts, 0, 5))
|
||||
>N : Symbol(N, Decl(instantiationExpressionErrorNoCrash.ts, 0, 28))
|
||||
>QR : Symbol(QR, Decl(instantiationExpressionErrorNoCrash.ts, 0, 45))
|
||||
|
||||
queries: Cache<N, QR>["queries"],
|
||||
>queries : Symbol(queries, Decl(instantiationExpressionErrorNoCrash.ts, 0, 50))
|
||||
>Cache : Symbol(Cache, Decl(instantiationExpressionErrorNoCrash.ts, 10, 2))
|
||||
>N : Symbol(N, Decl(instantiationExpressionErrorNoCrash.ts, 0, 28))
|
||||
>QR : Symbol(QR, Decl(instantiationExpressionErrorNoCrash.ts, 0, 45))
|
||||
|
||||
) => {
|
||||
const queriesMap = {} as QR;
|
||||
>queriesMap : Symbol(queriesMap, Decl(instantiationExpressionErrorNoCrash.ts, 3, 9))
|
||||
>QR : Symbol(QR, Decl(instantiationExpressionErrorNoCrash.ts, 0, 45))
|
||||
|
||||
const initialState = {
|
||||
>initialState : Symbol(initialState, Decl(instantiationExpressionErrorNoCrash.ts, 5, 9))
|
||||
|
||||
queries: queriesMap,
|
||||
>queries : Symbol(queries, Decl(instantiationExpressionErrorNoCrash.ts, 5, 26))
|
||||
>queriesMap : Symbol(queriesMap, Decl(instantiationExpressionErrorNoCrash.ts, 3, 9))
|
||||
|
||||
};
|
||||
|
||||
return (state = initialState) => state;
|
||||
>state : Symbol(state, Decl(instantiationExpressionErrorNoCrash.ts, 9, 12))
|
||||
>initialState : Symbol(initialState, Decl(instantiationExpressionErrorNoCrash.ts, 5, 9))
|
||||
>state : Symbol(state, Decl(instantiationExpressionErrorNoCrash.ts, 9, 12))
|
||||
|
||||
};
|
||||
|
||||
export type Cache<N extends string, QR> = {
|
||||
>Cache : Symbol(Cache, Decl(instantiationExpressionErrorNoCrash.ts, 10, 2))
|
||||
>N : Symbol(N, Decl(instantiationExpressionErrorNoCrash.ts, 12, 18))
|
||||
>QR : Symbol(QR, Decl(instantiationExpressionErrorNoCrash.ts, 12, 35))
|
||||
|
||||
queries: {
|
||||
>queries : Symbol(queries, Decl(instantiationExpressionErrorNoCrash.ts, 12, 43))
|
||||
|
||||
[QK in keyof QR]: ReturnType<typeof createCacheReducer<QR>>;
|
||||
>QK : Symbol(QK, Decl(instantiationExpressionErrorNoCrash.ts, 14, 9))
|
||||
>QR : Symbol(QR, Decl(instantiationExpressionErrorNoCrash.ts, 12, 35))
|
||||
>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --))
|
||||
>createCacheReducer : Symbol(createCacheReducer, Decl(instantiationExpressionErrorNoCrash.ts, 0, 5))
|
||||
>QR : Symbol(QR, Decl(instantiationExpressionErrorNoCrash.ts, 12, 35))
|
||||
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,62 @@
|
||||
//// [tests/cases/compiler/instantiationExpressionErrorNoCrash.ts] ////
|
||||
|
||||
=== instantiationExpressionErrorNoCrash.ts ===
|
||||
const createCacheReducer = <N extends string, QR>(
|
||||
>createCacheReducer : <N extends string, QR>(queries: Cache<N, QR>["queries"]) => (state?: { queries: QR; }) => { queries: QR; }
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
><N extends string, QR>( queries: Cache<N, QR>["queries"],) => { const queriesMap = {} as QR; const initialState = { queries: queriesMap, }; return (state = initialState) => state;} : <N extends string, QR>(queries: Cache<N, QR>["queries"]) => (state?: { queries: QR; }) => { queries: QR; }
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
queries: Cache<N, QR>["queries"],
|
||||
>queries : { [QK in keyof QR]: any; }
|
||||
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
) => {
|
||||
const queriesMap = {} as QR;
|
||||
>queriesMap : QR
|
||||
> : ^^
|
||||
>{} as QR : QR
|
||||
> : ^^
|
||||
>{} : {}
|
||||
> : ^^
|
||||
|
||||
const initialState = {
|
||||
>initialState : { queries: QR; }
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>{ queries: queriesMap, } : { queries: QR; }
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
|
||||
queries: queriesMap,
|
||||
>queries : QR
|
||||
> : ^^
|
||||
>queriesMap : QR
|
||||
> : ^^
|
||||
|
||||
};
|
||||
|
||||
return (state = initialState) => state;
|
||||
>(state = initialState) => state : (state?: { queries: QR; }) => { queries: QR; }
|
||||
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>state : { queries: QR; }
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>initialState : { queries: QR; }
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>state : { queries: QR; }
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
|
||||
};
|
||||
|
||||
export type Cache<N extends string, QR> = {
|
||||
>Cache : Cache<N, QR>
|
||||
> : ^^^^^^^^^^^^
|
||||
|
||||
queries: {
|
||||
>queries : { [QK in keyof QR]: any; }
|
||||
> : ^^^ ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
[QK in keyof QR]: ReturnType<typeof createCacheReducer<QR>>;
|
||||
>createCacheReducer : <N_1 extends string, QR_1>(queries: Cache<N_1, QR_1>["queries"]) => (state?: { queries: QR_1; }) => { queries: QR_1; }
|
||||
> : ^^^^^^^^^^^^^ ^^^^^^^^ ^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
};
|
||||
};
|
||||
@ -179,7 +179,7 @@ const c1 = g<string> || ((x: string) => x);
|
||||
>c1 : (x: string) => string
|
||||
> : ^ ^^^^^^^^^^^^^^^^^^^
|
||||
>g<string> || ((x: string) => x) : (x: string) => string
|
||||
> : ^ ^^ ^^^^^^^^^^^
|
||||
> : ^ ^^^^^^^^^^^^^^^^^^^
|
||||
>g<string> : ((x: string) => string) | undefined
|
||||
> : ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>g : (<T>(x: T) => T) | undefined
|
||||
@ -197,7 +197,7 @@ const c2 = g<string> ?? ((x: string) => x);
|
||||
>c2 : (x: string) => string
|
||||
> : ^ ^^^^^^^^^^^^^^^^^^^
|
||||
>g<string> ?? ((x: string) => x) : (x: string) => string
|
||||
> : ^ ^^ ^^^^^^^^^^^
|
||||
> : ^ ^^^^^^^^^^^^^^^^^^^
|
||||
>g<string> : ((x: string) => string) | undefined
|
||||
> : ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>g : (<T>(x: T) => T) | undefined
|
||||
|
||||
17
tests/cases/compiler/instantiationExpressionErrorNoCrash.ts
Normal file
17
tests/cases/compiler/instantiationExpressionErrorNoCrash.ts
Normal file
@ -0,0 +1,17 @@
|
||||
const createCacheReducer = <N extends string, QR>(
|
||||
queries: Cache<N, QR>["queries"],
|
||||
) => {
|
||||
const queriesMap = {} as QR;
|
||||
|
||||
const initialState = {
|
||||
queries: queriesMap,
|
||||
};
|
||||
|
||||
return (state = initialState) => state;
|
||||
};
|
||||
|
||||
export type Cache<N extends string, QR> = {
|
||||
queries: {
|
||||
[QK in keyof QR]: ReturnType<typeof createCacheReducer<QR>>;
|
||||
};
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user