@zzzen/pyright-internal 1.2.0-dev.20221218 → 1.2.0-dev.20230101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/analyzer/binder.js +8 -3
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/codeFlowEngine.d.ts +16 -1
  4. package/dist/analyzer/codeFlowEngine.js +41 -20
  5. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  6. package/dist/analyzer/constraintSolver.js +133 -53
  7. package/dist/analyzer/constraintSolver.js.map +1 -1
  8. package/dist/analyzer/patternMatching.js +3 -2
  9. package/dist/analyzer/patternMatching.js.map +1 -1
  10. package/dist/analyzer/program.js +11 -5
  11. package/dist/analyzer/program.js.map +1 -1
  12. package/dist/analyzer/properties.js +9 -0
  13. package/dist/analyzer/properties.js.map +1 -1
  14. package/dist/analyzer/protocols.js +1 -1
  15. package/dist/analyzer/protocols.js.map +1 -1
  16. package/dist/analyzer/sourceFile.js +2 -1
  17. package/dist/analyzer/sourceFile.js.map +1 -1
  18. package/dist/analyzer/testWalker.js +5 -0
  19. package/dist/analyzer/testWalker.js.map +1 -1
  20. package/dist/analyzer/typeCacheUtils.d.ts +28 -0
  21. package/dist/analyzer/{typeCache.js → typeCacheUtils.js} +8 -14
  22. package/dist/analyzer/typeCacheUtils.js.map +1 -0
  23. package/dist/analyzer/typeEvaluator.js +495 -359
  24. package/dist/analyzer/typeEvaluator.js.map +1 -1
  25. package/dist/analyzer/typeGuards.js +1 -2
  26. package/dist/analyzer/typeGuards.js.map +1 -1
  27. package/dist/analyzer/typeUtils.d.ts +14 -6
  28. package/dist/analyzer/typeUtils.js +291 -144
  29. package/dist/analyzer/typeUtils.js.map +1 -1
  30. package/dist/analyzer/typeVarContext.d.ts +10 -17
  31. package/dist/analyzer/typeVarContext.js +58 -39
  32. package/dist/analyzer/typeVarContext.js.map +1 -1
  33. package/dist/analyzer/types.d.ts +4 -12
  34. package/dist/analyzer/types.js +22 -22
  35. package/dist/analyzer/types.js.map +1 -1
  36. package/dist/commands/dumpFileDebugInfoCommand.js +2 -2
  37. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  38. package/dist/localization/localize.d.ts +18 -3
  39. package/dist/localization/localize.js +7 -1
  40. package/dist/localization/localize.js.map +1 -1
  41. package/dist/localization/package.nls.en-us.json +8 -2
  42. package/dist/parser/parseNodes.d.ts +1 -0
  43. package/dist/parser/parseNodes.js.map +1 -1
  44. package/dist/parser/parser.js +38 -16
  45. package/dist/parser/parser.js.map +1 -1
  46. package/dist/tests/typeEvaluator1.test.js +4 -0
  47. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  48. package/dist/tests/typeEvaluator2.test.js +10 -2
  49. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  50. package/dist/tests/typeEvaluator3.test.js +21 -3
  51. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  52. package/dist/tests/typeEvaluator4.test.js +4 -0
  53. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  54. package/dist/tests/typeEvaluator5.test.js +49 -7
  55. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  56. package/package.json +2 -2
  57. package/dist/analyzer/typeCache.d.ts +0 -40
  58. package/dist/analyzer/typeCache.js.map +0 -1
@@ -67,7 +67,7 @@ const staticExpressions_1 = require("./staticExpressions");
67
67
  const symbol_1 = require("./symbol");
68
68
  const symbolNameUtils_1 = require("./symbolNameUtils");
69
69
  const symbolUtils_1 = require("./symbolUtils");
70
- const typeCache_1 = require("./typeCache");
70
+ const typeCacheUtils_1 = require("./typeCacheUtils");
71
71
  const typedDicts_1 = require("./typedDicts");
72
72
  const typeEvaluatorTypes_1 = require("./typeEvaluatorTypes");
73
73
  const TypePrinter = __importStar(require("./typePrinter"));
@@ -227,9 +227,8 @@ const maxLiteralMathSubtypeCount = 64;
227
227
  exports.maxCodeComplexity = 768;
228
228
  function createTypeEvaluator(importLookup, evaluatorOptions) {
229
229
  const symbolResolutionStack = [];
230
- const typeCacheFlags = new Map();
231
230
  const asymmetricDescriptorAssignmentCache = new Set();
232
- const speculativeTypeTracker = new typeCache_1.SpeculativeTypeTracker();
231
+ const speculativeTypeTracker = new typeCacheUtils_1.SpeculativeTypeTracker();
233
232
  const suppressedNodeStack = [];
234
233
  let functionRecursionMap = new Set();
235
234
  let codeFlowAnalyzerCache = new Map();
@@ -250,7 +249,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
250
249
  let strClassType;
251
250
  let dictClassType;
252
251
  let typedDictClassType;
253
- let incompleteTypeCache;
254
252
  let printExpressionSpaceCount = 0;
255
253
  const returnTypeInferenceContextStack = [];
256
254
  let returnTypeInferenceTypeCache;
@@ -292,25 +290,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
292
290
  else {
293
291
  cachedType = typeCache.get(node.id);
294
292
  }
295
- return cachedType !== undefined;
293
+ return cachedType !== undefined && !cachedType.isIncomplete;
296
294
  }
297
- function readTypeCache(node, flags) {
298
- var _a, _b;
299
- let cachedType;
295
+ function readTypeCacheEntry(node) {
300
296
  // Should we use a temporary cache associated with a contextual
301
297
  // analysis of a function, contextualized based on call-site argument types?
302
298
  if (returnTypeInferenceTypeCache && isNodeInReturnTypeInferenceContext(node)) {
303
- cachedType = returnTypeInferenceTypeCache.get(node.id);
299
+ return returnTypeInferenceTypeCache.get(node.id);
304
300
  }
305
301
  else {
306
- cachedType = typeCache.get(node.id);
302
+ return typeCache.get(node.id);
307
303
  }
308
- if (cachedType === undefined) {
304
+ }
305
+ function readTypeCache(node, flags) {
306
+ var _a, _b;
307
+ const cacheEntry = readTypeCacheEntry(node);
308
+ if (!cacheEntry || cacheEntry.isIncomplete) {
309
309
  return undefined;
310
310
  }
311
311
  if (evaluatorOptions.verifyTypeCacheEvaluatorFlags || verifyTypeCacheEvaluatorFlags) {
312
312
  if (flags !== undefined) {
313
- const expectedFlags = typeCacheFlags.get(node.id);
313
+ const expectedFlags = cacheEntry.flags;
314
314
  if (expectedFlags !== undefined && flags !== expectedFlags) {
315
315
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
316
316
  const position = (0, positionUtils_1.convertOffsetToPosition)(node.start, fileInfo.lines);
@@ -327,34 +327,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
327
327
  }
328
328
  }
329
329
  }
330
- (0, debug_1.assert)(!(0, typeCache_1.isIncompleteType)(cachedType));
331
- return cachedType;
330
+ return cacheEntry.type;
332
331
  }
333
332
  function writeTypeCache(node, type, flags, isIncomplete, expectedType, allowSpeculativeCaching = false) {
334
- if (isIncomplete) {
335
- if (incompleteTypeCache) {
336
- incompleteTypeCache.set(node.id, type);
337
- }
338
- return;
339
- }
340
333
  // Should we use a temporary cache associated with a contextual
341
334
  // analysis of a function, contextualized based on call-site argument types?
342
335
  const typeCacheToUse = returnTypeInferenceTypeCache && isNodeInReturnTypeInferenceContext(node)
343
336
  ? returnTypeInferenceTypeCache
344
337
  : typeCache;
345
- typeCacheToUse.set(node.id, type);
346
- if (evaluatorOptions.verifyTypeCacheEvaluatorFlags || verifyTypeCacheEvaluatorFlags) {
347
- if (typeCacheToUse === typeCache && flags !== undefined) {
348
- typeCacheFlags.set(node.id, flags);
349
- }
350
- }
338
+ typeCacheToUse.set(node.id, { type, isIncomplete, flags });
351
339
  // If the entry is located within a part of the parse tree that is currently being
352
340
  // "speculatively" evaluated, track it so we delete the cached entry when we leave
353
341
  // this speculative context.
354
342
  if (speculativeTypeTracker.isSpeculative(node)) {
355
343
  speculativeTypeTracker.trackEntry(typeCacheToUse, node.id);
356
344
  if (allowSpeculativeCaching) {
357
- speculativeTypeTracker.addSpeculativeType(node, type, expectedType);
345
+ speculativeTypeTracker.addSpeculativeType(node, { type, isIncomplete }, expectedType);
358
346
  }
359
347
  }
360
348
  }
@@ -517,12 +505,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
517
505
  }
518
506
  else {
519
507
  // Is it cached in the speculative type cache?
520
- const speculativeCachedType = speculativeTypeTracker.getSpeculativeType(node, expectedType);
521
- if (speculativeCachedType) {
508
+ const cachedTypeResult = speculativeTypeTracker.getSpeculativeType(node, expectedType);
509
+ if (cachedTypeResult) {
522
510
  if (printExpressionTypes) {
523
- console.log(`${getPrintExpressionTypesSpaces()}${ParseTreeUtils.printExpression(node)} (${getLineNum(node)}): Speculative ${printType(speculativeCachedType)}`);
511
+ console.log(`${getPrintExpressionTypesSpaces()}${ParseTreeUtils.printExpression(node)} (${getLineNum(node)}): Speculative ${printType(cachedTypeResult.type)}`);
524
512
  }
525
- return { type: speculativeCachedType };
513
+ return { type: cachedTypeResult.type, isIncomplete: cachedTypeResult.isIncomplete };
526
514
  }
527
515
  }
528
516
  if (printExpressionTypes) {
@@ -918,24 +906,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
918
906
  return typeResult;
919
907
  }
920
908
  function stripLiteralValue(type) {
921
- if ((0, types_1.isClass)(type)) {
922
- if (type.literalValue !== undefined) {
923
- type = types_1.ClassType.cloneWithLiteral(type, /* value */ undefined);
924
- }
925
- else if (types_1.ClassType.isBuiltIn(type, 'LiteralString')) {
926
- // Handle "LiteralString" specially.
927
- if (strClassType && (0, types_1.isInstantiableClass)(strClassType)) {
928
- type = types_1.ClassType.cloneAsInstance(strClassType);
909
+ return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
910
+ if ((0, types_1.isClass)(subtype)) {
911
+ if (subtype.literalValue !== undefined) {
912
+ return types_1.ClassType.cloneWithLiteral(subtype, /* value */ undefined);
913
+ }
914
+ if (types_1.ClassType.isBuiltIn(subtype, 'LiteralString')) {
915
+ // Handle "LiteralString" specially.
916
+ if (strClassType && (0, types_1.isInstantiableClass)(strClassType)) {
917
+ return types_1.ClassType.cloneAsInstance(strClassType);
918
+ }
929
919
  }
930
920
  }
931
- return type;
932
- }
933
- if ((0, types_1.isUnion)(type)) {
934
- return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
935
- return stripLiteralValue(subtype);
936
- });
937
- }
938
- return type;
921
+ return subtype;
922
+ });
939
923
  }
940
924
  function getTypeOfParameterAnnotation(paramTypeNode, paramCategory) {
941
925
  return getTypeOfAnnotation(paramTypeNode, {
@@ -2762,7 +2746,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2762
2746
  return undefined;
2763
2747
  }
2764
2748
  function getTypeOfName(node, flags) {
2765
- var _a, _b;
2749
+ var _a;
2766
2750
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
2767
2751
  const name = node.value;
2768
2752
  let symbol;
@@ -2773,7 +2757,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2773
2757
  const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
2774
2758
  if (typeParamSymbol) {
2775
2759
  symbol = typeParamSymbol;
2776
- type = (_a = getDeclaredTypeOfSymbol(typeParamSymbol)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
2760
+ (0, debug_1.assert)(symbol.getDeclarations().length === 1);
2761
+ const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
2762
+ (0, debug_1.assert)((decl === null || decl === void 0 ? void 0 : decl.type) === 3 /* TypeParameter */);
2763
+ type = getTypeOfTypeParameter(decl.node);
2777
2764
  setSymbolAccessed(fileInfo, symbol, node);
2778
2765
  }
2779
2766
  else {
@@ -2914,7 +2901,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2914
2901
  type.details.name === name) {
2915
2902
  // Handle the special case of a PEP 604 union. These can appear within
2916
2903
  // an implied type alias where we are not expecting a type.
2917
- const isPep604Union = ((_b = node.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 7 /* BinaryOperation */ &&
2904
+ const isPep604Union = ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 7 /* BinaryOperation */ &&
2918
2905
  node.parent.operator === 6 /* BitwiseOr */;
2919
2906
  if (!isPep604Union) {
2920
2907
  // A TypeVar in contexts where we're not expecting a type is
@@ -3030,7 +3017,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3030
3017
  if (memberName === 'args' || memberName === 'kwargs') {
3031
3018
  const outerFunctionScope = ParseTreeUtils.getEnclosingClassOrFunction(enclosingScope);
3032
3019
  if ((outerFunctionScope === null || outerFunctionScope === void 0 ? void 0 : outerFunctionScope.nodeType) === 28 /* Function */) {
3033
- enclosingScope = outerFunctionScope;
3020
+ if (scopedTypeVarInfo.isRescoped) {
3021
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet
3022
+ .reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecScopedToReturnType().format({
3023
+ name: type.details.name,
3024
+ }), node);
3025
+ }
3026
+ else {
3027
+ enclosingScope = outerFunctionScope;
3028
+ }
3034
3029
  }
3035
3030
  else if (!scopedTypeVarInfo.type.scopeId) {
3036
3031
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecNotUsedByOuterScope().format({
@@ -3064,9 +3059,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3064
3059
  else if ((flags & 4096 /* DisallowTypeVarsWithoutScopeId */) !== 0) {
3065
3060
  if ((type.scopeId === undefined || scopedTypeVarInfo.foundInterveningClass) &&
3066
3061
  !type.details.isSynthesized) {
3067
- const message = (0, types_1.isParamSpec)(type)
3068
- ? localize_1.Localizer.Diagnostic.paramSpecNotUsedByOuterScope()
3069
- : localize_1.Localizer.Diagnostic.typeVarNotUsedByOuterScope();
3062
+ let message;
3063
+ if (scopedTypeVarInfo.isRescoped) {
3064
+ message = (0, types_1.isParamSpec)(type)
3065
+ ? localize_1.Localizer.Diagnostic.paramSpecScopedToReturnType()
3066
+ : localize_1.Localizer.Diagnostic.typeVarScopedToReturnType();
3067
+ }
3068
+ else {
3069
+ message = (0, types_1.isParamSpec)(type)
3070
+ ? localize_1.Localizer.Diagnostic.paramSpecNotUsedByOuterScope()
3071
+ : localize_1.Localizer.Diagnostic.typeVarNotUsedByOuterScope();
3072
+ }
3070
3073
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message.format({ name: type.details.name }), node);
3071
3074
  }
3072
3075
  }
@@ -3082,43 +3085,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3082
3085
  // type arguments. If so, it fills in these type arguments with Unknown
3083
3086
  // and optionally reports an error.
3084
3087
  function reportMissingTypeArguments(node, type, flags) {
3085
- if ((flags & 2 /* DoNotSpecialize */) === 0) {
3086
- if ((0, types_1.isInstantiableClass)(type)) {
3087
- if ((flags & 64 /* ExpectingType */) !== 0) {
3088
- if ((0, typeUtils_1.requiresTypeArguments)(type) && !type.typeArguments) {
3089
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForClass().format({
3090
- name: type.aliasName || type.details.name,
3091
- }), node);
3092
- }
3093
- }
3094
- if (!type.typeArguments) {
3095
- type = createSpecializedClassType(type, /* typeArgs */ undefined, flags, node);
3088
+ if ((flags & 2 /* DoNotSpecialize */) !== 0) {
3089
+ return type;
3090
+ }
3091
+ // Is this a generic class that needs to be specialized?
3092
+ if ((0, types_1.isInstantiableClass)(type)) {
3093
+ if ((flags & 64 /* ExpectingType */) !== 0) {
3094
+ if ((0, typeUtils_1.requiresTypeArguments)(type) && !type.typeArguments) {
3095
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForClass().format({
3096
+ name: type.aliasName || type.details.name,
3097
+ }), node);
3096
3098
  }
3097
3099
  }
3098
- if ((flags & 64 /* ExpectingType */) !== 0 &&
3099
- type.typeAliasInfo &&
3100
- type.typeAliasInfo.typeParameters &&
3101
- type.typeAliasInfo.typeParameters.length > 0 &&
3102
- !type.typeAliasInfo.typeArguments) {
3103
- let reportMissingTypeArguments = false;
3104
- const defaultTypeArgs = [];
3105
- type.typeAliasInfo.typeParameters.forEach((param) => {
3106
- if (param.details.defaultType) {
3107
- defaultTypeArgs.push(param.details.defaultType);
3108
- }
3109
- else {
3110
- defaultTypeArgs.push(types_1.UnknownType.create());
3111
- reportMissingTypeArguments = true;
3112
- }
3113
- });
3114
- const typeVarContext = (0, typeUtils_1.buildTypeVarContext)(type.typeAliasInfo.typeParameters, defaultTypeArgs, type.typeAliasInfo.typeVarScopeId);
3115
- if (reportMissingTypeArguments) {
3116
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForAlias().format({
3117
- name: type.typeAliasInfo.name,
3118
- }), node);
3100
+ if (!type.typeArguments) {
3101
+ type = createSpecializedClassType(type, /* typeArgs */ undefined, flags, node);
3102
+ }
3103
+ }
3104
+ // Is this a generic type alias that needs to be specialized?
3105
+ if ((flags & 64 /* ExpectingType */) !== 0 &&
3106
+ type.typeAliasInfo &&
3107
+ type.typeAliasInfo.typeParameters &&
3108
+ type.typeAliasInfo.typeParameters.length > 0 &&
3109
+ !type.typeAliasInfo.typeArguments) {
3110
+ let reportMissingTypeArguments = false;
3111
+ const defaultTypeArgs = [];
3112
+ const typeVarContext = new typeVarContext_1.TypeVarContext(type.typeAliasInfo.typeVarScopeId);
3113
+ type.typeAliasInfo.typeParameters.forEach((param) => {
3114
+ if (!param.details.defaultType) {
3115
+ reportMissingTypeArguments = true;
3116
+ }
3117
+ let defaultType;
3118
+ if (param.details.defaultType || param.details.isParamSpec) {
3119
+ defaultType = (0, typeUtils_1.applySolvedTypeVars)(param, typeVarContext, { unknownIfNotFound: true });
3120
+ }
3121
+ else {
3122
+ defaultType = types_1.UnknownType.create();
3119
3123
  }
3120
- type = types_1.TypeBase.cloneForTypeAlias((0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, /* unknownIfNotFound */ true), type.typeAliasInfo.name, type.typeAliasInfo.fullName, type.typeAliasInfo.typeVarScopeId, type.typeAliasInfo.typeParameters, defaultTypeArgs);
3124
+ defaultTypeArgs.push(defaultType);
3125
+ typeVarContext.setTypeVarType(param, defaultType);
3126
+ });
3127
+ if (reportMissingTypeArguments) {
3128
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForAlias().format({
3129
+ name: type.typeAliasInfo.name,
3130
+ }), node);
3121
3131
  }
3132
+ type = types_1.TypeBase.cloneForTypeAlias((0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, { unknownIfNotFound: true }), type.typeAliasInfo.name, type.typeAliasInfo.fullName, type.typeAliasInfo.typeVarScopeId, type.typeAliasInfo.typeParameters, defaultTypeArgs);
3122
3133
  }
3123
3134
  return type;
3124
3135
  }
@@ -3152,8 +3163,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3152
3163
  return scopeIds;
3153
3164
  }
3154
3165
  // Walks up the parse tree to find a function, class, or type alias
3155
- // assignment that provides the context for a type variable.
3166
+ // declaration that provides the context for a type variable.
3156
3167
  function findScopedTypeVar(node, type) {
3168
+ var _a;
3157
3169
  let curNode = node;
3158
3170
  let nestedClassCount = 0;
3159
3171
  (0, debug_1.assert)(types_1.TypeBase.isInstantiable(type));
@@ -3175,14 +3187,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3175
3187
  else if (curNode.nodeType === 28 /* Function */) {
3176
3188
  const functionTypeInfo = getTypeOfFunction(curNode);
3177
3189
  if (functionTypeInfo) {
3178
- typeParametersForScope = [];
3179
- functionTypeInfo.functionType.details.parameters.forEach((param) => {
3180
- if (param.hasDeclaredType) {
3181
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(param.type));
3182
- }
3183
- });
3184
- if (functionTypeInfo.functionType.details.declaredReturnType) {
3185
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionTypeInfo.functionType.details.declaredReturnType));
3190
+ const functionDetails = functionTypeInfo.functionType.details;
3191
+ typeParametersForScope = functionDetails.typeParameters;
3192
+ // Was this type parameter "rescoped" to a callable found within the
3193
+ // return type annotation? If so, it is not available for use within
3194
+ // the function body.
3195
+ if ((_a = functionDetails.rescopedTypeParameters) === null || _a === void 0 ? void 0 : _a.some((tp) => tp.details.name === type.details.name)) {
3196
+ return { type, isRescoped: true, foundInterveningClass: false };
3186
3197
  }
3187
3198
  }
3188
3199
  scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
@@ -3195,7 +3206,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3195
3206
  if (match === null || match === void 0 ? void 0 : match.scopeId) {
3196
3207
  // Use the scoped version of the TypeVar rather than the (unscoped) original type.
3197
3208
  type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
3198
- return { type, foundInterveningClass: nestedClassCount > 1 && !scopeUsesTypeParameterSyntax };
3209
+ return {
3210
+ type,
3211
+ isRescoped: false,
3212
+ foundInterveningClass: nestedClassCount > 1 && !scopeUsesTypeParameterSyntax,
3213
+ };
3199
3214
  }
3200
3215
  }
3201
3216
  curNode = curNode.parent;
@@ -3228,6 +3243,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3228
3243
  }
3229
3244
  return {
3230
3245
  type: types_1.TypeVarType.cloneForScopeId(type, leftType.details.recursiveTypeAliasScopeId, leftType.details.recursiveTypeAliasName, 2 /* TypeAlias */),
3246
+ isRescoped: false,
3231
3247
  foundInterveningClass: false,
3232
3248
  };
3233
3249
  }
@@ -3235,7 +3251,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3235
3251
  curNode = curNode.parent;
3236
3252
  }
3237
3253
  // Return the original type.
3238
- return { type, foundInterveningClass: false };
3254
+ return { type, isRescoped: false, foundInterveningClass: false };
3239
3255
  }
3240
3256
  function getTypeOfMemberAccess(node, flags) {
3241
3257
  const baseTypeFlags = 2 /* DoNotSpecialize */ |
@@ -4209,12 +4225,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4209
4225
  }
4210
4226
  return indexTypeResult;
4211
4227
  }
4212
- function adjustTypeArgumentsForVariadicTypeVar(typeArgs, typeParameters, errorNode) {
4213
- var _a;
4228
+ function adjustTypeArgumentsForVariadicTypeVar(typeArgs, typeParameters, typeVarScopeId, errorNode) {
4214
4229
  const variadicIndex = typeParameters.findIndex((param) => (0, types_1.isVariadicTypeVar)(param));
4215
4230
  // Do we need to adjust the type arguments to map to a variadic type
4216
4231
  // param at the end of the list?
4217
4232
  if (variadicIndex >= 0) {
4233
+ const variadicTypeVar = typeParameters[variadicIndex];
4218
4234
  if (tupleClassType && (0, types_1.isInstantiableClass)(tupleClassType)) {
4219
4235
  if (variadicIndex < typeArgs.length) {
4220
4236
  const variadicTypeResults = typeArgs.slice(variadicIndex, variadicIndex + 1 + typeArgs.length - typeParameters.length);
@@ -4254,11 +4270,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4254
4270
  ];
4255
4271
  }
4256
4272
  }
4257
- else {
4273
+ else if (!variadicTypeVar.details.defaultType) {
4258
4274
  // Add an empty tuple that maps to the TypeVarTuple type parameter.
4259
4275
  typeArgs.push({
4260
4276
  node: errorNode,
4261
- type: (_a = typeParameters[variadicIndex].details.defaultType) !== null && _a !== void 0 ? _a : (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, [],
4277
+ type: (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, [],
4262
4278
  /* isTypeArgumentExplicit */ true,
4263
4279
  /* isUnpackedTuple */ true)),
4264
4280
  });
@@ -4295,7 +4311,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4295
4311
  return undefined;
4296
4312
  }
4297
4313
  const typeParameters = baseType.typeAliasInfo.typeParameters;
4298
- let typeArgs = adjustTypeArgumentsForVariadicTypeVar(getTypeArgs(node, flags), typeParameters, node);
4314
+ let typeArgs = adjustTypeArgumentsForVariadicTypeVar(getTypeArgs(node, flags), typeParameters, baseType.typeAliasInfo.typeVarScopeId, node);
4299
4315
  // PEP 612 says that if the class has only one type parameter consisting
4300
4316
  // of a ParamSpec, the list of arguments does not need to be enclosed in
4301
4317
  // a list. We'll handle that case specially here. Presumably this applies to
@@ -4328,7 +4344,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4328
4344
  const typeVarContext = new typeVarContext_1.TypeVarContext(baseType.typeAliasInfo.typeVarScopeId);
4329
4345
  const diag = new diagnostic_1.DiagnosticAddendum();
4330
4346
  typeParameters.forEach((param, index) => {
4331
- var _a;
4332
4347
  if (param.details.isParamSpec && index < typeArgs.length) {
4333
4348
  const typeArgType = typeArgs[index].type;
4334
4349
  if (typeArgs[index].typeList) {
@@ -4391,9 +4406,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4391
4406
  if (index < typeArgs.length && typeArgs[index].typeList) {
4392
4407
  addError(localize_1.Localizer.Diagnostic.typeArgListNotAllowed(), typeArgs[index].node);
4393
4408
  }
4394
- const typeArgType = index < typeArgs.length
4395
- ? (0, typeUtils_1.convertToInstance)(typeArgs[index].type)
4396
- : (_a = param.details.defaultType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
4409
+ let typeArgType;
4410
+ if (index < typeArgs.length) {
4411
+ typeArgType = (0, typeUtils_1.convertToInstance)(typeArgs[index].type);
4412
+ }
4413
+ else if (param.details.defaultType) {
4414
+ typeArgType = (0, typeUtils_1.applySolvedTypeVars)(param, typeVarContext, { unknownIfNotFound: true });
4415
+ }
4416
+ else {
4417
+ typeArgType = types_1.UnknownType.create();
4418
+ }
4397
4419
  (0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, param, typeArgType, diag, typeVarContext, 128 /* RetainLiteralsForTypeVar */);
4398
4420
  }
4399
4421
  });
@@ -4404,8 +4426,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4404
4426
  (_b = baseType.typeAliasInfo.typeParameters) === null || _b === void 0 ? void 0 : _b.forEach((typeParam) => {
4405
4427
  let typeVarType;
4406
4428
  if ((0, types_1.isParamSpec)(typeParam)) {
4407
- const paramSpecValue = typeVarContext.getParamSpec(typeParam);
4408
- typeVarType = paramSpecValue ? (0, typeUtils_1.convertParamSpecValueToType)(paramSpecValue) : types_1.UnknownType.create();
4429
+ const paramSpecType = typeVarContext.getParamSpecType(typeParam);
4430
+ typeVarType = paramSpecType ? (0, typeUtils_1.convertParamSpecValueToType)(paramSpecType) : types_1.UnknownType.create();
4409
4431
  }
4410
4432
  else {
4411
4433
  typeVarType = typeVarContext.getTypeVarType(typeParam);
@@ -4429,7 +4451,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4429
4451
  let isIncomplete = baseTypeResult.isIncomplete;
4430
4452
  const type = mapSubtypesExpandTypeVars(baseTypeResult.type,
4431
4453
  /* conditionFilter */ undefined, (concreteSubtype, unexpandedSubtype) => {
4432
- var _a;
4454
+ var _a, _b;
4433
4455
  if ((0, types_1.isAnyOrUnknown)(concreteSubtype)) {
4434
4456
  return concreteSubtype;
4435
4457
  }
@@ -4496,7 +4518,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4496
4518
  const isClassVarAnnotation = (0, types_1.isInstantiableClass)(concreteSubtype) && types_1.ClassType.isBuiltIn(concreteSubtype, 'ClassVar');
4497
4519
  let typeArgs = getTypeArgs(node, flags, isAnnotatedClass, hasCustomClassGetItem || !isGenericClass, isFinalAnnotation, isClassVarAnnotation);
4498
4520
  if (!isAnnotatedClass) {
4499
- typeArgs = adjustTypeArgumentsForVariadicTypeVar(typeArgs, concreteSubtype.details.typeParameters, node);
4521
+ typeArgs = adjustTypeArgumentsForVariadicTypeVar(typeArgs, concreteSubtype.details.typeParameters, (_b = (0, typeUtils_1.getTypeVarScopeId)(concreteSubtype)) !== null && _b !== void 0 ? _b : '', node);
4500
4522
  }
4501
4523
  // If this is a custom __class_getitem__, there's no need to specialize the class.
4502
4524
  // Just return it as is.
@@ -4954,6 +4976,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4954
4976
  }
4955
4977
  const entryTypeResults = node.expressions.map((expr, index) => getTypeOfExpression(expr,
4956
4978
  /* flags */ undefined, index < expectedTypes.length ? expectedTypes[index] : undefined));
4979
+ const isIncomplete = entryTypeResults.some((result) => result.isIncomplete);
4957
4980
  const type = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, buildTupleTypesList(entryTypeResults),
4958
4981
  /* isTypeArgumentExplicit */ true));
4959
4982
  // Copy any expected type diag addenda for precision error reporting.
@@ -4966,7 +4989,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4966
4989
  }
4967
4990
  });
4968
4991
  }
4969
- return { type, expectedTypeDiagAddendum };
4992
+ return { type, expectedTypeDiagAddendum, isIncomplete };
4970
4993
  }
4971
4994
  function getTypeOfTupleInferred(node) {
4972
4995
  const entryTypeResults = node.expressions.map((expr) => getTypeOfExpression(expr));
@@ -5953,7 +5976,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5953
5976
  unsolvedTypeVarsAreUnknown = false;
5954
5977
  }
5955
5978
  }
5956
- const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, unsolvedTypeVarsAreUnknown);
5979
+ const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, {
5980
+ unknownIfNotFound: unsolvedTypeVarsAreUnknown,
5981
+ });
5957
5982
  return types_1.ClassType.cloneAsInstance(specializedType);
5958
5983
  }
5959
5984
  // Similar to applyExpectedTypeForConstructor, this function handles the
@@ -7118,7 +7143,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7118
7143
  }
7119
7144
  const effectiveReturnType = getFunctionEffectiveReturnType(type);
7120
7145
  let effectiveExpectedType = expectedType;
7121
- let effectiveFlags = 4 /* AllowTypeVarNarrowing */;
7146
+ let effectiveFlags = 0 /* Default */;
7122
7147
  if ((0, typeUtils_1.containsLiteralType)(effectiveExpectedType, /* includeTypeArgs */ true)) {
7123
7148
  effectiveFlags |= 128 /* RetainLiteralsForTypeVar */;
7124
7149
  }
@@ -7141,9 +7166,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7141
7166
  if (effectiveExpectedType) {
7142
7167
  // Prepopulate the typeVarContext based on the specialized expected type if the
7143
7168
  // callee has a declared return type. This will allow us to more closely match
7144
- // the expected type if possible. We set the AllowTypeVarNarrowing and
7145
- // SkipStripLiteralForTypeVar flags so the type can be further narrowed
7146
- // and so literals are not stripped.
7169
+ // the expected type if possible.
7147
7170
  // If the return type is not the same as the expected type but is
7148
7171
  // assignable to the expected type, determine which type arguments
7149
7172
  // are needed to match the expected type.
@@ -7340,15 +7363,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7340
7363
  // the call below to adjustCallableReturnType will "detach" these
7341
7364
  // TypeVars from the scope of this function and "attach" them to
7342
7365
  // the scope of the callable.
7343
- let unknownIfUnsolved = !(0, types_1.isFunction)(returnType);
7366
+ let unknownIfNotFound = !(0, types_1.isFunction)(returnType);
7344
7367
  // We'll also leave TypeVars unsolved if the call is a recursive
7345
7368
  // call to a generic function.
7346
7369
  const typeVarScopes = getTypeVarScopesForNode(errorNode);
7347
7370
  if (typeVarScopes.some((typeVarScope) => typeVarContext.hasSolveForScope(typeVarScope))) {
7348
- unknownIfUnsolved = false;
7371
+ unknownIfNotFound = false;
7349
7372
  }
7350
- let specializedReturnType = (0, typeUtils_1.addConditionToType)((0, typeUtils_1.applySolvedTypeVars)(returnType, typeVarContext, unknownIfUnsolved,
7351
- /* useNarrowBoundOnly */ false, eliminateUnsolvedInUnions), typeCondition);
7373
+ let specializedReturnType = (0, typeUtils_1.addConditionToType)((0, typeUtils_1.applySolvedTypeVars)(returnType, typeVarContext, {
7374
+ unknownIfNotFound,
7375
+ eliminateUnsolvedInUnions,
7376
+ }), typeCondition);
7352
7377
  // If the final return type is an unpacked tuple, turn it into a normal (unpacked) tuple.
7353
7378
  if ((0, types_1.isUnpackedClass)(specializedReturnType)) {
7354
7379
  specializedReturnType = types_1.ClassType.cloneForUnpacked(specializedReturnType, /* isUnpackedTuple */ false);
@@ -7413,20 +7438,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7413
7438
  }
7414
7439
  // Determines whether the specified argument list satisfies the function
7415
7440
  // signature bound to the specified ParamSpec. Return value indicates success.
7416
- function validateFunctionArgumentsForParamSpec(errorNode, argList, paramSpec, typeVarContext, conditionFilter) {
7441
+ function validateFunctionArgumentsForParamSpec(errorNode, argList, paramSpec, destTypeVarContext, conditionFilter) {
7417
7442
  var _a;
7418
- const paramSpecValue = typeVarContext.getParamSpec(paramSpec);
7419
- if (!paramSpecValue) {
7443
+ const paramSpecType = destTypeVarContext.getParamSpecType(paramSpec);
7444
+ if (!paramSpecType) {
7420
7445
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecNotBound().format({ type: printType(paramSpec) }), ((_a = argList[0]) === null || _a === void 0 ? void 0 : _a.valueExpression) || errorNode);
7421
7446
  return false;
7422
7447
  }
7423
- // If the ParamSpec was bound to a generic function, some TypeVars may
7424
- // not yet be solved. Add the TypeVar scope for the bound function.
7425
- typeVarContext.addSolveForScope(paramSpecValue.typeVarScopeId);
7448
+ const srcTypeVarContext = new typeVarContext_1.TypeVarContext(paramSpecType.details.typeVarScopeId);
7426
7449
  let reportedArgError = false;
7427
7450
  // Build a map of all named parameters.
7428
7451
  const paramMap = new Map();
7429
- const paramSpecParams = paramSpecValue.parameters;
7452
+ const paramSpecParams = paramSpecType.details.parameters;
7430
7453
  paramSpecParams.forEach((param) => {
7431
7454
  if (param.name) {
7432
7455
  paramMap.set(param.name, param);
@@ -7485,7 +7508,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7485
7508
  requiresTypeVarMatching: false,
7486
7509
  argument: arg,
7487
7510
  errorNode: arg.valueExpression || errorNode,
7488
- }, typeVarContext,
7511
+ }, srcTypeVarContext,
7489
7512
  /* functionType */ undefined,
7490
7513
  /* skipUnknownArgCheck */ false,
7491
7514
  /* skipOverloadArg */ false,
@@ -7507,7 +7530,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7507
7530
  const paramInfo = paramMap.get(name);
7508
7531
  return paramInfo.category === 0 /* Simple */ && !paramInfo.hasDefault;
7509
7532
  });
7510
- if (unassignedParams.length > 0 && !paramSpecValue.paramSpec) {
7533
+ if (unassignedParams.length > 0 && !paramSpecType.details.paramSpec) {
7511
7534
  const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
7512
7535
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
7513
7536
  ? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
@@ -7515,6 +7538,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7515
7538
  reportedArgError = true;
7516
7539
  }
7517
7540
  }
7541
+ if (!reportedArgError) {
7542
+ destTypeVarContext.applySourceContextTypeVars(srcTypeVarContext);
7543
+ }
7518
7544
  return !reportedArgError;
7519
7545
  }
7520
7546
  function validateArgType(argParam, typeVarContext, functionType, skipUnknownCheck, skipOverloadArg, useNarrowBoundOnly, conditionFilter) {
@@ -7536,8 +7562,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7536
7562
  functionType !== undefined &&
7537
7563
  argParam.paramType.scopeId === functionType.details.typeVarScopeId
7538
7564
  ? undefined
7539
- : (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext,
7540
- /* unknownIfNotFound */ false, useNarrowBoundOnly);
7565
+ : (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext, { useNarrowBoundOnly });
7541
7566
  // If the expected type is unknown, don't use an expected type. Instead,
7542
7567
  // use default rules for evaluating the expression type.
7543
7568
  if (expectedType && (0, types_1.isUnknown)(expectedType)) {
@@ -7856,8 +7881,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7856
7881
  // or constraint.
7857
7882
  if (typeVar.details.defaultType && defaultValueNode) {
7858
7883
  const typeVarContext = new typeVarContext_1.TypeVarContext(types_1.WildcardTypeVarScopeId);
7859
- const concreteDefaultType = (0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext,
7860
- /* unknownIfNotFound */ true);
7884
+ const concreteDefaultType = makeTopLevelTypeVarsConcrete((0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext, {
7885
+ unknownIfNotFound: true,
7886
+ }));
7861
7887
  if (typeVar.details.boundType) {
7862
7888
  if (!assignType(typeVar.details.boundType, concreteDefaultType)) {
7863
7889
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultBoundMismatch(), defaultValueNode);
@@ -8016,62 +8042,67 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8016
8042
  // in the Python specification: The static type checker will treat
8017
8043
  // the new type as if it were a subclass of the original type.
8018
8044
  function createNewType(errorNode, argList) {
8045
+ var _a;
8019
8046
  const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
8020
- let className = '_';
8021
- if (argList.length >= 1) {
8022
- const nameArg = argList[0];
8023
- if (nameArg.argumentCategory === 0 /* Simple */) {
8024
- if (nameArg.valueExpression && nameArg.valueExpression.nodeType === 48 /* StringList */) {
8025
- className = nameArg.valueExpression.strings.map((s) => s.value).join('');
8026
- }
8027
- }
8028
- }
8029
- if (argList.length >= 2) {
8030
- const baseClass = getTypeOfArgumentExpectingType(argList[1]).type;
8031
- if ((0, types_1.isInstantiableClass)(baseClass)) {
8032
- if (types_1.ClassType.isProtocolClass(baseClass)) {
8033
- addError(localize_1.Localizer.Diagnostic.newTypeProtocolClass(), argList[1].node || errorNode);
8034
- }
8035
- else if (baseClass.literalValue !== undefined) {
8036
- addError(localize_1.Localizer.Diagnostic.newTypeLiteral(), argList[1].node || errorNode);
8037
- }
8038
- const classFlags = baseClass.details.flags & ~(1 /* BuiltInClass */ | 2 /* SpecialBuiltIn */);
8039
- const classType = types_1.ClassType.createInstantiable(className, ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className), fileInfo.moduleName, fileInfo.filePath, classFlags, ParseTreeUtils.getTypeSourceId(errorNode),
8040
- /* declaredMetaclass */ undefined, baseClass.details.effectiveMetaclass);
8041
- classType.details.baseClasses.push(baseClass);
8042
- (0, typeUtils_1.computeMroLinearization)(classType);
8043
- // Synthesize an __init__ method that accepts only the specified type.
8044
- const initType = types_1.FunctionType.createSynthesizedInstance('__init__');
8045
- types_1.FunctionType.addParameter(initType, {
8046
- category: 0 /* Simple */,
8047
- name: 'self',
8048
- type: types_1.ClassType.cloneAsInstance(classType),
8049
- hasDeclaredType: true,
8050
- });
8051
- types_1.FunctionType.addParameter(initType, {
8052
- category: 0 /* Simple */,
8053
- name: '_x',
8054
- type: types_1.ClassType.cloneAsInstance(baseClass),
8055
- hasDeclaredType: true,
8056
- });
8057
- initType.details.declaredReturnType = types_1.NoneType.createInstance();
8058
- classType.details.fields.set('__init__', symbol_1.Symbol.createWithType(4 /* ClassMember */, initType));
8059
- // Synthesize a trivial __new__ method.
8060
- const newType = types_1.FunctionType.createSynthesizedInstance('__new__', 1 /* ConstructorMethod */);
8061
- types_1.FunctionType.addParameter(newType, {
8062
- category: 0 /* Simple */,
8063
- name: 'cls',
8064
- type: classType,
8065
- hasDeclaredType: true,
8066
- });
8067
- types_1.FunctionType.addDefaultParameters(newType);
8068
- newType.details.declaredReturnType = types_1.ClassType.cloneAsInstance(classType);
8069
- classType.details.fields.set('__new__', symbol_1.Symbol.createWithType(4 /* ClassMember */, newType));
8070
- return classType;
8071
- }
8072
- else if (!(0, types_1.isAnyOrUnknown)(baseClass)) {
8073
- addError(localize_1.Localizer.Diagnostic.newTypeNotAClass(), argList[1].node || errorNode);
8074
- }
8047
+ let className = '';
8048
+ if (argList.length !== 2) {
8049
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.newTypeParamCount(), errorNode);
8050
+ return undefined;
8051
+ }
8052
+ const nameArg = argList[0];
8053
+ if (nameArg.argumentCategory === 0 /* Simple */ &&
8054
+ nameArg.valueExpression &&
8055
+ nameArg.valueExpression.nodeType === 48 /* StringList */) {
8056
+ className = nameArg.valueExpression.strings.map((s) => s.value).join('');
8057
+ }
8058
+ if (!className) {
8059
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.newTypeBadName(), (_a = argList[0].node) !== null && _a !== void 0 ? _a : errorNode);
8060
+ return undefined;
8061
+ }
8062
+ const baseClass = getTypeOfArgumentExpectingType(argList[1]).type;
8063
+ if ((0, types_1.isInstantiableClass)(baseClass)) {
8064
+ if (types_1.ClassType.isProtocolClass(baseClass)) {
8065
+ addError(localize_1.Localizer.Diagnostic.newTypeProtocolClass(), argList[1].node || errorNode);
8066
+ }
8067
+ else if (baseClass.literalValue !== undefined) {
8068
+ addError(localize_1.Localizer.Diagnostic.newTypeLiteral(), argList[1].node || errorNode);
8069
+ }
8070
+ const classFlags = baseClass.details.flags & ~(1 /* BuiltInClass */ | 2 /* SpecialBuiltIn */);
8071
+ const classType = types_1.ClassType.createInstantiable(className, ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className), fileInfo.moduleName, fileInfo.filePath, classFlags, ParseTreeUtils.getTypeSourceId(errorNode),
8072
+ /* declaredMetaclass */ undefined, baseClass.details.effectiveMetaclass);
8073
+ classType.details.baseClasses.push(baseClass);
8074
+ (0, typeUtils_1.computeMroLinearization)(classType);
8075
+ // Synthesize an __init__ method that accepts only the specified type.
8076
+ const initType = types_1.FunctionType.createSynthesizedInstance('__init__');
8077
+ types_1.FunctionType.addParameter(initType, {
8078
+ category: 0 /* Simple */,
8079
+ name: 'self',
8080
+ type: types_1.ClassType.cloneAsInstance(classType),
8081
+ hasDeclaredType: true,
8082
+ });
8083
+ types_1.FunctionType.addParameter(initType, {
8084
+ category: 0 /* Simple */,
8085
+ name: '_x',
8086
+ type: types_1.ClassType.cloneAsInstance(baseClass),
8087
+ hasDeclaredType: true,
8088
+ });
8089
+ initType.details.declaredReturnType = types_1.NoneType.createInstance();
8090
+ classType.details.fields.set('__init__', symbol_1.Symbol.createWithType(4 /* ClassMember */, initType));
8091
+ // Synthesize a trivial __new__ method.
8092
+ const newType = types_1.FunctionType.createSynthesizedInstance('__new__', 1 /* ConstructorMethod */);
8093
+ types_1.FunctionType.addParameter(newType, {
8094
+ category: 0 /* Simple */,
8095
+ name: 'cls',
8096
+ type: classType,
8097
+ hasDeclaredType: true,
8098
+ });
8099
+ types_1.FunctionType.addDefaultParameters(newType);
8100
+ newType.details.declaredReturnType = types_1.ClassType.cloneAsInstance(classType);
8101
+ classType.details.fields.set('__new__', symbol_1.Symbol.createWithType(4 /* ClassMember */, newType));
8102
+ return classType;
8103
+ }
8104
+ if (!(0, types_1.isAnyOrUnknown)(baseClass)) {
8105
+ addError(localize_1.Localizer.Diagnostic.newTypeNotAClass(), argList[1].node || errorNode);
8075
8106
  }
8076
8107
  return undefined;
8077
8108
  }
@@ -9296,7 +9327,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9296
9327
  // type explicitly includes literals.
9297
9328
  let typeVarContext = new typeVarContext_1.TypeVarContext(targetTypeVar.scopeId);
9298
9329
  if (useSynthesizedTypeVar) {
9299
- typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType, expectedType);
9330
+ typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType,
9331
+ /* narrowBoundNoLiterals */ undefined, expectedType);
9300
9332
  }
9301
9333
  if (entryTypes.every((entryType) => assignType(targetTypeVar, stripLiteralValue(entryType), /* diag */ undefined, typeVarContext))) {
9302
9334
  return (0, typeUtils_1.applySolvedTypeVars)(targetTypeVar, typeVarContext);
@@ -9304,8 +9336,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9304
9336
  // Allocate a fresh typeVarContext before we try again with literals not stripped.
9305
9337
  typeVarContext = new typeVarContext_1.TypeVarContext(targetTypeVar.scopeId);
9306
9338
  if (useSynthesizedTypeVar) {
9307
- typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType, expectedType,
9308
- /* retainLiteral */ true);
9339
+ typeVarContext.setTypeVarType(targetTypeVar, isNarrowable ? undefined : expectedType,
9340
+ /* narrowBoundNoLiterals */ undefined, expectedType);
9309
9341
  }
9310
9342
  if (entryTypes.every((entryType) => assignType(targetTypeVar, entryType, /* diag */ undefined, typeVarContext))) {
9311
9343
  return (0, typeUtils_1.applySolvedTypeVars)(targetTypeVar, typeVarContext);
@@ -10375,7 +10407,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10375
10407
  }
10376
10408
  return createSpecialType(classType, typeArgs, /* paramLimit */ undefined, /* allowParamSpec */ true);
10377
10409
  }
10378
- function transformTypeForTypeAlias(type, name, errorNode, typeParameters) {
10410
+ function transformTypeForTypeAlias(type, name, errorNode, typeParameters, typeParamNodes) {
10379
10411
  if (!types_1.TypeBase.isInstantiable(type)) {
10380
10412
  return type;
10381
10413
  }
@@ -10404,6 +10436,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10404
10436
  }
10405
10437
  return (0, typeUtils_1.convertToInstance)(typeVar);
10406
10438
  });
10439
+ // Validate the default types for all type parameters.
10440
+ typeParameters.forEach((typeParam, index) => {
10441
+ var _a;
10442
+ let bestErrorNode = errorNode;
10443
+ if (typeParamNodes && index < typeParamNodes.length) {
10444
+ bestErrorNode = (_a = typeParamNodes[index].defaultExpression) !== null && _a !== void 0 ? _a : typeParamNodes[index].name;
10445
+ }
10446
+ validateTypeParameterDefault(bestErrorNode, typeParam, typeParameters.slice(0, index));
10447
+ });
10407
10448
  // Verify that we have at most one variadic type variable.
10408
10449
  const variadics = typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
10409
10450
  if (variadics.length > 1) {
@@ -10745,6 +10786,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10745
10786
  // path does not handle traditional type aliases, which are treated as
10746
10787
  // variables since they use normal variable assignment syntax.
10747
10788
  function getTypeOfTypeAlias(node) {
10789
+ var _a;
10748
10790
  const cachedType = readTypeCache(node.name, 0 /* None */);
10749
10791
  if (cachedType) {
10750
10792
  return cachedType;
@@ -10782,7 +10824,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10782
10824
  }
10783
10825
  // Clear the temporary type we wrote above.
10784
10826
  deleteTypeCacheEntry(node.name);
10785
- aliasType = transformTypeForTypeAlias(aliasType, node.name, node.expression, typeParameters);
10827
+ aliasType = transformTypeForTypeAlias(aliasType, node.name, node.expression, typeParameters, (_a = node.typeParameters) === null || _a === void 0 ? void 0 : _a.parameters);
10786
10828
  if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
10787
10829
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
10788
10830
  name: node.name.value,
@@ -11100,6 +11142,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11100
11142
  names: variadics.map((v) => `"${v.details.name}"`).join(', '),
11101
11143
  }), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
11102
11144
  }
11145
+ // Validate the default types for all type parameters.
11146
+ classType.details.typeParameters.forEach((typeParam, index) => {
11147
+ var _a;
11148
+ let bestErrorNode = node.name;
11149
+ if (node.typeParameters && index < node.typeParameters.parameters.length) {
11150
+ const typeParamNode = node.typeParameters.parameters[index];
11151
+ bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
11152
+ }
11153
+ validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
11154
+ });
11103
11155
  if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
11104
11156
  addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
11105
11157
  }
@@ -11288,6 +11340,34 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11288
11340
  }
11289
11341
  return { classType, decoratedType };
11290
11342
  }
11343
+ // Determines whether the type parameters has a default that refers to another
11344
+ // type parameter. If so, validates that it is in the list of "live" type
11345
+ // parameters and updates the scope of the type parameter referred to in the
11346
+ // default type expression.
11347
+ function validateTypeParameterDefault(errorNode, typeParam, otherLiveTypeParams) {
11348
+ if (!typeParam.details.defaultType) {
11349
+ const typeVarWithDefault = otherLiveTypeParams.find((param) => param.details.defaultType);
11350
+ if (typeVarWithDefault) {
11351
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarWithoutDefault().format({
11352
+ name: typeParam.details.name,
11353
+ other: typeVarWithDefault.details.name,
11354
+ }), errorNode);
11355
+ }
11356
+ return;
11357
+ }
11358
+ const invalidTypeVars = new Set();
11359
+ (0, typeUtils_1.validateTypeVarDefault)(typeParam, otherLiveTypeParams, invalidTypeVars);
11360
+ // If we found one or more unapplied type variable, report an error.
11361
+ if (invalidTypeVars.size > 0) {
11362
+ const diag = new diagnostic_1.DiagnosticAddendum();
11363
+ invalidTypeVars.forEach((name) => {
11364
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarDefaultOutOfScope().format({ name }));
11365
+ });
11366
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultInvalidTypeVar().format({
11367
+ name: typeParam.details.name,
11368
+ }) + diag.getString(), errorNode);
11369
+ }
11370
+ }
11291
11371
  function inferTypeParameterVarianceForClass(classType) {
11292
11372
  if (!classType.details.requiresVarianceInference) {
11293
11373
  return;
@@ -11594,6 +11674,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11594
11674
  });
11595
11675
  }
11596
11676
  function getTypeOfFunction(node) {
11677
+ var _a, _b;
11597
11678
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
11598
11679
  // Is this type already cached?
11599
11680
  const cachedFunctionType = readTypeCache(node.name, 0 /* None */);
@@ -11693,8 +11774,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11693
11774
  }), node.functionAnnotationComment);
11694
11775
  }
11695
11776
  }
11777
+ // If this function uses PEP 695 syntax for type parameters,
11778
+ // accumulate the list of type parameters upfront.
11779
+ const typeParametersSeen = [];
11696
11780
  if (node.typeParameters) {
11697
- evaluateTypeParameterList(node.typeParameters);
11781
+ functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters);
11782
+ }
11783
+ else {
11784
+ functionType.details.typeParameters = typeParametersSeen;
11698
11785
  }
11699
11786
  const markParamAccessed = (param) => {
11700
11787
  if (param.name) {
@@ -11842,6 +11929,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11842
11929
  isTypeInferred,
11843
11930
  };
11844
11931
  types_1.FunctionType.addParameter(functionType, functionParam);
11932
+ if (functionParam.hasDeclaredType) {
11933
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersSeen, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionParam.type));
11934
+ }
11845
11935
  if (param.name) {
11846
11936
  const variadicParamType = transformVariadicParamType(node, param.category, functionParam.type);
11847
11937
  paramTypes.push(variadicParamType);
@@ -11882,19 +11972,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11882
11972
  // If there was a defined return type, analyze that first so when we
11883
11973
  // walk the contents of the function, return statements can be
11884
11974
  // validated against this type.
11885
- if (node.returnTypeAnnotation) {
11975
+ const returnTypeAnnotationNode = (_a = node.returnTypeAnnotation) !== null && _a !== void 0 ? _a : (_b = node.functionAnnotationComment) === null || _b === void 0 ? void 0 : _b.returnTypeAnnotation;
11976
+ if (returnTypeAnnotationNode) {
11886
11977
  // Temporarily set the return type to unknown in case of recursion.
11887
11978
  functionType.details.declaredReturnType = types_1.UnknownType.create();
11888
- const returnType = getTypeOfAnnotation(node.returnTypeAnnotation, {
11889
- associateTypeVarsWithScope: true,
11890
- disallowRecursiveTypeAlias: true,
11891
- });
11892
- functionType.details.declaredReturnType = returnType;
11893
- }
11894
- else if (node.functionAnnotationComment) {
11895
- // Temporarily set the return type to unknown in case of recursion.
11896
- functionType.details.declaredReturnType = types_1.UnknownType.create();
11897
- const returnType = getTypeOfAnnotation(node.functionAnnotationComment.returnTypeAnnotation, {
11979
+ const returnType = getTypeOfAnnotation(returnTypeAnnotationNode, {
11898
11980
  associateTypeVarsWithScope: true,
11899
11981
  disallowRecursiveTypeAlias: true,
11900
11982
  });
@@ -11915,6 +11997,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11915
11997
  }
11916
11998
  }
11917
11999
  }
12000
+ // Accumulate any type parameters used in the return type.
12001
+ if (functionType.details.declaredReturnType && returnTypeAnnotationNode) {
12002
+ rescopeTypeVarsForCallableReturnType(functionType.details.declaredReturnType, functionType, typeParametersSeen);
12003
+ }
11918
12004
  // If the return type is explicitly annotated as a generator, mark the
11919
12005
  // function as a generator even though it may not contain a "yield" statement.
11920
12006
  // This is important for generator functions declared in stub files, abstract
@@ -11930,6 +12016,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11930
12016
  functionType.details.flags |= 16 /* Generator */;
11931
12017
  }
11932
12018
  }
12019
+ // Validate the default types for all type parameters.
12020
+ functionType.details.typeParameters.forEach((typeParam, index) => {
12021
+ var _a;
12022
+ let bestErrorNode = node.name;
12023
+ if (node.typeParameters && index < node.typeParameters.parameters.length) {
12024
+ const typeParamNode = node.typeParameters.parameters[index];
12025
+ bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
12026
+ }
12027
+ validateTypeParameterDefault(bestErrorNode, typeParam, functionType.details.typeParameters.slice(0, index));
12028
+ });
11933
12029
  // Clear the "partially evaluated" flag to indicate that the functionType
11934
12030
  // is fully evaluated.
11935
12031
  functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
@@ -11967,6 +12063,37 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11967
12063
  writeTypeCache(node, decoratedType, 0 /* None */, /* isIncomplete */ false);
11968
12064
  return { functionType, decoratedType };
11969
12065
  }
12066
+ // If the declared return type of a function contains type variables that
12067
+ // are found nowhere else in the signature and are contained within a
12068
+ // Callable, these type variables are "rescoped" from the function to
12069
+ // the Callable.
12070
+ function rescopeTypeVarsForCallableReturnType(returnType, functionType, typeParametersSeen) {
12071
+ const typeVarsInReturnType = (0, typeUtils_1.getTypeVarArgumentsRecursive)(returnType);
12072
+ const rescopedTypeVars = [];
12073
+ typeVarsInReturnType.forEach((typeVar) => {
12074
+ if (types_1.TypeBase.isInstantiable(typeVar)) {
12075
+ typeVar = types_1.TypeVarType.cloneAsInstance(typeVar);
12076
+ }
12077
+ // If this type variable isn't scoped to this function, it is probably
12078
+ // associated with an outer scope.
12079
+ if (typeVar.scopeId !== functionType.details.typeVarScopeId) {
12080
+ return;
12081
+ }
12082
+ // If this type variable was already seen in one or more input parameters,
12083
+ // don't attempt to rescope it.
12084
+ if (typeParametersSeen.some((tp) => (0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(tp), typeVar))) {
12085
+ return;
12086
+ }
12087
+ // Is this type variable seen outside of a single callable?
12088
+ if ((0, typeUtils_1.isTypeVarLimitedToCallable)(returnType, typeVar)) {
12089
+ rescopedTypeVars.push(typeVar);
12090
+ }
12091
+ });
12092
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersSeen, typeVarsInReturnType);
12093
+ // Note that the type parameters have been rescoped so they are not
12094
+ // considered valid for the body of this function.
12095
+ functionType.details.rescopedTypeParameters = rescopedTypeVars;
12096
+ }
11970
12097
  function adjustParameterAnnotatedType(param, type) {
11971
12098
  var _a;
11972
12099
  // PEP 484 indicates that if a parameter has a default value of 'None'
@@ -13315,36 +13442,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13315
13442
  // within that tree. If the type cannot be determined (because it's part
13316
13443
  // of a cyclical dependency), the function returns undefined.
13317
13444
  function evaluateTypeForSubnode(subnode, callback) {
13318
- // If the type cache is already populated, don't bother
13319
- // doing additional work.
13320
- let subnodeType = readTypeCache(subnode, /* flags */ undefined);
13321
- if (subnodeType) {
13322
- return { type: subnodeType };
13445
+ // If the type cache is already populated with a complete type,
13446
+ // don't bother doing additional work.
13447
+ let cacheEntry = readTypeCacheEntry(subnode);
13448
+ if (cacheEntry && !cacheEntry.isIncomplete) {
13449
+ return { type: cacheEntry.type };
13323
13450
  }
13324
- const oldIncompleteCache = incompleteTypeCache;
13325
- try {
13326
- // If there isn't already an incompleteTypeCache allocated, allocate
13327
- // one now. We'll use this same cache for nested calls, but we'll
13328
- // abandon it once the last nested call completes.
13329
- if (!incompleteTypeCache) {
13330
- incompleteTypeCache = new Map();
13331
- }
13332
- callback();
13333
- subnodeType = readTypeCache(subnode, /* flags */ undefined);
13334
- if (subnodeType) {
13335
- return { type: subnodeType };
13336
- }
13337
- subnodeType = incompleteTypeCache.get(subnode.id);
13338
- if (subnodeType) {
13339
- return { type: subnodeType, isIncomplete: true };
13340
- }
13341
- incompleteTypeCache = oldIncompleteCache;
13342
- }
13343
- catch (e) {
13344
- // We don't use a finally clause here because the debugger doesn't
13345
- // handle it well when stepping through code.
13346
- incompleteTypeCache = oldIncompleteCache;
13347
- throw e;
13451
+ callback();
13452
+ cacheEntry = readTypeCacheEntry(subnode);
13453
+ if (cacheEntry) {
13454
+ return { type: cacheEntry.type, isIncomplete: cacheEntry.isIncomplete };
13348
13455
  }
13349
13456
  return undefined;
13350
13457
  }
@@ -13609,8 +13716,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13609
13716
  }
13610
13717
  }
13611
13718
  }
13719
+ const typeVarContext = new typeVarContext_1.TypeVarContext(classType.details.typeVarScopeId);
13612
13720
  fullTypeParams.forEach((typeParam, index) => {
13613
- var _a;
13614
13721
  if (typeArgs && index < typeArgs.length) {
13615
13722
  if (typeParam.details.isParamSpec) {
13616
13723
  const typeArg = typeArgs[index];
@@ -13620,6 +13727,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13620
13727
  types_1.FunctionType.addDefaultParameters(functionType);
13621
13728
  functionType.details.flags |= 32768 /* SkipArgsKwargsCompatibilityCheck */;
13622
13729
  typeArgTypes.push(functionType);
13730
+ typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(functionType));
13623
13731
  return;
13624
13732
  }
13625
13733
  if (typeArg.typeList) {
@@ -13633,6 +13741,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13633
13741
  });
13634
13742
  });
13635
13743
  typeArgTypes.push(functionType);
13744
+ typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(functionType));
13636
13745
  return;
13637
13746
  }
13638
13747
  if ((0, types_1.isInstantiableClass)(typeArg.type) && types_1.ClassType.isBuiltIn(typeArg.type, 'Concatenate')) {
@@ -13659,10 +13768,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13659
13768
  return;
13660
13769
  }
13661
13770
  }
13662
- typeArgTypes.push((0, typeUtils_1.convertToInstance)(typeArgs[index].type));
13771
+ const typeArgType = (0, typeUtils_1.convertToInstance)(typeArgs[index].type);
13772
+ typeArgTypes.push(typeArgType);
13773
+ typeVarContext.setTypeVarType(typeParam, typeArgType);
13663
13774
  return;
13664
13775
  }
13665
- typeArgTypes.push((_a = typeParam.details.defaultType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create());
13776
+ const solvedDefaultType = (0, typeUtils_1.applySolvedTypeVars)(typeParam, typeVarContext, { unknownIfNotFound: true });
13777
+ typeArgTypes.push(solvedDefaultType);
13778
+ if ((0, types_1.isParamSpec)(typeParam)) {
13779
+ typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(solvedDefaultType));
13780
+ }
13781
+ else {
13782
+ typeVarContext.setTypeVarType(typeParam, solvedDefaultType);
13783
+ }
13666
13784
  });
13667
13785
  typeArgTypes = typeArgTypes.map((typeArgType, index) => {
13668
13786
  if (index < typeArgCount) {
@@ -14202,65 +14320,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14202
14320
  return undefined;
14203
14321
  }
14204
14322
  case 3 /* TypeParameter */: {
14205
- let typeVar = types_1.TypeVarType.createInstantiable(declaration.node.name.value);
14206
- if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
14207
- typeVar.details.isVariadic = true;
14208
- }
14209
- else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
14210
- typeVar.details.isParamSpec = true;
14211
- }
14212
- if (declaration.node.boundExpression) {
14213
- if (declaration.node.boundExpression.nodeType === 52 /* Tuple */) {
14214
- const constraints = declaration.node.boundExpression.expressions.map((constraint) => {
14215
- const constraintType = getTypeOfExpressionExpectingType(constraint).type;
14216
- if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
14217
- addError(localize_1.Localizer.Diagnostic.typeVarBoundGeneric(), constraint);
14218
- }
14219
- return (0, typeUtils_1.convertToInstance)(constraintType);
14220
- });
14221
- if (constraints.length < 2) {
14222
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(declaration.node.boundExpression).diagnosticRuleSet
14223
- .reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), declaration.node.boundExpression);
14224
- }
14225
- else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
14226
- typeVar.details.constraints = constraints;
14227
- }
14228
- }
14229
- else {
14230
- const boundType = getTypeOfExpressionExpectingType(declaration.node.boundExpression).type;
14231
- if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
14232
- addError(localize_1.Localizer.Diagnostic.typeVarConstraintGeneric(), declaration.node.boundExpression);
14233
- }
14234
- if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
14235
- typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
14236
- }
14237
- }
14238
- }
14239
- if (declaration.node.defaultExpression) {
14240
- // TODO - need to finish. For now, just evaluate the expression
14241
- // to generate any errors.
14242
- getTypeOfExpression(declaration.node.defaultExpression, 2097152 /* AllowUnpackedTupleOrTypeVarTuple */);
14243
- }
14244
- typeVar.details.isTypeParamSyntax = true;
14245
- // Associate the type variable with the owning scope.
14246
- const scopeNode = ParseTreeUtils.getTypeVarScopeNode(declaration.node);
14247
- if (scopeNode) {
14248
- let scopeType;
14249
- if (scopeNode.nodeType === 10 /* Class */) {
14250
- scopeType = 0 /* Class */;
14251
- // Set the variance to "auto" for class-scoped TypeVars.
14252
- typeVar.details.declaredVariance = 0 /* Auto */;
14253
- }
14254
- else if (scopeNode.nodeType === 28 /* Function */) {
14255
- scopeType = 1 /* Function */;
14256
- }
14257
- else {
14258
- (0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
14259
- scopeType = 2 /* TypeAlias */;
14260
- }
14261
- typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
14262
- }
14263
- return typeVar;
14323
+ return getTypeOfTypeParameter(declaration.node);
14264
14324
  }
14265
14325
  case 1 /* Variable */: {
14266
14326
  const typeAnnotationNode = declaration.typeAnnotationNode;
@@ -14305,6 +14365,99 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14305
14365
  }
14306
14366
  }
14307
14367
  }
14368
+ function getTypeOfTypeParameter(node) {
14369
+ // Is this type already cached?
14370
+ const cachedTypeVarType = readTypeCache(node.name, 0 /* None */);
14371
+ if (cachedTypeVarType && (0, types_1.isTypeVar)(cachedTypeVarType)) {
14372
+ return cachedTypeVarType;
14373
+ }
14374
+ let typeVar = types_1.TypeVarType.createInstantiable(node.name.value);
14375
+ typeVar.details.isTypeParamSyntax = true;
14376
+ if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
14377
+ typeVar.details.isVariadic = true;
14378
+ }
14379
+ else if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
14380
+ typeVar.details.isParamSpec = true;
14381
+ }
14382
+ // Cache the value before we evaluate the bound or the default type in
14383
+ // case it refers to itself in a circular manner.
14384
+ writeTypeCache(node, typeVar, /* flags */ undefined, /* isIncomplete */ false);
14385
+ writeTypeCache(node.name, typeVar, /* flags */ undefined, /* isIncomplete */ false);
14386
+ if (node.boundExpression) {
14387
+ if (node.boundExpression.nodeType === 52 /* Tuple */) {
14388
+ const constraints = node.boundExpression.expressions.map((constraint) => {
14389
+ const constraintType = getTypeOfExpressionExpectingType(constraint).type;
14390
+ if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
14391
+ addError(localize_1.Localizer.Diagnostic.typeVarBoundGeneric(), constraint);
14392
+ }
14393
+ return (0, typeUtils_1.convertToInstance)(constraintType);
14394
+ });
14395
+ if (constraints.length < 2) {
14396
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node.boundExpression).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), node.boundExpression);
14397
+ }
14398
+ else if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
14399
+ typeVar.details.constraints = constraints;
14400
+ }
14401
+ }
14402
+ else {
14403
+ const boundType = getTypeOfExpressionExpectingType(node.boundExpression).type;
14404
+ if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
14405
+ addError(localize_1.Localizer.Diagnostic.typeVarConstraintGeneric(), node.boundExpression);
14406
+ }
14407
+ if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
14408
+ typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
14409
+ }
14410
+ }
14411
+ }
14412
+ if (node.defaultExpression) {
14413
+ if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
14414
+ typeVar.details.defaultType = getParamSpecDefaultType(node.defaultExpression);
14415
+ }
14416
+ else if (node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
14417
+ typeVar.details.defaultType = getTypeVarTupleDefaultType(node.defaultExpression);
14418
+ }
14419
+ else {
14420
+ typeVar.details.defaultType = (0, typeUtils_1.convertToInstance)(getTypeOfExpressionExpectingType(node.defaultExpression).type);
14421
+ }
14422
+ }
14423
+ // If a default is provided, make sure it is compatible with the bound
14424
+ // or constraint.
14425
+ if (typeVar.details.defaultType && node.defaultExpression) {
14426
+ const typeVarContext = new typeVarContext_1.TypeVarContext(types_1.WildcardTypeVarScopeId);
14427
+ const concreteDefaultType = (0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext, {
14428
+ unknownIfNotFound: true,
14429
+ });
14430
+ if (typeVar.details.boundType) {
14431
+ if (!assignType(typeVar.details.boundType, concreteDefaultType)) {
14432
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultBoundMismatch(), node.defaultExpression);
14433
+ }
14434
+ }
14435
+ else if (typeVar.details.constraints.length > 0) {
14436
+ if (!typeVar.details.constraints.some((constraint) => (0, types_1.isTypeSame)(constraint, concreteDefaultType))) {
14437
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultConstraintMismatch(), node.defaultExpression);
14438
+ }
14439
+ }
14440
+ }
14441
+ // Associate the type variable with the owning scope.
14442
+ const scopeNode = ParseTreeUtils.getTypeVarScopeNode(node);
14443
+ if (scopeNode) {
14444
+ let scopeType;
14445
+ if (scopeNode.nodeType === 10 /* Class */) {
14446
+ scopeType = 0 /* Class */;
14447
+ // Set the variance to "auto" for class-scoped TypeVars.
14448
+ typeVar.details.declaredVariance = 0 /* Auto */;
14449
+ }
14450
+ else if (scopeNode.nodeType === 28 /* Function */) {
14451
+ scopeType = 1 /* Function */;
14452
+ }
14453
+ else {
14454
+ (0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
14455
+ scopeType = 2 /* TypeAlias */;
14456
+ }
14457
+ typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
14458
+ }
14459
+ return typeVar;
14460
+ }
14308
14461
  function getInferredTypeOfDeclaration(symbol, decl) {
14309
14462
  var _a, _b;
14310
14463
  const resolvedDecl = resolveAliasDeclaration(decl,
@@ -15244,7 +15397,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15244
15397
  const removedArgs = srcTypeArgs.splice(destVariadicIndex, srcArgsToCapture);
15245
15398
  // Package up the remaining type arguments into a tuple object.
15246
15399
  const variadicTuple = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, removedArgs.map((typeArg) => {
15247
- return { type: stripLiteralValue(typeArg.type), isUnbounded: typeArg.isUnbounded };
15400
+ return { type: typeArg.type, isUnbounded: typeArg.isUnbounded };
15248
15401
  }),
15249
15402
  /* isTypeArgumentExplicit */ true,
15250
15403
  /* isUnpackedTuple */ true));
@@ -15272,7 +15425,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15272
15425
  for (let argIndex = 0; argIndex < srcTypeArgs.length; argIndex++) {
15273
15426
  const entryDiag = diag === null || diag === void 0 ? void 0 : diag.createAddendum();
15274
15427
  if (!assignType(destTypeArgs[argIndex].type, srcTypeArgs[argIndex].type, entryDiag === null || entryDiag === void 0 ? void 0 : entryDiag.createAddendum(), typeVarContext,
15275
- /* srcTypeVarContext */ undefined, flags | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
15428
+ /* srcTypeVarContext */ undefined, flags, recursionCount)) {
15276
15429
  if (entryDiag) {
15277
15430
  entryDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.tupleEntryTypeMismatch().format({
15278
15431
  entry: argIndex + 1,
@@ -15376,7 +15529,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15376
15529
  for (let i = 0; i < destType.details.typeParameters.length; i++) {
15377
15530
  const typeArgType = i < srcTypeArgs.length ? srcTypeArgs[i] : types_1.UnknownType.create();
15378
15531
  destTypeVarContext.setTypeVarType(destType.details.typeParameters[i],
15379
- /* narrowBound */ undefined, typeArgType);
15532
+ /* narrowBound */ undefined,
15533
+ /* narrowBoundNoLiterals */ undefined, typeArgType);
15380
15534
  }
15381
15535
  }
15382
15536
  return true;
@@ -15513,24 +15667,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15513
15667
  }
15514
15668
  else {
15515
15669
  // Have we already recursed once?
15516
- if ((flags & 2048 /* SkipRecursiveTypeCheck */) !== 0) {
15670
+ if ((flags & 4 /* SkipRecursiveTypeCheck */) !== 0) {
15517
15671
  return true;
15518
15672
  }
15519
15673
  // Note that we are comparing two recursive types and do
15520
15674
  // not recursive more than once.
15521
- flags |= 2048 /* SkipRecursiveTypeCheck */;
15675
+ flags |= 4 /* SkipRecursiveTypeCheck */;
15522
15676
  }
15523
15677
  }
15524
15678
  // Transform recursive type aliases if necessary.
15525
15679
  const transformedDestType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(destType);
15526
15680
  const transformedSrcType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(srcType);
15527
- // Did both the source and dest include recursive type aliases?
15528
- // If so, we are potentially dealing with different recursive type
15529
- // aliases that are defined in the same way.
15530
- if (transformedDestType !== destType &&
15531
- transformedSrcType !== srcType &&
15532
- (0, types_1.isUnion)(transformedDestType) &&
15533
- (0, types_1.isUnion)(transformedSrcType)) {
15681
+ // Did either the source or dest include recursive type aliases?
15682
+ // If so, we could be dealing with different recursive type aliases
15683
+ // or a recursive type alias and a recursive protocol definition.
15684
+ if ((transformedDestType !== destType && (0, types_1.isUnion)(transformedDestType)) ||
15685
+ (transformedSrcType !== srcType && (0, types_1.isUnion)(transformedSrcType))) {
15534
15686
  // Use a smaller recursive limit in this case to prevent runaway recursion.
15535
15687
  if (recursionCount > maxRecursiveTypeAliasRecursionCount) {
15536
15688
  return true;
@@ -15548,9 +15700,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15548
15700
  if ((flags & 16 /* OverloadOverlapCheck */) !== 0) {
15549
15701
  srcType = makeTopLevelTypeVarsConcrete(srcType);
15550
15702
  }
15551
- // Strip a few of the flags we don't want to propagate to other calls.
15703
+ // Strip flags we don't want to propagate to other calls.
15552
15704
  const originalFlags = flags;
15553
- flags &= ~(64 /* AllowBoolTypeGuard */ | 4 /* AllowTypeVarNarrowing */);
15705
+ flags &= ~64 /* AllowBoolTypeGuard */;
15554
15706
  // Before performing any other checks, see if the dest type is a
15555
15707
  // TypeVar that we are attempting to match.
15556
15708
  if ((0, types_1.isTypeVar)(destType)) {
@@ -15628,27 +15780,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15628
15780
  /* srcTypeVarContext */ undefined, originalFlags, recursionCount);
15629
15781
  }
15630
15782
  else {
15631
- // Reverse the order of assignment to populate the TypeVarContext for
15632
- // the source TypeVar. Normally we set the AllowTypeVarNarrowing flag
15633
- // so the wide type bound of the TypeVar is set rather than the narrow
15634
- // type bound. This allows the type to be further narrowed through other
15635
- // assignments. However, if we're populating the expected type in the
15636
- // TypeVarContext, we don't want to allow further narrowing.
15637
- let effectiveFlags = originalFlags;
15638
- if ((originalFlags & 1024 /* PopulatingExpectedType */) !== 0) {
15639
- effectiveFlags &= ~(2 /* ReverseTypeVarMatching */ | 4 /* AllowTypeVarNarrowing */);
15640
- }
15641
- else {
15642
- effectiveFlags |= 4 /* AllowTypeVarNarrowing */;
15643
- }
15644
- if ((0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, srcType, destType, diag, srcTypeVarContext, effectiveFlags, recursionCount)) {
15783
+ if ((0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, srcType, destType, diag, srcTypeVarContext, originalFlags, recursionCount)) {
15645
15784
  return true;
15646
15785
  }
15647
15786
  // If the dest type is a union, only one of the subtypes needs to match.
15648
15787
  let isAssignable = false;
15649
15788
  if ((0, types_1.isUnion)(destType)) {
15650
15789
  (0, typeUtils_1.doForEachSubtype)(destType, (destSubtype) => {
15651
- if ((0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, srcType, destSubtype, diag, srcTypeVarContext, originalFlags | 4 /* AllowTypeVarNarrowing */, recursionCount)) {
15790
+ if ((0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, srcType, destSubtype, diag, srcTypeVarContext, originalFlags, recursionCount)) {
15652
15791
  isAssignable = true;
15653
15792
  }
15654
15793
  });
@@ -16015,17 +16154,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16015
16154
  // to eliminate as many exact type matches between the src and dest.
16016
16155
  if ((0, types_1.isUnion)(destType)) {
16017
16156
  // Handle the special case where the dest is a union of Any and
16018
- // a type variable and AssignTypeFlags.AllowTypeVarNarrowing is
16019
- // in effect. This occurs, for example, with the return type of
16157
+ // a type variable. This occurs, for example, with the return type of
16020
16158
  // the getattr function.
16021
- if ((flags & 4 /* AllowTypeVarNarrowing */) !== 0) {
16022
- const nonAnySubtypes = destType.subtypes.filter((t) => !(0, types_1.isAnyOrUnknown)(t));
16023
- if (nonAnySubtypes.length === 1 && (0, types_1.isTypeVar)(nonAnySubtypes[0])) {
16024
- assignType(nonAnySubtypes[0], srcType,
16025
- /* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
16026
- // This always succeeds because the destination contains Any.
16027
- return true;
16028
- }
16159
+ const nonAnySubtypes = destType.subtypes.filter((t) => !(0, types_1.isAnyOrUnknown)(t));
16160
+ if (nonAnySubtypes.length === 1 && (0, types_1.isTypeVar)(nonAnySubtypes[0])) {
16161
+ assignType(nonAnySubtypes[0], srcType,
16162
+ /* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
16163
+ // This always succeeds because the destination contains Any.
16164
+ return true;
16029
16165
  }
16030
16166
  const remainingDestSubtypes = [];
16031
16167
  let remainingSrcSubtypes = [...srcType.subtypes];
@@ -16457,9 +16593,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16457
16593
  let specializedDestType = destType;
16458
16594
  let reverseMatchingFailed = false;
16459
16595
  if ((flags & 2 /* ReverseTypeVarMatching */) === 0) {
16460
- specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext,
16461
- /* unknownIfNotFound */ undefined,
16462
- /* useNarrowBoundOnly */ true);
16596
+ specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext, { useNarrowBoundOnly: true });
16463
16597
  if ((0, typeUtils_1.requiresSpecialization)(specializedDestType)) {
16464
16598
  reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
16465
16599
  /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
@@ -16469,9 +16603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16469
16603
  }
16470
16604
  }
16471
16605
  else {
16472
- specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext,
16473
- /* unknownIfNotFound */ undefined,
16474
- /* useNarrowBoundOnly */ true);
16606
+ specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext, { useNarrowBoundOnly: true });
16475
16607
  if ((0, typeUtils_1.requiresSpecialization)(specializedSrcType)) {
16476
16608
  reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
16477
16609
  /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
@@ -16496,8 +16628,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16496
16628
  if ((0, types_1.isTypeVar)(specializedSrcType) &&
16497
16629
  specializedSrcType.details.isSynthesizedSelf &&
16498
16630
  specializedSrcType.details.boundType) {
16499
- specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(specializedSrcType.details.boundType, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(specializedSrcType)),
16500
- /* unknownIfNotFound */ true);
16631
+ specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(specializedSrcType.details.boundType, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(specializedSrcType)), { unknownIfNotFound: true });
16501
16632
  }
16502
16633
  }
16503
16634
  if (!assignType(specializedSrcType, specializedDestType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), srcTypeVarContext, destTypeVarContext, flags, recursionCount)) {
@@ -16895,18 +17026,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16895
17026
  assignType(typeVarEntry.typeVar, effectiveSrcTypeVarContext.getTypeVarType(typeVarEntry.typeVar),
16896
17027
  /* diag */ undefined, destTypeVarContext, srcTypeVarContext, 0 /* Default */, recursionCount);
16897
17028
  });
16898
- // Perform partial specialization of type variables to allow for
16899
- // "higher-order" type variables.
16900
- if (!destTypeVarContext.isLocked()) {
16901
- destTypeVarContext.getTypeVars().forEach((entry) => {
16902
- if (entry.narrowBound) {
16903
- const specializedType = (0, typeUtils_1.applySolvedTypeVars)(entry.narrowBound, destTypeVarContext);
16904
- if (specializedType !== entry.narrowBound) {
16905
- destTypeVarContext.setTypeVarType(entry.typeVar, specializedType, entry.wideBound, entry.retainLiteral);
16906
- }
16907
- }
16908
- });
16909
- }
16910
17029
  // Are we assigning to a function with a ParamSpec?
16911
17030
  if (targetIncludesParamSpec) {
16912
17031
  const effectiveDestType = (flags & 2 /* ReverseTypeVarMatching */) === 0 ? destType : srcType;
@@ -17030,6 +17149,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17030
17149
  }
17031
17150
  }
17032
17151
  }
17152
+ // Apply any solved source TypeVars to the dest TypeVar solutions. This
17153
+ // allows for higher-order functions to accept generic callbacks.
17154
+ destTypeVarContext.applySourceContextTypeVars(srcTypeVarContext);
17033
17155
  return canAssign;
17034
17156
  }
17035
17157
  // If the declaredType contains type arguments that are "Any" and
@@ -17191,9 +17313,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17191
17313
  // Verify that the positional param count matches exactly or that the override
17192
17314
  // adds only params that preserve the original signature.
17193
17315
  let foundParamCountMismatch = false;
17194
- if (overrideParamDetails.positionParamCount < baseParamDetails.positionParamCount &&
17195
- overrideParamDetails.argsIndex === undefined) {
17196
- foundParamCountMismatch = true;
17316
+ if (overrideParamDetails.positionParamCount < baseParamDetails.positionParamCount) {
17317
+ if (overrideParamDetails.argsIndex === undefined) {
17318
+ foundParamCountMismatch = true;
17319
+ }
17320
+ else {
17321
+ const overrideArgsType = overrideParamDetails.params[overrideParamDetails.argsIndex].type;
17322
+ for (let i = overrideParamDetails.positionParamCount; i < baseParamDetails.positionParamCount; i++) {
17323
+ if (!assignType(overrideArgsType, baseParamDetails.params[i].type, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
17324
+ localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
17325
+ index: i + 1,
17326
+ baseType: printType(baseParamDetails.params[i].type),
17327
+ overrideType: printType(overrideArgsType),
17328
+ });
17329
+ canOverride = false;
17330
+ }
17331
+ }
17332
+ }
17197
17333
  }
17198
17334
  else if (overrideParamDetails.positionParamCount > baseParamDetails.positionParamCount) {
17199
17335
  // Verify that all of the override parameters that extend the