diff --git a/packages/pyright-internal/src/analyzer/checker.ts b/packages/pyright-internal/src/analyzer/checker.ts index e3bdba5c1458..c1c9d31c46f6 100644 --- a/packages/pyright-internal/src/analyzer/checker.ts +++ b/packages/pyright-internal/src/analyzer/checker.ts @@ -5357,6 +5357,12 @@ export class Checker extends ParseTreeWalker { return; } + // Skip type variables that have been internally synthesized + // for a variety of reasons. + if (param.shared.isSynthesized) { + return; + } + // Skip type variables with auto-variance. if (param.shared.declaredVariance === Variance.Auto) { return; diff --git a/packages/pyright-internal/src/analyzer/typeEvaluator.ts b/packages/pyright-internal/src/analyzer/typeEvaluator.ts index f78ae9c697b0..a1467b287402 100644 --- a/packages/pyright-internal/src/analyzer/typeEvaluator.ts +++ b/packages/pyright-internal/src/analyzer/typeEvaluator.ts @@ -17232,8 +17232,7 @@ export function createTypeEvaluator( arg.d.valueExpr ); } - genericTypeParams = []; - addTypeVarsToListIfUnique(genericTypeParams, getTypeVarArgsRecursive(argType)); + genericTypeParams = buildTypeParamsFromTypeArgs(argType); } } } else if ( @@ -17249,8 +17248,7 @@ export function createTypeEvaluator( arg.d.valueExpr ); } - protocolTypeParams = []; - addTypeVarsToListIfUnique(protocolTypeParams, getTypeVarArgsRecursive(argType)); + protocolTypeParams = buildTypeParamsFromTypeArgs(argType); if (node.d.typeParams && protocolTypeParams.length > 0) { addDiagnostic( @@ -17749,6 +17747,25 @@ export function createTypeEvaluator( }); } + function buildTypeParamsFromTypeArgs(classType: ClassType): TypeVarType[] { + const typeParams: TypeVarType[] = []; + const typeArgs = classType.priv.typeArgs ?? []; + + typeArgs.forEach((typeArg, index) => { + if (isTypeVar(typeArg)) { + typeParams.push(typeArg); + return; + } + + // Synthesize a dummy type parameter. + const typeVar = TypeVarType.createInstance(`__P${index}`); + typeVar.shared.isSynthesized = true; + typeParams.push(typeVar); + }); + + return typeParams; + } + // Determines whether the type parameters has a default that refers to another // type parameter. If so, validates that it is in the list of "live" type // parameters and updates the scope of the type parameter referred to in the