Skip to content

Commit

Permalink
Fixed bug that results in a false positive error under very specific …
Browse files Browse the repository at this point in the history
…conditions involving a recursive type alias that is defined in terms of another type alias. This addresses microsoft#8784. (microsoft#8785)
  • Loading branch information
erictraut authored Aug 19, 2024
1 parent 0b2dc24 commit a93b66f
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions packages/pyright-internal/src/analyzer/typeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1026,9 +1026,16 @@ export function isTypeAliasRecursive(typeAliasPlaceholder: TypeVarType, type: Ty
);
}

export function transformPossibleRecursiveTypeAlias(type: Type): Type;
export function transformPossibleRecursiveTypeAlias(type: Type | undefined): Type | undefined;
export function transformPossibleRecursiveTypeAlias(type: Type | undefined): Type | undefined {
// Recursively transforms all top-level TypeVars that represent recursive
// type aliases into their actual types.
export function transformPossibleRecursiveTypeAlias(type: Type, recursionCount?: number): Type;
export function transformPossibleRecursiveTypeAlias(type: Type | undefined, recursionCount?: number): Type | undefined;
export function transformPossibleRecursiveTypeAlias(type: Type | undefined, recursionCount = 0): Type | undefined {
if (recursionCount >= maxTypeRecursionCount) {
return type;
}
recursionCount++;

if (type) {
const aliasInfo = type.props?.typeAliasInfo;

Expand All @@ -1038,15 +1045,18 @@ export function transformPossibleRecursiveTypeAlias(type: Type | undefined): Typ
: type.shared.boundType;

if (!aliasInfo?.typeArgs || !type.shared.recursiveAlias.typeParams) {
return unspecializedType;
return transformPossibleRecursiveTypeAlias(unspecializedType, recursionCount);
}

const solution = buildSolution(type.shared.recursiveAlias.typeParams, aliasInfo.typeArgs);
return applySolvedTypeVars(unspecializedType, solution);
return transformPossibleRecursiveTypeAlias(
applySolvedTypeVars(unspecializedType, solution),
recursionCount
);
}

if (isUnion(type) && type.priv.includesRecursiveTypeAlias) {
let newType = mapSubtypes(type, (subtype) => transformPossibleRecursiveTypeAlias(subtype));
let newType = mapSubtypes(type, (subtype) => transformPossibleRecursiveTypeAlias(subtype, recursionCount));

if (newType !== type && aliasInfo) {
// Copy the type alias information if present.
Expand Down

0 comments on commit a93b66f

Please sign in to comment.