mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 01:04:49 -05:00
Optimize eagerly calculating CouldContainTypeVariables during object type instantiation (#54538)
This commit is contained in:
@@ -5585,7 +5585,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function createIntrinsicType(kind: TypeFlags, intrinsicName: string, objectFlags = ObjectFlags.None): IntrinsicType {
|
||||
const type = createType(kind) as IntrinsicType;
|
||||
type.intrinsicName = intrinsicName;
|
||||
type.objectFlags = objectFlags;
|
||||
type.objectFlags = objectFlags | ObjectFlags.CouldContainTypeVariablesComputed | ObjectFlags.IsGenericTypeComputed | ObjectFlags.IsUnknownLikeUnionComputed | ObjectFlags.IsNeverIntersectionComputed;
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -18798,17 +18798,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
result = target.objectFlags & ObjectFlags.Reference ? createDeferredTypeReference((type as DeferredTypeReference).target, (type as DeferredTypeReference).node, newMapper, newAliasSymbol, newAliasTypeArguments) :
|
||||
target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target as MappedType, newMapper, newAliasSymbol, newAliasTypeArguments) :
|
||||
instantiateAnonymousType(target, newMapper, newAliasSymbol, newAliasTypeArguments);
|
||||
// If none of the type arguments for the outer type parameters contain type variables, it follows
|
||||
// that the instantiated type doesn't reference type variables.
|
||||
if (result.flags & TypeFlags.ObjectFlagsType && !((result as ObjectFlagsType).objectFlags & ObjectFlags.CouldContainTypeVariablesComputed)) {
|
||||
const resultCouldContainTypeVariables = some(typeArguments, couldContainTypeVariables);
|
||||
// The above check may have caused the result's objectFlags to update if the result is referenced via typeArguments.
|
||||
if (!((result as ObjectFlagsType).objectFlags & ObjectFlags.CouldContainTypeVariablesComputed)) {
|
||||
(result as ObjectFlagsType).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed |
|
||||
(resultCouldContainTypeVariables ? ObjectFlags.CouldContainTypeVariables : 0);
|
||||
target.instantiations.set(id, result); // Set cached result early in case we recursively invoke instantiation while eagerly computing type variable visibility below
|
||||
const resultObjectFlags = getObjectFlags(result);
|
||||
if (result.flags & TypeFlags.ObjectFlagsType && !(resultObjectFlags & ObjectFlags.CouldContainTypeVariablesComputed)) {
|
||||
const resultCouldContainTypeVariables = some(typeArguments, couldContainTypeVariables); // one of the input type arguments might be or contain the result
|
||||
if (!(getObjectFlags(result) & ObjectFlags.CouldContainTypeVariablesComputed)) {
|
||||
// if `result` is one of the object types we tried to make (it may not be, due to how `instantiateMappedType` works), we can carry forward the type variable containment check from the input type arguments
|
||||
if (resultObjectFlags & (ObjectFlags.Mapped | ObjectFlags.Anonymous | ObjectFlags.Reference)) {
|
||||
(result as ObjectFlagsType).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed | (resultCouldContainTypeVariables ? ObjectFlags.CouldContainTypeVariables : 0);
|
||||
}
|
||||
// If none of the type arguments for the outer type parameters contain type variables, it follows
|
||||
// that the instantiated type doesn't reference type variables.
|
||||
// Intrinsics have `CouldContainTypeVariablesComputed` pre-set, so this should only cover unions and intersections resulting from `instantiateMappedType`
|
||||
else {
|
||||
(result as ObjectFlagsType).objectFlags |= !resultCouldContainTypeVariables ? ObjectFlags.CouldContainTypeVariablesComputed : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
target.instantiations.set(id, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user