Skip to content

Commit 7698260

Browse files
committed
Conditionalize the carrying-forward of type variable containment checks
within `getObjectTypeInstantiation` more. The existing check pulls the flags forward onto primitives/unions/intersections which may result from `instantiateMappedType` unconditionally. This means we may mark unions and intersections as possibly containing type parameters when they in fact cannot.
1 parent 67299ed commit 7698260

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

src/compiler/checker.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5584,7 +5584,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
55845584
function createIntrinsicType(kind: TypeFlags, intrinsicName: string, objectFlags = ObjectFlags.None): IntrinsicType {
55855585
const type = createType(kind) as IntrinsicType;
55865586
type.intrinsicName = intrinsicName;
5587-
type.objectFlags = objectFlags;
5587+
type.objectFlags = objectFlags | ObjectFlags.CouldContainTypeVariablesComputed | ObjectFlags.IsGenericTypeComputed | ObjectFlags.IsUnknownLikeUnionComputed | ObjectFlags.IsNeverIntersectionComputed;
55885588
return type;
55895589
}
55905590

@@ -18797,13 +18797,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1879718797
result = target.objectFlags & ObjectFlags.Reference ? createDeferredTypeReference((type as DeferredTypeReference).target, (type as DeferredTypeReference).node, newMapper, newAliasSymbol, newAliasTypeArguments) :
1879818798
target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target as MappedType, newMapper, newAliasSymbol, newAliasTypeArguments) :
1879918799
instantiateAnonymousType(target, newMapper, newAliasSymbol, newAliasTypeArguments);
18800-
// If none of the type arguments for the outer type parameters contain type variables, it follows
18801-
// that the instantiated type doesn't reference type variables.
18802-
if (result.flags & TypeFlags.ObjectFlagsType && !((result as ObjectFlagsType).objectFlags & ObjectFlags.CouldContainTypeVariablesComputed)) {
18803-
(result as ObjectFlagsType).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed |
18804-
(some(typeArguments, couldContainTypeVariables) ? ObjectFlags.CouldContainTypeVariables : 0);
18800+
target.instantiations.set(id, result); // Set cached result early in case we recursively invoke instantiation while eagerly computing type variable visibility below
18801+
const resultObjectFlags = getObjectFlags(result);
18802+
if (result.flags & TypeFlags.ObjectFlagsType && !(resultObjectFlags & ObjectFlags.CouldContainTypeVariablesComputed)) {
18803+
const resultCouldContainTypeVariables = some(typeArguments, couldContainTypeVariables); // one of the input type arguments might be or contain the result
18804+
if (!(getObjectFlags(result) & ObjectFlags.CouldContainTypeVariablesComputed)) {
18805+
// 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
18806+
if (resultObjectFlags & (ObjectFlags.Mapped | ObjectFlags.Anonymous | ObjectFlags.Reference)) {
18807+
(result as ObjectFlagsType).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed | (resultCouldContainTypeVariables ? ObjectFlags.CouldContainTypeVariables : 0);
18808+
}
18809+
// If none of the type arguments for the outer type parameters contain type variables, it follows
18810+
// that the instantiated type doesn't reference type variables.
18811+
// Intrinsics have `CouldContainTypeVariablesComputed` pre-set, so this should only cover unions and intersections resulting from `instantiateMappedType`
18812+
else {
18813+
(result as ObjectFlagsType).objectFlags |= !resultCouldContainTypeVariables ? ObjectFlags.CouldContainTypeVariablesComputed : 0;
18814+
}
18815+
}
1880518816
}
18806-
target.instantiations.set(id, result);
1880718817
}
1880818818
return result;
1880918819
}

0 commit comments

Comments
 (0)