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

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 (87) hide show
  1. package/dist/analyzer/aliasDeclarationUtils.js +23 -9
  2. package/dist/analyzer/aliasDeclarationUtils.js.map +1 -1
  3. package/dist/analyzer/analyzerFileInfo.d.ts +1 -0
  4. package/dist/analyzer/analyzerFileInfo.js.map +1 -1
  5. package/dist/analyzer/backgroundAnalysisProgram.d.ts +1 -0
  6. package/dist/analyzer/backgroundAnalysisProgram.js +3 -0
  7. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  8. package/dist/analyzer/binder.js +2 -2
  9. package/dist/analyzer/binder.js.map +1 -1
  10. package/dist/analyzer/checker.js +63 -38
  11. package/dist/analyzer/checker.js.map +1 -1
  12. package/dist/analyzer/constraintSolver.js +5 -0
  13. package/dist/analyzer/constraintSolver.js.map +1 -1
  14. package/dist/analyzer/declarationUtils.d.ts +2 -1
  15. package/dist/analyzer/declarationUtils.js +7 -4
  16. package/dist/analyzer/declarationUtils.js.map +1 -1
  17. package/dist/analyzer/importResolver.js +2 -2
  18. package/dist/analyzer/importResolver.js.map +1 -1
  19. package/dist/analyzer/program.d.ts +1 -0
  20. package/dist/analyzer/program.js +15 -3
  21. package/dist/analyzer/program.js.map +1 -1
  22. package/dist/analyzer/service.js +8 -4
  23. package/dist/analyzer/service.js.map +1 -1
  24. package/dist/analyzer/sourceFile.js +5 -2
  25. package/dist/analyzer/sourceFile.js.map +1 -1
  26. package/dist/analyzer/typeDocStringUtils.d.ts +2 -0
  27. package/dist/analyzer/typeDocStringUtils.js +14 -13
  28. package/dist/analyzer/typeDocStringUtils.js.map +1 -1
  29. package/dist/analyzer/typeEvaluator.d.ts +0 -1
  30. package/dist/analyzer/typeEvaluator.js +182 -46
  31. package/dist/analyzer/typeEvaluator.js.map +1 -1
  32. package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -0
  33. package/dist/analyzer/typeUtils.d.ts +1 -1
  34. package/dist/analyzer/typeUtils.js +2 -1
  35. package/dist/analyzer/typeUtils.js.map +1 -1
  36. package/dist/analyzer/types.d.ts +3 -1
  37. package/dist/analyzer/types.js +27 -4
  38. package/dist/analyzer/types.js.map +1 -1
  39. package/dist/backgroundAnalysisBase.d.ts +1 -1
  40. package/dist/common/commandLineOptions.d.ts +1 -1
  41. package/dist/common/commandLineOptions.js +0 -2
  42. package/dist/common/commandLineOptions.js.map +1 -1
  43. package/dist/common/configOptions.d.ts +1 -1
  44. package/dist/common/configOptions.js +4 -3
  45. package/dist/common/configOptions.js.map +1 -1
  46. package/dist/common/diagnosticRules.d.ts +1 -0
  47. package/dist/common/diagnosticRules.js +1 -0
  48. package/dist/common/diagnosticRules.js.map +1 -1
  49. package/dist/common/pathUtils.js +1 -1
  50. package/dist/common/pathUtils.js.map +1 -1
  51. package/dist/common/positionUtils.js +3 -9
  52. package/dist/common/positionUtils.js.map +1 -1
  53. package/dist/languageServerBase.js +2 -0
  54. package/dist/languageServerBase.js.map +1 -1
  55. package/dist/languageService/completionProvider.d.ts +1 -0
  56. package/dist/languageService/completionProvider.js +13 -1
  57. package/dist/languageService/completionProvider.js.map +1 -1
  58. package/dist/languageService/documentSymbolProvider.d.ts +1 -1
  59. package/dist/languageService/documentSymbolProvider.js +1 -1
  60. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  61. package/dist/languageService/hoverProvider.d.ts +1 -0
  62. package/dist/languageService/hoverProvider.js +19 -3
  63. package/dist/languageService/hoverProvider.js.map +1 -1
  64. package/dist/localization/localize.d.ts +10 -2
  65. package/dist/localization/localize.js +5 -2
  66. package/dist/localization/localize.js.map +1 -1
  67. package/dist/localization/package.nls.en-us.json +5 -2
  68. package/dist/pyright.js +55 -13
  69. package/dist/pyright.js.map +1 -1
  70. package/dist/tests/fourslash/hover.docFromSrc.fourslash.js +9 -7
  71. package/dist/tests/fourslash/hover.docFromSrc.fourslash.js.map +1 -1
  72. package/dist/tests/fourslash/hover.docFromSrc.pkg-vs-module2.fourslash.js +4 -1
  73. package/dist/tests/fourslash/hover.docFromSrc.pkg-vs-module2.fourslash.js.map +1 -1
  74. package/dist/tests/fourslash/hover.docFromSrc.relativeImport2.fourslash.js +2 -1
  75. package/dist/tests/fourslash/hover.docFromSrc.relativeImport2.fourslash.js.map +1 -1
  76. package/dist/tests/fourslash/hover.docFromSrc.relativeImport3.fourslash.js +8 -1
  77. package/dist/tests/fourslash/hover.docFromSrc.relativeImport3.fourslash.js.map +1 -1
  78. package/dist/tests/fourslash/shadowedImports.fourslash.js +12 -0
  79. package/dist/tests/fourslash/shadowedImports.fourslash.js.map +1 -1
  80. package/dist/tests/pathUtils.test.js +20 -5
  81. package/dist/tests/pathUtils.test.js.map +1 -1
  82. package/dist/tests/typeEvaluator3.test.js +28 -2
  83. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  84. package/dist/tests/typeEvaluator4.test.js +4 -0
  85. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  86. package/dist/tests/typeEvaluator5.test.js +1 -1
  87. package/package.json +2 -2
@@ -205,6 +205,12 @@ const maxOverloadUnionExpansionCount = 64;
205
205
  // Maximum number of recursive function return type inference attempts
206
206
  // that can be concurrently pending before we give up.
207
207
  const maxInferFunctionReturnRecursionCount = 12;
208
+ // Maximum recursion amount when comparing two recursive type aliases.
209
+ // Increasing this can greatly increase the time required to evaluate
210
+ // two recursive type aliases that have the same definition. Decreasing
211
+ // it can increase the chance of false negatives for such recursive
212
+ // type aliases.
213
+ const maxRecursiveTypeAliasRecursionCount = 10;
208
214
  // This switch enables a special debug mode that attempts to catch
209
215
  // bugs due to inconsistent evaluation flags used when reading types
210
216
  // from the type cache.
@@ -697,7 +703,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
697
703
  }
698
704
  }
699
705
  if (flags & 65536 /* DisallowRecursiveTypeAliasPlaceholder */) {
700
- if ((0, typeUtils_1.isTypeAliasPlaceholder)(typeResult.type)) {
706
+ if ((0, types_1.isTypeVar)(typeResult.type) && (0, typeUtils_1.isTypeAliasPlaceholder)(typeResult.type)) {
701
707
  typeResult.type.details.illegalRecursionDetected = true;
702
708
  }
703
709
  }
@@ -1980,6 +1986,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1980
1986
  if (diagLevel === 'none') {
1981
1987
  return undefined;
1982
1988
  }
1989
+ // Should we suppress this diagnostic because it's within an unannotated function?
1990
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
1991
+ if (!fileInfo.diagnosticRuleSet.analyzeUnannotatedFunctions) {
1992
+ const containingFunction = ParseTreeUtils.getEnclosingFunction(node);
1993
+ // Is the target node within the body of the function? If so, suppress the diagnostic.
1994
+ if (containingFunction &&
1995
+ ParseTreeUtils.isUnannotatedFunction(containingFunction) &&
1996
+ ParseTreeUtils.isNodeContainedWithin(node, containingFunction.suite)) {
1997
+ return undefined;
1998
+ }
1999
+ }
1983
2000
  const diagnostic = addDiagnosticWithSuppressionCheck(diagLevel, message, node, range);
1984
2001
  if (diagnostic) {
1985
2002
  diagnostic.setRule(rule);
@@ -2752,15 +2769,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2752
2769
  let type;
2753
2770
  let isIncomplete = false;
2754
2771
  const allowForwardReferences = (flags & 4 /* AllowForwardReferences */) !== 0 || fileInfo.isStubFile;
2755
- if (!evaluatorOptions.analyzeUnannotatedFunctions) {
2756
- const containingFunction = ParseTreeUtils.getEnclosingFunction(node);
2757
- if (containingFunction && ParseTreeUtils.isUnannotatedFunction(containingFunction)) {
2758
- return {
2759
- type: types_1.AnyType.create(),
2760
- isIncomplete: false,
2761
- };
2762
- }
2763
- }
2764
2772
  // Does this name refer to a PEP 695-style type parameter?
2765
2773
  const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
2766
2774
  if (typeParamSymbol) {
@@ -2789,6 +2797,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2789
2797
  useCodeFlowAnalysis = false;
2790
2798
  }
2791
2799
  symbol = symbolWithScope.symbol;
2800
+ setSymbolAccessed(fileInfo, symbol, node);
2801
+ // If we're not supposed to be analyzing this function, skip the remaining work
2802
+ // to determine the name's type. Simply evaluate its type as Any.
2803
+ if (!fileInfo.diagnosticRuleSet.analyzeUnannotatedFunctions) {
2804
+ const containingFunction = ParseTreeUtils.getEnclosingFunction(node);
2805
+ if (containingFunction && ParseTreeUtils.isUnannotatedFunction(containingFunction)) {
2806
+ return {
2807
+ type: types_1.AnyType.create(),
2808
+ isIncomplete: false,
2809
+ };
2810
+ }
2811
+ }
2792
2812
  // Get the effective type (either the declared type or the inferred type).
2793
2813
  // If we're using code flow analysis, pass the usage node so we consider
2794
2814
  // only the assignment nodes that are reachable from this usage.
@@ -2845,7 +2865,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2845
2865
  }
2846
2866
  // Detect, report, and fill in missing type arguments if appropriate.
2847
2867
  type = reportMissingTypeArguments(node, type, flags);
2848
- setSymbolAccessed(fileInfo, symbol, node);
2849
2868
  if ((flags & 1024 /* ExpectingTypeAnnotation */) !== 0) {
2850
2869
  // Verify that the name does not refer to a (non type alias) variable.
2851
2870
  if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
@@ -4402,7 +4421,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4402
4421
  if (typeAliasResult) {
4403
4422
  return typeAliasResult;
4404
4423
  }
4405
- if ((0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
4424
+ if ((0, types_1.isTypeVar)(baseTypeResult.type) && (0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
4406
4425
  const typeArgTypes = getTypeArgs(node, flags).map((t) => (0, typeUtils_1.convertToInstance)(t.type));
4407
4426
  const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
4408
4427
  return { type };
@@ -4499,14 +4518,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4499
4518
  }
4500
4519
  return typeResult.type;
4501
4520
  }
4502
- if ((0, types_1.isNever)(concreteSubtype)) {
4503
- return types_1.UnknownType.create();
4521
+ if ((0, types_1.isNever)(concreteSubtype) || (0, types_1.isUnbound)(concreteSubtype)) {
4522
+ return types_1.NeverType.createNever();
4504
4523
  }
4505
4524
  if ((0, types_1.isNoneInstance)(concreteSubtype) && !isIncomplete) {
4506
4525
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalSubscript, diagnosticRules_1.DiagnosticRule.reportOptionalSubscript, localize_1.Localizer.Diagnostic.noneNotSubscriptable(), node.baseExpression);
4507
4526
  return types_1.UnknownType.create();
4508
4527
  }
4509
- if (!(0, types_1.isUnbound)(concreteSubtype) && !isIncomplete) {
4528
+ if (!isIncomplete) {
4510
4529
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
4511
4530
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSubscriptable().format({ type: printType(concreteSubtype) }), node.baseExpression);
4512
4531
  }
@@ -5363,6 +5382,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5363
5382
  let matchedOverload;
5364
5383
  const argTypeOverride = expandedArgTypes[expandedTypesIndex];
5365
5384
  const hasArgTypeOverride = argTypeOverride.some((a) => a !== undefined);
5385
+ const possibleMatchResults = [];
5386
+ let isDefinitiveMatchFound = false;
5366
5387
  for (let overloadIndex = 0; overloadIndex < argParamMatches.length; overloadIndex++) {
5367
5388
  const overload = argParamMatches[overloadIndex].overload;
5368
5389
  let matchResults = argParamMatches[overloadIndex];
@@ -5402,10 +5423,44 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5402
5423
  matchResults,
5403
5424
  typeVarContext: effectiveTypeVarContext,
5404
5425
  });
5405
- returnTypes.push(callResult.returnType);
5406
- break;
5426
+ if (callResult.isArgumentAnyOrUnknown) {
5427
+ possibleMatchResults.push(callResult.returnType);
5428
+ }
5429
+ else {
5430
+ returnTypes.push(callResult.returnType);
5431
+ isDefinitiveMatchFound = true;
5432
+ break;
5433
+ }
5407
5434
  }
5408
5435
  }
5436
+ // If we didn't find a definitive match that doesn't depend on
5437
+ // an Any or Unknown argument, fall back on the possible match.
5438
+ // If there were multiple possible matches, evaluate the type as
5439
+ // Unknown, but include the "possible types" to allow for completion
5440
+ // suggestions.
5441
+ if (!isDefinitiveMatchFound) {
5442
+ // Eliminate any return types that are subsumed by other return types.
5443
+ let dedupedMatchResults = [];
5444
+ possibleMatchResults.forEach((subtype) => {
5445
+ let isSubtypeSubsumed = false;
5446
+ for (let dedupedIndex = 0; dedupedIndex < dedupedMatchResults.length; dedupedIndex++) {
5447
+ if (assignType(dedupedMatchResults[dedupedIndex], subtype)) {
5448
+ isSubtypeSubsumed = true;
5449
+ break;
5450
+ }
5451
+ else if (assignType(subtype, dedupedMatchResults[dedupedIndex])) {
5452
+ dedupedMatchResults[dedupedIndex] = types_1.NeverType.createNever();
5453
+ break;
5454
+ }
5455
+ }
5456
+ if (!isSubtypeSubsumed) {
5457
+ dedupedMatchResults.push(subtype);
5458
+ }
5459
+ });
5460
+ dedupedMatchResults = dedupedMatchResults.filter((t) => !(0, types_1.isNever)(t));
5461
+ const combinedTypes = (0, types_1.combineTypes)(dedupedMatchResults);
5462
+ returnTypes.push(dedupedMatchResults.length > 1 ? types_1.UnknownType.createPossibleType(combinedTypes) : combinedTypes);
5463
+ }
5409
5464
  if (!matchedOverload) {
5410
5465
  return { argumentErrors: true, isTypeIncomplete };
5411
5466
  }
@@ -5428,6 +5483,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5428
5483
  }
5429
5484
  return {
5430
5485
  argumentErrors: false,
5486
+ isArgumentAnyOrUnknown: finalCallResult.isArgumentAnyOrUnknown,
5431
5487
  returnType: (0, types_1.combineTypes)(returnTypes),
5432
5488
  isTypeIncomplete,
5433
5489
  specializedInitSelfType: finalCallResult.specializedInitSelfType,
@@ -5787,7 +5843,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5787
5843
  }
5788
5844
  });
5789
5845
  }
5790
- if (!validatedTypes && argList.length > 0) {
5846
+ if (!validatedTypes && argList.some((arg) => arg.argumentCategory === 0 /* Simple */)) {
5791
5847
  // Suppress this error if the class was instantiated from a custom
5792
5848
  // metaclass because it's likely that it's a false positive. Also
5793
5849
  // suppress the error if the class's metaclass has a __call__ method.
@@ -6974,9 +7030,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6974
7030
  ((0, types_1.isClassInstance)(argType) &&
6975
7031
  (0, typeUtils_1.isTupleClass)(argType) &&
6976
7032
  argType.tupleTypeArguments &&
6977
- argType.tupleTypeArguments.some((arg) => (0, types_1.isUnpackedVariadicTypeVar)(arg.type)));
7033
+ argType.tupleTypeArguments.length === 1 &&
7034
+ (0, types_1.isUnpackedVariadicTypeVar)(argType.tupleTypeArguments[0].type));
6978
7035
  if (containsVariadicTypeVar &&
6979
- argParam.argument.argumentCategory !== 1 /* UnpackedList */) {
7036
+ argParam.argument.argumentCategory !== 1 /* UnpackedList */ &&
7037
+ !argParam.mapsToVarArgList) {
6980
7038
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarTupleMustBeUnpacked(), (_a = argParam.argument.valueExpression) !== null && _a !== void 0 ? _a : errorNode);
6981
7039
  reportedArgError = true;
6982
7040
  }
@@ -7110,6 +7168,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7110
7168
  let isTypeIncomplete = matchResults.isTypeIncomplete;
7111
7169
  let argumentErrors = false;
7112
7170
  let specializedInitSelfType;
7171
+ let isArgumentAnyOrUnknown = false;
7113
7172
  const typeCondition = (0, typeUtils_1.getTypeCondition)(type);
7114
7173
  if (type.boundTypeVarScopeId) {
7115
7174
  // If the function was bound to a class or object and was a constructor, a
@@ -7213,6 +7272,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7213
7272
  if (argResult.condition) {
7214
7273
  condition = (_a = types_1.TypeCondition.combine(condition, argResult.condition)) !== null && _a !== void 0 ? _a : [];
7215
7274
  }
7275
+ if ((0, types_1.isAnyOrUnknown)(argResult.argType)) {
7276
+ isArgumentAnyOrUnknown = true;
7277
+ }
7216
7278
  if (type.details.paramSpec) {
7217
7279
  if (argParam.argument.argumentCategory === 1 /* UnpackedList */) {
7218
7280
  if ((0, types_1.isParamSpec)(argResult.argType) && argResult.argType.paramSpecAccess === 'args') {
@@ -7308,6 +7370,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7308
7370
  }
7309
7371
  return {
7310
7372
  argumentErrors,
7373
+ isArgumentAnyOrUnknown,
7311
7374
  returnType: specializedReturnType,
7312
7375
  isTypeIncomplete,
7313
7376
  activeParam: matchResults.activeParam,
@@ -8248,6 +8311,35 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8248
8311
  if ((0, types_1.isUnion)(newUnion)) {
8249
8312
  types_1.TypeBase.setSpecialForm(newUnion);
8250
8313
  }
8314
+ // Check for "stringified" forward reference type expressions. The "|" operator
8315
+ // doesn't support these except in certain circumstances. Notably, it can't be used
8316
+ // with other strings or with types that are not specialized using an index form.
8317
+ if (!fileInfo.isStubFile) {
8318
+ let stringNode;
8319
+ let otherNode;
8320
+ let otherType;
8321
+ if (leftExpression.nodeType === 48 /* StringList */) {
8322
+ stringNode = leftExpression;
8323
+ otherNode = rightExpression;
8324
+ otherType = rightType;
8325
+ }
8326
+ else if (rightExpression.nodeType === 48 /* StringList */) {
8327
+ stringNode = rightExpression;
8328
+ otherNode = leftExpression;
8329
+ otherType = leftType;
8330
+ }
8331
+ if (stringNode && otherNode && otherType) {
8332
+ let isAllowed = true;
8333
+ if ((0, types_1.isClass)(otherType)) {
8334
+ if (!otherType.isTypeArgumentExplicit || (0, types_1.isClassInstance)(otherType)) {
8335
+ isAllowed = false;
8336
+ }
8337
+ }
8338
+ if (!isAllowed) {
8339
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.unionForwardReferenceNotAllowed(), stringNode);
8340
+ }
8341
+ }
8342
+ }
8251
8343
  return { type: newUnion };
8252
8344
  }
8253
8345
  }
@@ -8743,13 +8835,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8743
8835
  let effectiveExpectedType = expectedType;
8744
8836
  if (expectedType && (0, types_1.isUnion)(expectedType)) {
8745
8837
  let matchingSubtype;
8838
+ let matchingSubtypeResult;
8746
8839
  (0, typeUtils_1.doForEachSubtype)(expectedType, (subtype) => {
8747
- if (!matchingSubtype) {
8748
- const subtypeResult = useSpeculativeMode(node, () => {
8749
- return getTypeOfDictionaryExpected(node, subtype);
8750
- });
8751
- if (subtypeResult && assignType(subtype, subtypeResult.type)) {
8840
+ // Use shortcut if we've already found a match.
8841
+ if (matchingSubtypeResult && !matchingSubtypeResult.typeErrors) {
8842
+ return;
8843
+ }
8844
+ const subtypeResult = useSpeculativeMode(node, () => {
8845
+ return getTypeOfDictionaryExpected(node, subtype);
8846
+ });
8847
+ if (subtypeResult && assignType(subtype, subtypeResult.type)) {
8848
+ // If this is the first result we're seeing or it's the first result
8849
+ // without errors, select it as the match.
8850
+ if (!matchingSubtypeResult || (matchingSubtypeResult.typeErrors && !subtypeResult.typeErrors)) {
8752
8851
  matchingSubtype = subtype;
8852
+ matchingSubtypeResult = subtypeResult;
8753
8853
  }
8754
8854
  }
8755
8855
  });
@@ -9011,13 +9111,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9011
9111
  let effectiveExpectedType = expectedType;
9012
9112
  if (expectedType && (0, types_1.isUnion)(expectedType)) {
9013
9113
  let matchingSubtype;
9114
+ let matchingSubtypeResult;
9014
9115
  (0, typeUtils_1.doForEachSubtype)(expectedType, (subtype) => {
9015
- if (!matchingSubtype) {
9016
- const subtypeResult = useSpeculativeMode(node, () => {
9017
- return getTypeOfListOrSetExpected(node, subtype);
9018
- });
9019
- if (subtypeResult && assignType(subtype, subtypeResult.type)) {
9116
+ // Use shortcut if we've already found a match.
9117
+ if (matchingSubtypeResult && !matchingSubtypeResult.typeErrors) {
9118
+ return;
9119
+ }
9120
+ const subtypeResult = useSpeculativeMode(node, () => {
9121
+ return getTypeOfListOrSetExpected(node, subtype);
9122
+ });
9123
+ if (subtypeResult && assignType(subtype, subtypeResult.type)) {
9124
+ // If this is the first result we're seeing or it's the first result
9125
+ // without errors, select it as the match.
9126
+ if (!matchingSubtypeResult || (matchingSubtypeResult.typeErrors && !subtypeResult.typeErrors)) {
9020
9127
  matchingSubtype = subtype;
9128
+ matchingSubtypeResult = subtypeResult;
9021
9129
  }
9022
9130
  }
9023
9131
  });
@@ -10502,6 +10610,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10502
10610
  let isSpeculativeTypeAlias = false;
10503
10611
  if (isDeclaredTypeAlias(node.leftExpression)) {
10504
10612
  typeAliasNameNode = node.leftExpression.valueExpression;
10613
+ if (!(0, declarationUtils_1.isLegalTypeAliasExpressionForm)(node.rightExpression)) {
10614
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIllegalExpressionForm(), node.rightExpression);
10615
+ }
10505
10616
  }
10506
10617
  else if (node.leftExpression.nodeType === 38 /* Name */) {
10507
10618
  const symbolWithScope = lookUpSymbolRecursive(node.leftExpression, node.leftExpression.value,
@@ -10660,6 +10771,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10660
10771
  typeParameters = evaluateTypeParameterList(node.typeParameters);
10661
10772
  typeAliasTypeVar.details.recursiveTypeParameters = typeParameters;
10662
10773
  }
10774
+ if (!(0, declarationUtils_1.isLegalTypeAliasExpressionForm)(node.expression)) {
10775
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIllegalExpressionForm(), node.expression);
10776
+ }
10663
10777
  const aliasTypeResult = getTypeOfExpressionExpectingType(node.expression);
10664
10778
  let isIncomplete = false;
10665
10779
  let aliasType = aliasTypeResult.type;
@@ -14716,6 +14830,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14716
14830
  var _a;
14717
14831
  let returnType;
14718
14832
  let isIncomplete = false;
14833
+ let analyzeUnannotatedFunctions = true;
14719
14834
  // Don't attempt to infer the return type for a stub file.
14720
14835
  if (types_1.FunctionType.isStubDefinition(type)) {
14721
14836
  return types_1.UnknownType.create();
@@ -14733,8 +14848,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14733
14848
  }
14734
14849
  else if (type.details.declaration) {
14735
14850
  const functionNode = type.details.declaration.node;
14851
+ analyzeUnannotatedFunctions =
14852
+ AnalyzerNodeInfo.getFileInfo(functionNode).diagnosticRuleSet.analyzeUnannotatedFunctions;
14736
14853
  // Skip return type inference if we are in "skip unannotated function" mode.
14737
- if (evaluatorOptions.analyzeUnannotatedFunctions && !checkCodeFlowTooComplex(functionNode.suite)) {
14854
+ if (analyzeUnannotatedFunctions && !checkCodeFlowTooComplex(functionNode.suite)) {
14738
14855
  const codeFlowComplexity = AnalyzerNodeInfo.getCodeFlowComplexity(functionNode);
14739
14856
  // For very complex functions that have no annotated parameter types,
14740
14857
  // don't attempt to infer the return type because it can be extremely
@@ -14771,7 +14888,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14771
14888
  // params, try to analyze the function with the provided argument types and
14772
14889
  // attempt to do a better job at inference.
14773
14890
  if (!isIncomplete &&
14774
- evaluatorOptions.analyzeUnannotatedFunctions &&
14891
+ analyzeUnannotatedFunctions &&
14775
14892
  (0, typeUtils_1.isPartlyUnknown)(returnType) &&
14776
14893
  types_1.FunctionType.hasUnannotatedParams(type) &&
14777
14894
  !types_1.FunctionType.isStubDefinition(type) &&
@@ -15405,8 +15522,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15405
15522
  }
15406
15523
  }
15407
15524
  // Transform recursive type aliases if necessary.
15408
- destType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(destType);
15409
- srcType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(srcType);
15525
+ const transformedDestType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(destType);
15526
+ 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)) {
15534
+ // Use a smaller recursive limit in this case to prevent runaway recursion.
15535
+ if (recursionCount > maxRecursiveTypeAliasRecursionCount) {
15536
+ return true;
15537
+ }
15538
+ }
15539
+ destType = transformedDestType;
15540
+ srcType = transformedSrcType;
15410
15541
  // If the source or dest is unbound, allow the assignment. The
15411
15542
  // error will be reported elsewhere.
15412
15543
  if ((0, types_1.isUnbound)(destType) || (0, types_1.isUnbound)(srcType)) {
@@ -15628,19 +15759,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15628
15759
  }
15629
15760
  instantiableType = (0, typeUtils_1.convertToInstantiable)(typeTypeArg);
15630
15761
  }
15631
- else {
15762
+ else if (types_1.TypeBase.isInstantiable(destType)) {
15632
15763
  typeTypeArg = objectType !== null && objectType !== void 0 ? objectType : types_1.AnyType.create();
15633
15764
  instantiableType = expandedSrcType;
15634
15765
  }
15635
- if ((0, types_1.isClassInstance)(typeTypeArg) || (0, types_1.isTypeVar)(typeTypeArg)) {
15636
- if (assignType(destType, instantiableType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
15637
- return true;
15766
+ if (instantiableType && typeTypeArg) {
15767
+ if ((0, types_1.isClassInstance)(typeTypeArg) || (0, types_1.isTypeVar)(typeTypeArg)) {
15768
+ if (assignType(destType, instantiableType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
15769
+ return true;
15770
+ }
15771
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
15772
+ sourceType: printType(srcType),
15773
+ destType: printType(destType),
15774
+ }));
15775
+ return false;
15638
15776
  }
15639
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
15640
- sourceType: printType(srcType),
15641
- destType: printType(destType),
15642
- }));
15643
- return false;
15644
15777
  }
15645
15778
  }
15646
15779
  if ((0, types_1.isInstantiableClass)(destType)) {
@@ -16103,7 +16236,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16103
16236
  // in case the destType is a union with hundreds of literals.
16104
16237
  if ((0, types_1.isClassInstance)(srcType) &&
16105
16238
  (0, typeUtils_1.isLiteralType)(srcType) &&
16106
- types_1.UnionType.containsType(destType, srcType, recursionCount)) {
16239
+ types_1.UnionType.containsType(destType, srcType, /* exclusionSet */ undefined, recursionCount)) {
16107
16240
  return true;
16108
16241
  }
16109
16242
  (0, typeUtils_1.doForEachSubtype)(destType, (subtype) => {
@@ -17248,7 +17381,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17248
17381
  if ((0, types_1.isAnyOrUnknown)(srcType)) {
17249
17382
  return srcType;
17250
17383
  }
17251
- let effectiveSrcType = srcType;
17384
+ let effectiveSrcType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(srcType);
17252
17385
  if ((0, types_1.isTypeVar)(srcType)) {
17253
17386
  if ((0, types_1.isTypeSame)(srcType, destType)) {
17254
17387
  return srcType;
@@ -17262,7 +17395,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17262
17395
  return srcType;
17263
17396
  }
17264
17397
  // If there's a bound type, make sure the source is derived from it.
17265
- if (destType.details.boundType) {
17398
+ if (destType.details.boundType && !(0, typeUtils_1.isTypeAliasPlaceholder)(effectiveSrcType)) {
17266
17399
  if (!assignType(destType.details.boundType, effectiveSrcType, diag.createAddendum(),
17267
17400
  /* destTypeVarContext */ undefined,
17268
17401
  /* srcTypeVarContext */ undefined)) {
@@ -17303,6 +17436,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17303
17436
  if (constraints.length === 0) {
17304
17437
  return srcType;
17305
17438
  }
17439
+ if ((0, typeUtils_1.isTypeAliasPlaceholder)(srcType)) {
17440
+ return srcType;
17441
+ }
17306
17442
  if ((0, types_1.isTypeVar)(srcType) && srcType.details.constraints.length > 0) {
17307
17443
  // Make sure all the source constraint types map to constraint types in the dest.
17308
17444
  if (srcType.details.constraints.every((sourceConstraint) => {