@zzzen/pyright-internal 1.2.0-dev.20221225 → 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 (47) hide show
  1. package/dist/analyzer/binder.js +5 -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 +17 -9
  5. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  6. package/dist/analyzer/constraintSolver.js +30 -31
  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/sourceFile.js +1 -0
  13. package/dist/analyzer/sourceFile.js.map +1 -1
  14. package/dist/analyzer/typeCacheUtils.d.ts +28 -0
  15. package/dist/analyzer/{typeCache.js → typeCacheUtils.js} +8 -14
  16. package/dist/analyzer/typeCacheUtils.js.map +1 -0
  17. package/dist/analyzer/typeEvaluator.js +447 -281
  18. package/dist/analyzer/typeEvaluator.js.map +1 -1
  19. package/dist/analyzer/typeGuards.js +1 -2
  20. package/dist/analyzer/typeGuards.js.map +1 -1
  21. package/dist/analyzer/typeUtils.d.ts +12 -3
  22. package/dist/analyzer/typeUtils.js +283 -134
  23. package/dist/analyzer/typeUtils.js.map +1 -1
  24. package/dist/analyzer/typeVarContext.d.ts +2 -10
  25. package/dist/analyzer/typeVarContext.js +12 -31
  26. package/dist/analyzer/typeVarContext.js.map +1 -1
  27. package/dist/analyzer/types.d.ts +4 -12
  28. package/dist/analyzer/types.js +22 -22
  29. package/dist/analyzer/types.js.map +1 -1
  30. package/dist/commands/dumpFileDebugInfoCommand.js +2 -2
  31. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  32. package/dist/localization/localize.d.ts +18 -3
  33. package/dist/localization/localize.js +7 -1
  34. package/dist/localization/localize.js.map +1 -1
  35. package/dist/localization/package.nls.en-us.json +7 -1
  36. package/dist/parser/parser.js +3 -1
  37. package/dist/parser/parser.js.map +1 -1
  38. package/dist/tests/typeEvaluator2.test.js +1 -1
  39. package/dist/tests/typeEvaluator3.test.js +5 -1
  40. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  41. package/dist/tests/typeEvaluator4.test.js +4 -0
  42. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  43. package/dist/tests/typeEvaluator5.test.js +49 -7
  44. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  45. package/package.json +1 -1
  46. package/dist/analyzer/typeCache.d.ts +0 -40
  47. 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) {
@@ -2758,7 +2746,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2758
2746
  return undefined;
2759
2747
  }
2760
2748
  function getTypeOfName(node, flags) {
2761
- var _a, _b;
2749
+ var _a;
2762
2750
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
2763
2751
  const name = node.value;
2764
2752
  let symbol;
@@ -2769,7 +2757,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2769
2757
  const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
2770
2758
  if (typeParamSymbol) {
2771
2759
  symbol = typeParamSymbol;
2772
- 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);
2773
2764
  setSymbolAccessed(fileInfo, symbol, node);
2774
2765
  }
2775
2766
  else {
@@ -2910,7 +2901,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2910
2901
  type.details.name === name) {
2911
2902
  // Handle the special case of a PEP 604 union. These can appear within
2912
2903
  // an implied type alias where we are not expecting a type.
2913
- 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 */ &&
2914
2905
  node.parent.operator === 6 /* BitwiseOr */;
2915
2906
  if (!isPep604Union) {
2916
2907
  // A TypeVar in contexts where we're not expecting a type is
@@ -3026,7 +3017,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3026
3017
  if (memberName === 'args' || memberName === 'kwargs') {
3027
3018
  const outerFunctionScope = ParseTreeUtils.getEnclosingClassOrFunction(enclosingScope);
3028
3019
  if ((outerFunctionScope === null || outerFunctionScope === void 0 ? void 0 : outerFunctionScope.nodeType) === 28 /* Function */) {
3029
- 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
+ }
3030
3029
  }
3031
3030
  else if (!scopedTypeVarInfo.type.scopeId) {
3032
3031
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecNotUsedByOuterScope().format({
@@ -3060,9 +3059,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3060
3059
  else if ((flags & 4096 /* DisallowTypeVarsWithoutScopeId */) !== 0) {
3061
3060
  if ((type.scopeId === undefined || scopedTypeVarInfo.foundInterveningClass) &&
3062
3061
  !type.details.isSynthesized) {
3063
- const message = (0, types_1.isParamSpec)(type)
3064
- ? localize_1.Localizer.Diagnostic.paramSpecNotUsedByOuterScope()
3065
- : 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
+ }
3066
3073
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message.format({ name: type.details.name }), node);
3067
3074
  }
3068
3075
  }
@@ -3078,43 +3085,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3078
3085
  // type arguments. If so, it fills in these type arguments with Unknown
3079
3086
  // and optionally reports an error.
3080
3087
  function reportMissingTypeArguments(node, type, flags) {
3081
- if ((flags & 2 /* DoNotSpecialize */) === 0) {
3082
- if ((0, types_1.isInstantiableClass)(type)) {
3083
- if ((flags & 64 /* ExpectingType */) !== 0) {
3084
- if ((0, typeUtils_1.requiresTypeArguments)(type) && !type.typeArguments) {
3085
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForClass().format({
3086
- name: type.aliasName || type.details.name,
3087
- }), node);
3088
- }
3089
- }
3090
- if (!type.typeArguments) {
3091
- 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);
3092
3098
  }
3093
3099
  }
3094
- if ((flags & 64 /* ExpectingType */) !== 0 &&
3095
- type.typeAliasInfo &&
3096
- type.typeAliasInfo.typeParameters &&
3097
- type.typeAliasInfo.typeParameters.length > 0 &&
3098
- !type.typeAliasInfo.typeArguments) {
3099
- let reportMissingTypeArguments = false;
3100
- const defaultTypeArgs = [];
3101
- type.typeAliasInfo.typeParameters.forEach((param) => {
3102
- if (param.details.defaultType) {
3103
- defaultTypeArgs.push(param.details.defaultType);
3104
- }
3105
- else {
3106
- defaultTypeArgs.push(types_1.UnknownType.create());
3107
- reportMissingTypeArguments = true;
3108
- }
3109
- });
3110
- const typeVarContext = (0, typeUtils_1.buildTypeVarContext)(type.typeAliasInfo.typeParameters, defaultTypeArgs, type.typeAliasInfo.typeVarScopeId);
3111
- if (reportMissingTypeArguments) {
3112
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForAlias().format({
3113
- name: type.typeAliasInfo.name,
3114
- }), 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();
3115
3123
  }
3116
- 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);
3117
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);
3118
3133
  }
3119
3134
  return type;
3120
3135
  }
@@ -3148,8 +3163,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3148
3163
  return scopeIds;
3149
3164
  }
3150
3165
  // Walks up the parse tree to find a function, class, or type alias
3151
- // assignment that provides the context for a type variable.
3166
+ // declaration that provides the context for a type variable.
3152
3167
  function findScopedTypeVar(node, type) {
3168
+ var _a;
3153
3169
  let curNode = node;
3154
3170
  let nestedClassCount = 0;
3155
3171
  (0, debug_1.assert)(types_1.TypeBase.isInstantiable(type));
@@ -3171,14 +3187,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3171
3187
  else if (curNode.nodeType === 28 /* Function */) {
3172
3188
  const functionTypeInfo = getTypeOfFunction(curNode);
3173
3189
  if (functionTypeInfo) {
3174
- typeParametersForScope = [];
3175
- functionTypeInfo.functionType.details.parameters.forEach((param) => {
3176
- if (param.hasDeclaredType) {
3177
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(param.type));
3178
- }
3179
- });
3180
- if (functionTypeInfo.functionType.details.declaredReturnType) {
3181
- (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 };
3182
3197
  }
3183
3198
  }
3184
3199
  scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
@@ -3191,7 +3206,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3191
3206
  if (match === null || match === void 0 ? void 0 : match.scopeId) {
3192
3207
  // Use the scoped version of the TypeVar rather than the (unscoped) original type.
3193
3208
  type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
3194
- return { type, foundInterveningClass: nestedClassCount > 1 && !scopeUsesTypeParameterSyntax };
3209
+ return {
3210
+ type,
3211
+ isRescoped: false,
3212
+ foundInterveningClass: nestedClassCount > 1 && !scopeUsesTypeParameterSyntax,
3213
+ };
3195
3214
  }
3196
3215
  }
3197
3216
  curNode = curNode.parent;
@@ -3224,6 +3243,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3224
3243
  }
3225
3244
  return {
3226
3245
  type: types_1.TypeVarType.cloneForScopeId(type, leftType.details.recursiveTypeAliasScopeId, leftType.details.recursiveTypeAliasName, 2 /* TypeAlias */),
3246
+ isRescoped: false,
3227
3247
  foundInterveningClass: false,
3228
3248
  };
3229
3249
  }
@@ -3231,7 +3251,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3231
3251
  curNode = curNode.parent;
3232
3252
  }
3233
3253
  // Return the original type.
3234
- return { type, foundInterveningClass: false };
3254
+ return { type, isRescoped: false, foundInterveningClass: false };
3235
3255
  }
3236
3256
  function getTypeOfMemberAccess(node, flags) {
3237
3257
  const baseTypeFlags = 2 /* DoNotSpecialize */ |
@@ -4205,12 +4225,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4205
4225
  }
4206
4226
  return indexTypeResult;
4207
4227
  }
4208
- function adjustTypeArgumentsForVariadicTypeVar(typeArgs, typeParameters, errorNode) {
4209
- var _a;
4228
+ function adjustTypeArgumentsForVariadicTypeVar(typeArgs, typeParameters, typeVarScopeId, errorNode) {
4210
4229
  const variadicIndex = typeParameters.findIndex((param) => (0, types_1.isVariadicTypeVar)(param));
4211
4230
  // Do we need to adjust the type arguments to map to a variadic type
4212
4231
  // param at the end of the list?
4213
4232
  if (variadicIndex >= 0) {
4233
+ const variadicTypeVar = typeParameters[variadicIndex];
4214
4234
  if (tupleClassType && (0, types_1.isInstantiableClass)(tupleClassType)) {
4215
4235
  if (variadicIndex < typeArgs.length) {
4216
4236
  const variadicTypeResults = typeArgs.slice(variadicIndex, variadicIndex + 1 + typeArgs.length - typeParameters.length);
@@ -4250,11 +4270,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4250
4270
  ];
4251
4271
  }
4252
4272
  }
4253
- else {
4273
+ else if (!variadicTypeVar.details.defaultType) {
4254
4274
  // Add an empty tuple that maps to the TypeVarTuple type parameter.
4255
4275
  typeArgs.push({
4256
4276
  node: errorNode,
4257
- 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, [],
4258
4278
  /* isTypeArgumentExplicit */ true,
4259
4279
  /* isUnpackedTuple */ true)),
4260
4280
  });
@@ -4291,7 +4311,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4291
4311
  return undefined;
4292
4312
  }
4293
4313
  const typeParameters = baseType.typeAliasInfo.typeParameters;
4294
- let typeArgs = adjustTypeArgumentsForVariadicTypeVar(getTypeArgs(node, flags), typeParameters, node);
4314
+ let typeArgs = adjustTypeArgumentsForVariadicTypeVar(getTypeArgs(node, flags), typeParameters, baseType.typeAliasInfo.typeVarScopeId, node);
4295
4315
  // PEP 612 says that if the class has only one type parameter consisting
4296
4316
  // of a ParamSpec, the list of arguments does not need to be enclosed in
4297
4317
  // a list. We'll handle that case specially here. Presumably this applies to
@@ -4324,7 +4344,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4324
4344
  const typeVarContext = new typeVarContext_1.TypeVarContext(baseType.typeAliasInfo.typeVarScopeId);
4325
4345
  const diag = new diagnostic_1.DiagnosticAddendum();
4326
4346
  typeParameters.forEach((param, index) => {
4327
- var _a;
4328
4347
  if (param.details.isParamSpec && index < typeArgs.length) {
4329
4348
  const typeArgType = typeArgs[index].type;
4330
4349
  if (typeArgs[index].typeList) {
@@ -4387,9 +4406,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4387
4406
  if (index < typeArgs.length && typeArgs[index].typeList) {
4388
4407
  addError(localize_1.Localizer.Diagnostic.typeArgListNotAllowed(), typeArgs[index].node);
4389
4408
  }
4390
- const typeArgType = index < typeArgs.length
4391
- ? (0, typeUtils_1.convertToInstance)(typeArgs[index].type)
4392
- : (_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
+ }
4393
4419
  (0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, param, typeArgType, diag, typeVarContext, 128 /* RetainLiteralsForTypeVar */);
4394
4420
  }
4395
4421
  });
@@ -4400,8 +4426,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4400
4426
  (_b = baseType.typeAliasInfo.typeParameters) === null || _b === void 0 ? void 0 : _b.forEach((typeParam) => {
4401
4427
  let typeVarType;
4402
4428
  if ((0, types_1.isParamSpec)(typeParam)) {
4403
- const paramSpecValue = typeVarContext.getParamSpec(typeParam);
4404
- 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();
4405
4431
  }
4406
4432
  else {
4407
4433
  typeVarType = typeVarContext.getTypeVarType(typeParam);
@@ -4425,7 +4451,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4425
4451
  let isIncomplete = baseTypeResult.isIncomplete;
4426
4452
  const type = mapSubtypesExpandTypeVars(baseTypeResult.type,
4427
4453
  /* conditionFilter */ undefined, (concreteSubtype, unexpandedSubtype) => {
4428
- var _a;
4454
+ var _a, _b;
4429
4455
  if ((0, types_1.isAnyOrUnknown)(concreteSubtype)) {
4430
4456
  return concreteSubtype;
4431
4457
  }
@@ -4492,7 +4518,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4492
4518
  const isClassVarAnnotation = (0, types_1.isInstantiableClass)(concreteSubtype) && types_1.ClassType.isBuiltIn(concreteSubtype, 'ClassVar');
4493
4519
  let typeArgs = getTypeArgs(node, flags, isAnnotatedClass, hasCustomClassGetItem || !isGenericClass, isFinalAnnotation, isClassVarAnnotation);
4494
4520
  if (!isAnnotatedClass) {
4495
- 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);
4496
4522
  }
4497
4523
  // If this is a custom __class_getitem__, there's no need to specialize the class.
4498
4524
  // Just return it as is.
@@ -4950,6 +4976,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4950
4976
  }
4951
4977
  const entryTypeResults = node.expressions.map((expr, index) => getTypeOfExpression(expr,
4952
4978
  /* flags */ undefined, index < expectedTypes.length ? expectedTypes[index] : undefined));
4979
+ const isIncomplete = entryTypeResults.some((result) => result.isIncomplete);
4953
4980
  const type = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, buildTupleTypesList(entryTypeResults),
4954
4981
  /* isTypeArgumentExplicit */ true));
4955
4982
  // Copy any expected type diag addenda for precision error reporting.
@@ -4962,7 +4989,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4962
4989
  }
4963
4990
  });
4964
4991
  }
4965
- return { type, expectedTypeDiagAddendum };
4992
+ return { type, expectedTypeDiagAddendum, isIncomplete };
4966
4993
  }
4967
4994
  function getTypeOfTupleInferred(node) {
4968
4995
  const entryTypeResults = node.expressions.map((expr) => getTypeOfExpression(expr));
@@ -5949,7 +5976,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5949
5976
  unsolvedTypeVarsAreUnknown = false;
5950
5977
  }
5951
5978
  }
5952
- const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, unsolvedTypeVarsAreUnknown);
5979
+ const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, {
5980
+ unknownIfNotFound: unsolvedTypeVarsAreUnknown,
5981
+ });
5953
5982
  return types_1.ClassType.cloneAsInstance(specializedType);
5954
5983
  }
5955
5984
  // Similar to applyExpectedTypeForConstructor, this function handles the
@@ -7334,15 +7363,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7334
7363
  // the call below to adjustCallableReturnType will "detach" these
7335
7364
  // TypeVars from the scope of this function and "attach" them to
7336
7365
  // the scope of the callable.
7337
- let unknownIfUnsolved = !(0, types_1.isFunction)(returnType);
7366
+ let unknownIfNotFound = !(0, types_1.isFunction)(returnType);
7338
7367
  // We'll also leave TypeVars unsolved if the call is a recursive
7339
7368
  // call to a generic function.
7340
7369
  const typeVarScopes = getTypeVarScopesForNode(errorNode);
7341
7370
  if (typeVarScopes.some((typeVarScope) => typeVarContext.hasSolveForScope(typeVarScope))) {
7342
- unknownIfUnsolved = false;
7371
+ unknownIfNotFound = false;
7343
7372
  }
7344
- let specializedReturnType = (0, typeUtils_1.addConditionToType)((0, typeUtils_1.applySolvedTypeVars)(returnType, typeVarContext, unknownIfUnsolved,
7345
- /* useNarrowBoundOnly */ false, eliminateUnsolvedInUnions), typeCondition);
7373
+ let specializedReturnType = (0, typeUtils_1.addConditionToType)((0, typeUtils_1.applySolvedTypeVars)(returnType, typeVarContext, {
7374
+ unknownIfNotFound,
7375
+ eliminateUnsolvedInUnions,
7376
+ }), typeCondition);
7346
7377
  // If the final return type is an unpacked tuple, turn it into a normal (unpacked) tuple.
7347
7378
  if ((0, types_1.isUnpackedClass)(specializedReturnType)) {
7348
7379
  specializedReturnType = types_1.ClassType.cloneForUnpacked(specializedReturnType, /* isUnpackedTuple */ false);
@@ -7409,16 +7440,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7409
7440
  // signature bound to the specified ParamSpec. Return value indicates success.
7410
7441
  function validateFunctionArgumentsForParamSpec(errorNode, argList, paramSpec, destTypeVarContext, conditionFilter) {
7411
7442
  var _a;
7412
- const paramSpecValue = destTypeVarContext.getParamSpec(paramSpec);
7413
- const srcTypeVarContext = new typeVarContext_1.TypeVarContext(paramSpecValue === null || paramSpecValue === void 0 ? void 0 : paramSpecValue.typeVarScopeId);
7414
- if (!paramSpecValue) {
7443
+ const paramSpecType = destTypeVarContext.getParamSpecType(paramSpec);
7444
+ if (!paramSpecType) {
7415
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);
7416
7446
  return false;
7417
7447
  }
7448
+ const srcTypeVarContext = new typeVarContext_1.TypeVarContext(paramSpecType.details.typeVarScopeId);
7418
7449
  let reportedArgError = false;
7419
7450
  // Build a map of all named parameters.
7420
7451
  const paramMap = new Map();
7421
- const paramSpecParams = paramSpecValue.parameters;
7452
+ const paramSpecParams = paramSpecType.details.parameters;
7422
7453
  paramSpecParams.forEach((param) => {
7423
7454
  if (param.name) {
7424
7455
  paramMap.set(param.name, param);
@@ -7499,7 +7530,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7499
7530
  const paramInfo = paramMap.get(name);
7500
7531
  return paramInfo.category === 0 /* Simple */ && !paramInfo.hasDefault;
7501
7532
  });
7502
- if (unassignedParams.length > 0 && !paramSpecValue.paramSpec) {
7533
+ if (unassignedParams.length > 0 && !paramSpecType.details.paramSpec) {
7503
7534
  const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
7504
7535
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
7505
7536
  ? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
@@ -7531,8 +7562,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7531
7562
  functionType !== undefined &&
7532
7563
  argParam.paramType.scopeId === functionType.details.typeVarScopeId
7533
7564
  ? undefined
7534
- : (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext,
7535
- /* unknownIfNotFound */ false, useNarrowBoundOnly);
7565
+ : (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext, { useNarrowBoundOnly });
7536
7566
  // If the expected type is unknown, don't use an expected type. Instead,
7537
7567
  // use default rules for evaluating the expression type.
7538
7568
  if (expectedType && (0, types_1.isUnknown)(expectedType)) {
@@ -7851,8 +7881,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7851
7881
  // or constraint.
7852
7882
  if (typeVar.details.defaultType && defaultValueNode) {
7853
7883
  const typeVarContext = new typeVarContext_1.TypeVarContext(types_1.WildcardTypeVarScopeId);
7854
- const concreteDefaultType = (0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext,
7855
- /* unknownIfNotFound */ true);
7884
+ const concreteDefaultType = makeTopLevelTypeVarsConcrete((0, typeUtils_1.applySolvedTypeVars)(typeVar.details.defaultType, typeVarContext, {
7885
+ unknownIfNotFound: true,
7886
+ }));
7856
7887
  if (typeVar.details.boundType) {
7857
7888
  if (!assignType(typeVar.details.boundType, concreteDefaultType)) {
7858
7889
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarDefaultBoundMismatch(), defaultValueNode);
@@ -8011,62 +8042,67 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8011
8042
  // in the Python specification: The static type checker will treat
8012
8043
  // the new type as if it were a subclass of the original type.
8013
8044
  function createNewType(errorNode, argList) {
8045
+ var _a;
8014
8046
  const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
8015
- let className = '_';
8016
- if (argList.length >= 1) {
8017
- const nameArg = argList[0];
8018
- if (nameArg.argumentCategory === 0 /* Simple */) {
8019
- if (nameArg.valueExpression && nameArg.valueExpression.nodeType === 48 /* StringList */) {
8020
- className = nameArg.valueExpression.strings.map((s) => s.value).join('');
8021
- }
8022
- }
8023
- }
8024
- if (argList.length >= 2) {
8025
- const baseClass = getTypeOfArgumentExpectingType(argList[1]).type;
8026
- if ((0, types_1.isInstantiableClass)(baseClass)) {
8027
- if (types_1.ClassType.isProtocolClass(baseClass)) {
8028
- addError(localize_1.Localizer.Diagnostic.newTypeProtocolClass(), argList[1].node || errorNode);
8029
- }
8030
- else if (baseClass.literalValue !== undefined) {
8031
- addError(localize_1.Localizer.Diagnostic.newTypeLiteral(), argList[1].node || errorNode);
8032
- }
8033
- const classFlags = baseClass.details.flags & ~(1 /* BuiltInClass */ | 2 /* SpecialBuiltIn */);
8034
- const classType = types_1.ClassType.createInstantiable(className, ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className), fileInfo.moduleName, fileInfo.filePath, classFlags, ParseTreeUtils.getTypeSourceId(errorNode),
8035
- /* declaredMetaclass */ undefined, baseClass.details.effectiveMetaclass);
8036
- classType.details.baseClasses.push(baseClass);
8037
- (0, typeUtils_1.computeMroLinearization)(classType);
8038
- // Synthesize an __init__ method that accepts only the specified type.
8039
- const initType = types_1.FunctionType.createSynthesizedInstance('__init__');
8040
- types_1.FunctionType.addParameter(initType, {
8041
- category: 0 /* Simple */,
8042
- name: 'self',
8043
- type: types_1.ClassType.cloneAsInstance(classType),
8044
- hasDeclaredType: true,
8045
- });
8046
- types_1.FunctionType.addParameter(initType, {
8047
- category: 0 /* Simple */,
8048
- name: '_x',
8049
- type: types_1.ClassType.cloneAsInstance(baseClass),
8050
- hasDeclaredType: true,
8051
- });
8052
- initType.details.declaredReturnType = types_1.NoneType.createInstance();
8053
- classType.details.fields.set('__init__', symbol_1.Symbol.createWithType(4 /* ClassMember */, initType));
8054
- // Synthesize a trivial __new__ method.
8055
- const newType = types_1.FunctionType.createSynthesizedInstance('__new__', 1 /* ConstructorMethod */);
8056
- types_1.FunctionType.addParameter(newType, {
8057
- category: 0 /* Simple */,
8058
- name: 'cls',
8059
- type: classType,
8060
- hasDeclaredType: true,
8061
- });
8062
- types_1.FunctionType.addDefaultParameters(newType);
8063
- newType.details.declaredReturnType = types_1.ClassType.cloneAsInstance(classType);
8064
- classType.details.fields.set('__new__', symbol_1.Symbol.createWithType(4 /* ClassMember */, newType));
8065
- return classType;
8066
- }
8067
- else if (!(0, types_1.isAnyOrUnknown)(baseClass)) {
8068
- addError(localize_1.Localizer.Diagnostic.newTypeNotAClass(), argList[1].node || errorNode);
8069
- }
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);
8070
8106
  }
8071
8107
  return undefined;
8072
8108
  }
@@ -10371,7 +10407,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10371
10407
  }
10372
10408
  return createSpecialType(classType, typeArgs, /* paramLimit */ undefined, /* allowParamSpec */ true);
10373
10409
  }
10374
- function transformTypeForTypeAlias(type, name, errorNode, typeParameters) {
10410
+ function transformTypeForTypeAlias(type, name, errorNode, typeParameters, typeParamNodes) {
10375
10411
  if (!types_1.TypeBase.isInstantiable(type)) {
10376
10412
  return type;
10377
10413
  }
@@ -10400,6 +10436,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10400
10436
  }
10401
10437
  return (0, typeUtils_1.convertToInstance)(typeVar);
10402
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
+ });
10403
10448
  // Verify that we have at most one variadic type variable.
10404
10449
  const variadics = typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
10405
10450
  if (variadics.length > 1) {
@@ -10741,6 +10786,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10741
10786
  // path does not handle traditional type aliases, which are treated as
10742
10787
  // variables since they use normal variable assignment syntax.
10743
10788
  function getTypeOfTypeAlias(node) {
10789
+ var _a;
10744
10790
  const cachedType = readTypeCache(node.name, 0 /* None */);
10745
10791
  if (cachedType) {
10746
10792
  return cachedType;
@@ -10778,7 +10824,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10778
10824
  }
10779
10825
  // Clear the temporary type we wrote above.
10780
10826
  deleteTypeCacheEntry(node.name);
10781
- 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);
10782
10828
  if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
10783
10829
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
10784
10830
  name: node.name.value,
@@ -11096,6 +11142,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11096
11142
  names: variadics.map((v) => `"${v.details.name}"`).join(', '),
11097
11143
  }), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
11098
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
+ });
11099
11155
  if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
11100
11156
  addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
11101
11157
  }
@@ -11284,6 +11340,34 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11284
11340
  }
11285
11341
  return { classType, decoratedType };
11286
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
+ }
11287
11371
  function inferTypeParameterVarianceForClass(classType) {
11288
11372
  if (!classType.details.requiresVarianceInference) {
11289
11373
  return;
@@ -11590,6 +11674,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11590
11674
  });
11591
11675
  }
11592
11676
  function getTypeOfFunction(node) {
11677
+ var _a, _b;
11593
11678
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
11594
11679
  // Is this type already cached?
11595
11680
  const cachedFunctionType = readTypeCache(node.name, 0 /* None */);
@@ -11689,8 +11774,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11689
11774
  }), node.functionAnnotationComment);
11690
11775
  }
11691
11776
  }
11777
+ // If this function uses PEP 695 syntax for type parameters,
11778
+ // accumulate the list of type parameters upfront.
11779
+ const typeParametersSeen = [];
11692
11780
  if (node.typeParameters) {
11693
- evaluateTypeParameterList(node.typeParameters);
11781
+ functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters);
11782
+ }
11783
+ else {
11784
+ functionType.details.typeParameters = typeParametersSeen;
11694
11785
  }
11695
11786
  const markParamAccessed = (param) => {
11696
11787
  if (param.name) {
@@ -11838,6 +11929,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11838
11929
  isTypeInferred,
11839
11930
  };
11840
11931
  types_1.FunctionType.addParameter(functionType, functionParam);
11932
+ if (functionParam.hasDeclaredType) {
11933
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersSeen, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionParam.type));
11934
+ }
11841
11935
  if (param.name) {
11842
11936
  const variadicParamType = transformVariadicParamType(node, param.category, functionParam.type);
11843
11937
  paramTypes.push(variadicParamType);
@@ -11878,19 +11972,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11878
11972
  // If there was a defined return type, analyze that first so when we
11879
11973
  // walk the contents of the function, return statements can be
11880
11974
  // validated against this type.
11881
- 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) {
11882
11977
  // Temporarily set the return type to unknown in case of recursion.
11883
11978
  functionType.details.declaredReturnType = types_1.UnknownType.create();
11884
- const returnType = getTypeOfAnnotation(node.returnTypeAnnotation, {
11885
- associateTypeVarsWithScope: true,
11886
- disallowRecursiveTypeAlias: true,
11887
- });
11888
- functionType.details.declaredReturnType = returnType;
11889
- }
11890
- else if (node.functionAnnotationComment) {
11891
- // Temporarily set the return type to unknown in case of recursion.
11892
- functionType.details.declaredReturnType = types_1.UnknownType.create();
11893
- const returnType = getTypeOfAnnotation(node.functionAnnotationComment.returnTypeAnnotation, {
11979
+ const returnType = getTypeOfAnnotation(returnTypeAnnotationNode, {
11894
11980
  associateTypeVarsWithScope: true,
11895
11981
  disallowRecursiveTypeAlias: true,
11896
11982
  });
@@ -11911,6 +11997,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11911
11997
  }
11912
11998
  }
11913
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
+ }
11914
12004
  // If the return type is explicitly annotated as a generator, mark the
11915
12005
  // function as a generator even though it may not contain a "yield" statement.
11916
12006
  // This is important for generator functions declared in stub files, abstract
@@ -11926,6 +12016,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11926
12016
  functionType.details.flags |= 16 /* Generator */;
11927
12017
  }
11928
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
+ });
11929
12029
  // Clear the "partially evaluated" flag to indicate that the functionType
11930
12030
  // is fully evaluated.
11931
12031
  functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
@@ -11963,6 +12063,37 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11963
12063
  writeTypeCache(node, decoratedType, 0 /* None */, /* isIncomplete */ false);
11964
12064
  return { functionType, decoratedType };
11965
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
+ }
11966
12097
  function adjustParameterAnnotatedType(param, type) {
11967
12098
  var _a;
11968
12099
  // PEP 484 indicates that if a parameter has a default value of 'None'
@@ -13311,36 +13442,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13311
13442
  // within that tree. If the type cannot be determined (because it's part
13312
13443
  // of a cyclical dependency), the function returns undefined.
13313
13444
  function evaluateTypeForSubnode(subnode, callback) {
13314
- // If the type cache is already populated, don't bother
13315
- // doing additional work.
13316
- let subnodeType = readTypeCache(subnode, /* flags */ undefined);
13317
- if (subnodeType) {
13318
- 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 };
13319
13450
  }
13320
- const oldIncompleteCache = incompleteTypeCache;
13321
- try {
13322
- // If there isn't already an incompleteTypeCache allocated, allocate
13323
- // one now. We'll use this same cache for nested calls, but we'll
13324
- // abandon it once the last nested call completes.
13325
- if (!incompleteTypeCache) {
13326
- incompleteTypeCache = new Map();
13327
- }
13328
- callback();
13329
- subnodeType = readTypeCache(subnode, /* flags */ undefined);
13330
- if (subnodeType) {
13331
- return { type: subnodeType };
13332
- }
13333
- subnodeType = incompleteTypeCache.get(subnode.id);
13334
- if (subnodeType) {
13335
- return { type: subnodeType, isIncomplete: true };
13336
- }
13337
- incompleteTypeCache = oldIncompleteCache;
13338
- }
13339
- catch (e) {
13340
- // We don't use a finally clause here because the debugger doesn't
13341
- // handle it well when stepping through code.
13342
- incompleteTypeCache = oldIncompleteCache;
13343
- throw e;
13451
+ callback();
13452
+ cacheEntry = readTypeCacheEntry(subnode);
13453
+ if (cacheEntry) {
13454
+ return { type: cacheEntry.type, isIncomplete: cacheEntry.isIncomplete };
13344
13455
  }
13345
13456
  return undefined;
13346
13457
  }
@@ -13605,8 +13716,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13605
13716
  }
13606
13717
  }
13607
13718
  }
13719
+ const typeVarContext = new typeVarContext_1.TypeVarContext(classType.details.typeVarScopeId);
13608
13720
  fullTypeParams.forEach((typeParam, index) => {
13609
- var _a;
13610
13721
  if (typeArgs && index < typeArgs.length) {
13611
13722
  if (typeParam.details.isParamSpec) {
13612
13723
  const typeArg = typeArgs[index];
@@ -13616,6 +13727,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13616
13727
  types_1.FunctionType.addDefaultParameters(functionType);
13617
13728
  functionType.details.flags |= 32768 /* SkipArgsKwargsCompatibilityCheck */;
13618
13729
  typeArgTypes.push(functionType);
13730
+ typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(functionType));
13619
13731
  return;
13620
13732
  }
13621
13733
  if (typeArg.typeList) {
@@ -13629,6 +13741,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13629
13741
  });
13630
13742
  });
13631
13743
  typeArgTypes.push(functionType);
13744
+ typeVarContext.setTypeVarType(typeParam, (0, typeUtils_1.convertTypeToParamSpecValue)(functionType));
13632
13745
  return;
13633
13746
  }
13634
13747
  if ((0, types_1.isInstantiableClass)(typeArg.type) && types_1.ClassType.isBuiltIn(typeArg.type, 'Concatenate')) {
@@ -13655,10 +13768,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13655
13768
  return;
13656
13769
  }
13657
13770
  }
13658
- 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);
13659
13774
  return;
13660
13775
  }
13661
- 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
+ }
13662
13784
  });
13663
13785
  typeArgTypes = typeArgTypes.map((typeArgType, index) => {
13664
13786
  if (index < typeArgCount) {
@@ -14198,65 +14320,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14198
14320
  return undefined;
14199
14321
  }
14200
14322
  case 3 /* TypeParameter */: {
14201
- let typeVar = types_1.TypeVarType.createInstantiable(declaration.node.name.value);
14202
- if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
14203
- typeVar.details.isVariadic = true;
14204
- }
14205
- else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
14206
- typeVar.details.isParamSpec = true;
14207
- }
14208
- if (declaration.node.boundExpression) {
14209
- if (declaration.node.boundExpression.nodeType === 52 /* Tuple */) {
14210
- const constraints = declaration.node.boundExpression.expressions.map((constraint) => {
14211
- const constraintType = getTypeOfExpressionExpectingType(constraint).type;
14212
- if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
14213
- addError(localize_1.Localizer.Diagnostic.typeVarBoundGeneric(), constraint);
14214
- }
14215
- return (0, typeUtils_1.convertToInstance)(constraintType);
14216
- });
14217
- if (constraints.length < 2) {
14218
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(declaration.node.boundExpression).diagnosticRuleSet
14219
- .reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), declaration.node.boundExpression);
14220
- }
14221
- else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
14222
- typeVar.details.constraints = constraints;
14223
- }
14224
- }
14225
- else {
14226
- const boundType = getTypeOfExpressionExpectingType(declaration.node.boundExpression).type;
14227
- if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
14228
- addError(localize_1.Localizer.Diagnostic.typeVarConstraintGeneric(), declaration.node.boundExpression);
14229
- }
14230
- if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
14231
- typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
14232
- }
14233
- }
14234
- }
14235
- if (declaration.node.defaultExpression) {
14236
- // TODO - need to finish. For now, just evaluate the expression
14237
- // to generate any errors.
14238
- getTypeOfExpression(declaration.node.defaultExpression, 2097152 /* AllowUnpackedTupleOrTypeVarTuple */);
14239
- }
14240
- typeVar.details.isTypeParamSyntax = true;
14241
- // Associate the type variable with the owning scope.
14242
- const scopeNode = ParseTreeUtils.getTypeVarScopeNode(declaration.node);
14243
- if (scopeNode) {
14244
- let scopeType;
14245
- if (scopeNode.nodeType === 10 /* Class */) {
14246
- scopeType = 0 /* Class */;
14247
- // Set the variance to "auto" for class-scoped TypeVars.
14248
- typeVar.details.declaredVariance = 0 /* Auto */;
14249
- }
14250
- else if (scopeNode.nodeType === 28 /* Function */) {
14251
- scopeType = 1 /* Function */;
14252
- }
14253
- else {
14254
- (0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
14255
- scopeType = 2 /* TypeAlias */;
14256
- }
14257
- typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
14258
- }
14259
- return typeVar;
14323
+ return getTypeOfTypeParameter(declaration.node);
14260
14324
  }
14261
14325
  case 1 /* Variable */: {
14262
14326
  const typeAnnotationNode = declaration.typeAnnotationNode;
@@ -14301,6 +14365,99 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14301
14365
  }
14302
14366
  }
14303
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
+ }
14304
14461
  function getInferredTypeOfDeclaration(symbol, decl) {
14305
14462
  var _a, _b;
14306
14463
  const resolvedDecl = resolveAliasDeclaration(decl,
@@ -16436,9 +16593,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16436
16593
  let specializedDestType = destType;
16437
16594
  let reverseMatchingFailed = false;
16438
16595
  if ((flags & 2 /* ReverseTypeVarMatching */) === 0) {
16439
- specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext,
16440
- /* unknownIfNotFound */ undefined,
16441
- /* useNarrowBoundOnly */ true);
16596
+ specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext, { useNarrowBoundOnly: true });
16442
16597
  if ((0, typeUtils_1.requiresSpecialization)(specializedDestType)) {
16443
16598
  reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
16444
16599
  /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
@@ -16448,9 +16603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16448
16603
  }
16449
16604
  }
16450
16605
  else {
16451
- specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext,
16452
- /* unknownIfNotFound */ undefined,
16453
- /* useNarrowBoundOnly */ true);
16606
+ specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext, { useNarrowBoundOnly: true });
16454
16607
  if ((0, typeUtils_1.requiresSpecialization)(specializedSrcType)) {
16455
16608
  reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
16456
16609
  /* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
@@ -16475,8 +16628,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16475
16628
  if ((0, types_1.isTypeVar)(specializedSrcType) &&
16476
16629
  specializedSrcType.details.isSynthesizedSelf &&
16477
16630
  specializedSrcType.details.boundType) {
16478
- specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(specializedSrcType.details.boundType, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(specializedSrcType)),
16479
- /* unknownIfNotFound */ true);
16631
+ specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(specializedSrcType.details.boundType, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(specializedSrcType)), { unknownIfNotFound: true });
16480
16632
  }
16481
16633
  }
16482
16634
  if (!assignType(specializedSrcType, specializedDestType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), srcTypeVarContext, destTypeVarContext, flags, recursionCount)) {
@@ -17161,9 +17313,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17161
17313
  // Verify that the positional param count matches exactly or that the override
17162
17314
  // adds only params that preserve the original signature.
17163
17315
  let foundParamCountMismatch = false;
17164
- if (overrideParamDetails.positionParamCount < baseParamDetails.positionParamCount &&
17165
- overrideParamDetails.argsIndex === undefined) {
17166
- 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
+ }
17167
17333
  }
17168
17334
  else if (overrideParamDetails.positionParamCount > baseParamDetails.positionParamCount) {
17169
17335
  // Verify that all of the override parameters that extend the