@zzzen/pyright-internal 1.2.0-dev.20240728 → 1.2.0-dev.20240804

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 (89) hide show
  1. package/dist/analyzer/binder.js +7 -4
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.d.ts +2 -1
  4. package/dist/analyzer/checker.js +135 -83
  5. package/dist/analyzer/checker.js.map +1 -1
  6. package/dist/analyzer/codeFlowEngine.js +4 -4
  7. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  8. package/dist/analyzer/constraintSolution.d.ts +21 -0
  9. package/dist/analyzer/constraintSolution.js +71 -0
  10. package/dist/analyzer/constraintSolution.js.map +1 -0
  11. package/dist/analyzer/constraintSolver.d.ts +9 -5
  12. package/dist/analyzer/constraintSolver.js +420 -322
  13. package/dist/analyzer/constraintSolver.js.map +1 -1
  14. package/dist/analyzer/constraintTracker.d.ts +44 -0
  15. package/dist/analyzer/constraintTracker.js +230 -0
  16. package/dist/analyzer/constraintTracker.js.map +1 -0
  17. package/dist/analyzer/constructorTransform.js +15 -15
  18. package/dist/analyzer/constructorTransform.js.map +1 -1
  19. package/dist/analyzer/constructors.d.ts +1 -1
  20. package/dist/analyzer/constructors.js +59 -38
  21. package/dist/analyzer/constructors.js.map +1 -1
  22. package/dist/analyzer/dataClasses.js +35 -32
  23. package/dist/analyzer/dataClasses.js.map +1 -1
  24. package/dist/analyzer/decorators.js +1 -1
  25. package/dist/analyzer/decorators.js.map +1 -1
  26. package/dist/analyzer/functionTransform.js +1 -1
  27. package/dist/analyzer/functionTransform.js.map +1 -1
  28. package/dist/analyzer/operations.d.ts +1 -2
  29. package/dist/analyzer/operations.js +95 -72
  30. package/dist/analyzer/operations.js.map +1 -1
  31. package/dist/analyzer/packageTypeVerifier.js +8 -4
  32. package/dist/analyzer/packageTypeVerifier.js.map +1 -1
  33. package/dist/analyzer/parameterUtils.d.ts +3 -3
  34. package/dist/analyzer/parameterUtils.js +19 -21
  35. package/dist/analyzer/parameterUtils.js.map +1 -1
  36. package/dist/analyzer/patternMatching.js +21 -19
  37. package/dist/analyzer/patternMatching.js.map +1 -1
  38. package/dist/analyzer/properties.d.ts +3 -2
  39. package/dist/analyzer/properties.js +11 -11
  40. package/dist/analyzer/properties.js.map +1 -1
  41. package/dist/analyzer/protocols.d.ts +3 -3
  42. package/dist/analyzer/protocols.js +50 -48
  43. package/dist/analyzer/protocols.js.map +1 -1
  44. package/dist/analyzer/tuples.d.ts +2 -2
  45. package/dist/analyzer/tuples.js +10 -9
  46. package/dist/analyzer/tuples.js.map +1 -1
  47. package/dist/analyzer/typeComplexity.js +12 -4
  48. package/dist/analyzer/typeComplexity.js.map +1 -1
  49. package/dist/analyzer/typeEvaluator.js +806 -778
  50. package/dist/analyzer/typeEvaluator.js.map +1 -1
  51. package/dist/analyzer/typeEvaluatorTypes.d.ts +28 -8
  52. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  53. package/dist/analyzer/typeGuards.js +46 -39
  54. package/dist/analyzer/typeGuards.js.map +1 -1
  55. package/dist/analyzer/typePrinter.js +17 -15
  56. package/dist/analyzer/typePrinter.js.map +1 -1
  57. package/dist/analyzer/typeUtils.d.ts +32 -30
  58. package/dist/analyzer/typeUtils.js +331 -563
  59. package/dist/analyzer/typeUtils.js.map +1 -1
  60. package/dist/analyzer/typeWalker.js +1 -1
  61. package/dist/analyzer/typeWalker.js.map +1 -1
  62. package/dist/analyzer/typedDicts.d.ts +2 -2
  63. package/dist/analyzer/typedDicts.js +25 -25
  64. package/dist/analyzer/typedDicts.js.map +1 -1
  65. package/dist/analyzer/types.d.ts +24 -21
  66. package/dist/analyzer/types.js +110 -113
  67. package/dist/analyzer/types.js.map +1 -1
  68. package/dist/languageServerBase.d.ts +2 -2
  69. package/dist/languageServerBase.js +5 -2
  70. package/dist/languageServerBase.js.map +1 -1
  71. package/dist/languageService/completionProvider.js +2 -2
  72. package/dist/languageService/completionProvider.js.map +1 -1
  73. package/dist/tests/checker.test.js +10 -2
  74. package/dist/tests/checker.test.js.map +1 -1
  75. package/dist/tests/typeEvaluator1.test.js +1 -1
  76. package/dist/tests/typeEvaluator2.test.js +12 -0
  77. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  78. package/dist/tests/typeEvaluator3.test.js +4 -0
  79. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  80. package/dist/tests/typeEvaluator4.test.js +1 -1
  81. package/dist/tests/typeEvaluator5.test.js +1 -1
  82. package/dist/tests/typeEvaluator7.test.js +4 -0
  83. package/dist/tests/typeEvaluator7.test.js.map +1 -1
  84. package/dist/tests/typeEvaluator8.test.js +4 -0
  85. package/dist/tests/typeEvaluator8.test.js.map +1 -1
  86. package/package.json +1 -1
  87. package/dist/analyzer/typeVarContext.d.ts +0 -48
  88. package/dist/analyzer/typeVarContext.js +0 -288
  89. package/dist/analyzer/typeVarContext.js.map +0 -1
@@ -10,140 +10,372 @@
10
10
  *
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.addConstraintsForExpectedType = exports.updateTypeVarType = exports.assignTypeToTypeVar = void 0;
13
+ exports.applyUnificationVars = exports.addConstraintsForExpectedType = exports.updateTypeVarType = exports.solveConstraintSet = exports.solveConstraints = exports.assignTypeVar = void 0;
14
14
  const diagnostic_1 = require("../common/diagnostic");
15
15
  const localize_1 = require("../localization/localize");
16
+ const constraintSolution_1 = require("./constraintSolution");
17
+ const constraintTracker_1 = require("./constraintTracker");
16
18
  const typeEvaluatorTypes_1 = require("./typeEvaluatorTypes");
17
19
  const types_1 = require("./types");
18
20
  const typeUtils_1 = require("./typeUtils");
19
- const typeVarContext_1 = require("./typeVarContext");
20
21
  // As we widen the lower bound of a type variable, we may end up with
21
22
  // many subtypes. For performance reasons, we need to cap this at some
22
23
  // point. This constant determines the cap.
23
24
  const maxSubtypeCountForTypeVarLowerBound = 64;
24
- // This debugging switch enables logging of the TypeVarContext before and
25
+ // This debugging switch enables logging of the constraints before and
25
26
  // after it is updated by the constraint solver.
26
- const logTypeVarContextUpdates = false;
27
+ const logConstraintsUpdates = false;
27
28
  // Assigns the source type to the dest type var in the type var context. If an existing
28
29
  // type is already associated with that type var name, it attempts to either widen or
29
30
  // narrow the type (depending on the value of the isContravariant parameter). The goal is
30
31
  // to produce the narrowest type that meets all of the requirements. If the type var context
31
32
  // has been "locked", it simply validates that the srcType is compatible (with no attempt
32
33
  // to widen or narrow).
33
- function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext, flags = 0 /* AssignTypeFlags.Default */, recursionCount = 0) {
34
- if (logTypeVarContextUpdates) {
34
+ function assignTypeVar(evaluator, destType, srcType, diag, constraints, flags = 0 /* AssignTypeFlags.Default */, recursionCount = 0) {
35
+ let isAssignable;
36
+ if (logConstraintsUpdates) {
35
37
  const indent = ' '.repeat(recursionCount * 2);
36
38
  console.log(`${indent}`);
37
- console.log(`${indent}assignTypeToTypeVar called with`);
39
+ console.log(`${indent}assignTypeVar called with`);
38
40
  console.log(`${indent}destType: ${evaluator.printType(destType)}`);
39
41
  console.log(`${indent}srcType: ${evaluator.printType(srcType)}`);
40
42
  console.log(`${indent}flags: ${flags}`);
41
- console.log(`${indent}scopes: ${(typeVarContext.getSolveForScopes() || []).join(', ')}`);
42
- logTypeVarContext(evaluator, typeVarContext, indent);
43
+ if (constraints) {
44
+ logConstraints(evaluator, constraints, indent);
45
+ }
43
46
  }
44
- let isTypeVarInScope = true;
45
- const isInvariant = (flags & 1 /* AssignTypeFlags.EnforceInvariance */) !== 0;
46
- const isContravariant = (flags & 2 /* AssignTypeFlags.ReverseTypeVarMatching */) !== 0 && !isInvariant;
47
47
  // If the TypeVar doesn't have a scope ID, then it's being used
48
48
  // outside of a valid TypeVar scope. This will be reported as a
49
49
  // separate error. Just ignore this case to avoid redundant errors.
50
50
  if (!destType.priv.scopeId) {
51
51
  return true;
52
52
  }
53
+ if (types_1.TypeVarType.isBound(destType) && !types_1.TypeVarType.isUnification(destType)) {
54
+ return assignBoundTypeVar(evaluator, destType, srcType, diag, flags);
55
+ }
53
56
  // Handle type[T] as a dest and a special form as a source.
54
57
  if (types_1.TypeBase.isInstantiable(destType) &&
55
58
  (0, types_1.isInstantiableClass)(srcType) &&
56
59
  evaluator.isSpecialFormClass(srcType, flags)) {
57
60
  return false;
58
61
  }
59
- // Verify that we are solving for the scope associated with this
60
- // type variable.
61
- if (!typeVarContext.hasSolveForScope(destType.priv.scopeId)) {
62
- // Handle Any as a source.
63
- if ((0, types_1.isAnyOrUnknown)(srcType) || ((0, types_1.isClass)(srcType) && types_1.ClassType.derivesFromAnyOrUnknown(srcType))) {
64
- return true;
65
- }
66
- // Handle a type[Any] as a source.
67
- if ((0, types_1.isClassInstance)(srcType) && types_1.ClassType.isBuiltIn(srcType, 'type')) {
68
- if (!srcType.priv.typeArgs ||
69
- srcType.priv.typeArgs.length < 1 ||
70
- (0, types_1.isAnyOrUnknown)(srcType.priv.typeArgs[0])) {
71
- if (types_1.TypeBase.isInstantiable(destType)) {
72
- return true;
73
- }
62
+ // An TypeVar can always be assigned to itself, but we won't record this in the constraints.
63
+ if ((0, types_1.isTypeSame)(destType, srcType)) {
64
+ return true;
65
+ }
66
+ if ((0, types_1.isParamSpec)(destType)) {
67
+ // Handle ParamSpecs specially.
68
+ isAssignable = assignParamSpec(evaluator, destType, srcType, diag, constraints, recursionCount);
69
+ }
70
+ else {
71
+ if ((0, types_1.isTypeVarTuple)(destType) && !destType.priv.isInUnion) {
72
+ const tupleClassType = evaluator.getTupleClassType();
73
+ if (!(0, types_1.isUnpacked)(srcType) && tupleClassType) {
74
+ // Package up the type into a tuple.
75
+ srcType = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, [{ type: srcType, isUnbounded: false }],
76
+ /* isTypeArgExplicit */ true,
77
+ /* isUnpackedTuple */ true));
74
78
  }
75
79
  }
76
- // Is this the equivalent of an "Unknown" for a ParamSpec?
77
- if ((0, types_1.isParamSpec)(destType) &&
78
- (0, types_1.isFunction)(srcType) &&
79
- types_1.FunctionType.isParamSpecValue(srcType) &&
80
- types_1.FunctionType.isGradualCallableForm(srcType)) {
81
- return true;
80
+ // If we're assigning an unpacked TypeVarTuple to a regular TypeVar,
81
+ // we need to treat it as a union of the unpacked TypeVarTuple.
82
+ if ((0, types_1.isTypeVarTuple)(srcType) &&
83
+ srcType.priv.isUnpacked &&
84
+ !srcType.priv.isInUnion &&
85
+ !(0, types_1.isTypeVarTuple)(destType)) {
86
+ srcType = types_1.TypeVarType.cloneForUnpacked(srcType, /* isInUnion */ true);
82
87
  }
83
- // Never or NoReturn is always assignable to all type variables unless
84
- // we're enforcing invariance.
85
- if ((0, types_1.isNever)(srcType) && !isInvariant) {
86
- return true;
88
+ // Handle the constrained case. This case needs to be handled specially
89
+ // because type narrowing isn't used in this case. For example, if the
90
+ // source type is "Literal[1]" and the constraint list includes the type
91
+ // "float", the resulting type is float.
92
+ if (types_1.TypeVarType.hasConstraints(destType)) {
93
+ isAssignable = assignConstrainedTypeVar(evaluator, destType, srcType, diag, constraints, flags, recursionCount);
87
94
  }
88
- // If we're in "ignore type var scope" mode, don't generate
89
- // an error in this path.
90
- if ((flags & 1024 /* AssignTypeFlags.IgnoreTypeVarScope */) !== 0) {
91
- return true;
95
+ else {
96
+ isAssignable = assignUnconstrainedTypeVar(evaluator, destType, srcType, diag, constraints, flags, recursionCount);
92
97
  }
93
- isTypeVarInScope = false;
94
- // Emit an error unless this is a synthesized type variable used
95
- // for pseudo-generic classes.
96
- if (!destType.shared.isSynthesized || destType.shared.isSynthesizedSelf) {
97
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(srcType, destType)));
98
- return false;
98
+ }
99
+ if (logConstraintsUpdates) {
100
+ const indent = ' '.repeat(recursionCount * 2);
101
+ console.log(`${indent}`);
102
+ if (constraints) {
103
+ logConstraints(evaluator, constraints, indent);
99
104
  }
100
105
  }
101
- // An in-scope placeholder TypeVar can always be assigned to itself,
102
- // but we won't record this in the typeVarContext.
103
- if ((0, types_1.isTypeSame)(destType, srcType) && destType.priv.isInScopePlaceholder) {
106
+ return isAssignable;
107
+ }
108
+ exports.assignTypeVar = assignTypeVar;
109
+ // Returns a solution for the type variables tracked by the constraint tracker.
110
+ function solveConstraints(evaluator, constraints, options) {
111
+ const solutionSets = [];
112
+ constraints.doForEachConstraintSet((constraintSet) => {
113
+ const solutionSet = solveConstraintSet(evaluator, constraintSet, options);
114
+ solutionSets.push(solutionSet);
115
+ });
116
+ return new constraintSolution_1.ConstraintSolution(solutionSets);
117
+ }
118
+ exports.solveConstraints = solveConstraints;
119
+ function solveConstraintSet(evaluator, constraintSet, options) {
120
+ const solutionSet = new constraintSolution_1.ConstraintSolutionSet(constraintSet.getScopeIds());
121
+ constraintSet.doForEachTypeVar((entry) => {
122
+ const value = getTypeVarType(evaluator, constraintSet, entry.typeVar, options === null || options === void 0 ? void 0 : options.useLowerBoundOnly);
123
+ if (value) {
124
+ solutionSet.setType(entry.typeVar, value);
125
+ }
126
+ });
127
+ return solutionSet;
128
+ }
129
+ exports.solveConstraintSet = solveConstraintSet;
130
+ // Updates the lower and upper bounds for a type variable. It also calculates the
131
+ // lowerBoundNoLiterals, which is a variant of the lower bound that has
132
+ // literals stripped. By default, the constraint solver always uses the "no literals"
133
+ // type in its solutions unless the version with literals is required to satisfy
134
+ // the upper bound.
135
+ function updateTypeVarType(evaluator, constraints, destType, lowerBound, upperBound, forceRetainLiterals = false) {
136
+ let lowerBoundNoLiterals;
137
+ if (lowerBound && !forceRetainLiterals) {
138
+ const strippedLiteral = (0, types_1.isTypeVarTuple)(destType)
139
+ ? stripLiteralValueForUnpackedTuple(evaluator, lowerBound)
140
+ : evaluator.stripLiteralValue(lowerBound);
141
+ // Strip the literals from the lower bound and see if it is still
142
+ // narrower than the upper bound.
143
+ if (strippedLiteral !== lowerBound) {
144
+ if (!upperBound || evaluator.assignType(upperBound, strippedLiteral)) {
145
+ lowerBoundNoLiterals = strippedLiteral;
146
+ }
147
+ }
148
+ }
149
+ constraints.setBounds(destType, lowerBound, lowerBoundNoLiterals, upperBound);
150
+ }
151
+ exports.updateTypeVarType = updateTypeVarType;
152
+ // In cases where the expected type is a specialized base class of the
153
+ // source type, we need to determine which type arguments in the derived
154
+ // class will make it compatible with the specialized base class. This method
155
+ // performs this reverse mapping of type arguments and populates the type var
156
+ // map for the target type. If the type is not assignable to the expected type,
157
+ // it returns false.
158
+ function addConstraintsForExpectedType(evaluator, type, expectedType, constraints, liveTypeVarScopes, usageOffset = undefined) {
159
+ if ((0, types_1.isAny)(expectedType)) {
160
+ type.shared.typeParams.forEach((typeParam) => {
161
+ updateTypeVarType(evaluator, constraints, typeParam, expectedType, expectedType);
162
+ });
104
163
  return true;
105
164
  }
106
- if ((flags & 8 /* AssignTypeFlags.SkipSolveTypeVars */) !== 0) {
107
- return evaluator.assignType(evaluator.makeTopLevelTypeVarsConcrete(destType), evaluator.makeTopLevelTypeVarsConcrete(srcType), diag,
108
- /* destTypeVarContext */ undefined,
109
- /* srcTypeVarContext */ undefined, flags, recursionCount);
165
+ if ((0, types_1.isTypeVar)(expectedType) && types_1.TypeVarType.isSelf(expectedType) && expectedType.shared.boundType) {
166
+ expectedType = expectedType.shared.boundType;
110
167
  }
111
- if ((0, types_1.isParamSpec)(destType)) {
112
- return assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContext, recursionCount);
168
+ if (!(0, types_1.isClass)(expectedType)) {
169
+ return false;
113
170
  }
114
- if ((0, types_1.isTypeVarTuple)(destType) && !destType.priv.isVariadicInUnion) {
115
- if (!(0, types_1.isUnpacked)(srcType)) {
116
- const tupleClassType = evaluator.getTupleClassType();
117
- if (tupleClassType && (0, types_1.isInstantiableClass)(tupleClassType)) {
118
- // Package up the type into a tuple.
119
- srcType = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, [{ type: srcType, isUnbounded: false }],
120
- /* isTypeArgExplicit */ true,
121
- /* isUnpackedTuple */ true));
171
+ // If the expected type is generic (but not specialized), we can't proceed.
172
+ const expectedTypeArgs = expectedType.priv.typeArgs;
173
+ if (!expectedTypeArgs) {
174
+ return evaluator.assignType(type, expectedType,
175
+ /* diag */ undefined, constraints,
176
+ /* srcConstraints */ undefined, 2048 /* AssignTypeFlags.PopulatingExpectedType */);
177
+ }
178
+ evaluator.inferVarianceForClass(type);
179
+ // If the expected type is the same as the target type (commonly the case),
180
+ // we can use a faster method.
181
+ if (types_1.ClassType.isSameGenericClass(expectedType, type)) {
182
+ const solution = (0, typeUtils_1.buildSolutionFromSpecializedClass)(expectedType);
183
+ const typeParams = types_1.ClassType.getTypeParams(expectedType);
184
+ typeParams.forEach((typeParam) => {
185
+ let typeArgValue = solution.getMainSolutionSet().getType(typeParam);
186
+ if (typeArgValue && liveTypeVarScopes) {
187
+ typeArgValue = (0, typeUtils_1.transformExpectedType)(typeArgValue, liveTypeVarScopes, usageOffset);
122
188
  }
123
- else {
124
- srcType = types_1.UnknownType.create();
189
+ if (typeArgValue) {
190
+ const variance = types_1.TypeVarType.getVariance(typeParam);
191
+ updateTypeVarType(evaluator, constraints, typeParam, variance === 3 /* Variance.Covariant */ ? undefined : typeArgValue, variance === 4 /* Variance.Contravariant */ ? undefined : typeArgValue);
192
+ }
193
+ });
194
+ return true;
195
+ }
196
+ // Create a generic version of the expected type.
197
+ const expectedTypeScopeId = (0, typeUtils_1.getTypeVarScopeId)(expectedType);
198
+ const synthExpectedTypeArgs = types_1.ClassType.getTypeParams(expectedType).map((typeParam, index) => {
199
+ const typeVar = types_1.TypeVarType.createInstance(`__dest${index}`, (0, types_1.isParamSpec)(typeParam) ? types_1.TypeVarKind.ParamSpec : types_1.TypeVarKind.TypeVar);
200
+ typeVar.shared.isSynthesized = true;
201
+ // Use invariance here so we set the lower and upper bound on the TypeVar.
202
+ typeVar.shared.declaredVariance = 2 /* Variance.Invariant */;
203
+ typeVar.priv.scopeId = expectedTypeScopeId;
204
+ return typeVar;
205
+ });
206
+ const genericExpectedType = types_1.ClassType.specialize(expectedType, synthExpectedTypeArgs);
207
+ // For each type param in the target type, create a placeholder type variable.
208
+ const typeArgs = types_1.ClassType.getTypeParams(type).map((typeParam, index) => {
209
+ const typeVar = types_1.TypeVarType.createInstance(`__source${index}`, (0, types_1.isParamSpec)(typeParam) ? types_1.TypeVarKind.ParamSpec : types_1.TypeVarKind.TypeVar);
210
+ typeVar.shared.isSynthesized = true;
211
+ typeVar.shared.synthesizedIndex = index;
212
+ typeVar.shared.isExemptFromBoundCheck = true;
213
+ return types_1.TypeVarType.cloneAsUnificationVar(typeVar);
214
+ });
215
+ const specializedType = types_1.ClassType.specialize(type, typeArgs);
216
+ const syntheticConstraints = new constraintTracker_1.ConstraintTracker();
217
+ if (evaluator.assignType(genericExpectedType, specializedType,
218
+ /* diag */ undefined, syntheticConstraints,
219
+ /* srcConstraints */ undefined, 2048 /* AssignTypeFlags.PopulatingExpectedType */)) {
220
+ let isResultValid = true;
221
+ synthExpectedTypeArgs.forEach((typeVar, index) => {
222
+ let synthTypeVar = getTypeVarType(evaluator, syntheticConstraints.getMainConstraintSet(), typeVar);
223
+ const otherSubtypes = [];
224
+ // If the resulting type is a union, try to find a matching type var and move
225
+ // the remaining subtypes to the "otherSubtypes" array.
226
+ if (synthTypeVar) {
227
+ if ((0, types_1.isParamSpec)(typeVar) && (0, types_1.isFunction)(synthTypeVar)) {
228
+ synthTypeVar = (0, typeUtils_1.simplifyFunctionToParamSpec)(synthTypeVar);
229
+ }
230
+ if ((0, types_1.isUnion)(synthTypeVar)) {
231
+ let foundSynthTypeVar;
232
+ (0, typeUtils_1.sortTypes)(synthTypeVar.priv.subtypes).forEach((subtype) => {
233
+ if ((0, types_1.isTypeVar)(subtype) &&
234
+ subtype.shared.isSynthesized &&
235
+ subtype.shared.synthesizedIndex !== undefined &&
236
+ !foundSynthTypeVar) {
237
+ foundSynthTypeVar = subtype;
238
+ }
239
+ else {
240
+ otherSubtypes.push(subtype);
241
+ }
242
+ });
243
+ if (foundSynthTypeVar) {
244
+ synthTypeVar = foundSynthTypeVar;
245
+ }
246
+ }
247
+ }
248
+ // Is this one of the synthesized type vars we allocated above? If so,
249
+ // the type arg that corresponds to this type var maps back to the target type.
250
+ if (synthTypeVar &&
251
+ (0, types_1.isTypeVar)(synthTypeVar) &&
252
+ synthTypeVar.shared.isSynthesized &&
253
+ synthTypeVar.shared.synthesizedIndex !== undefined) {
254
+ const targetTypeVar = types_1.ClassType.getTypeParams(specializedType)[synthTypeVar.shared.synthesizedIndex];
255
+ if (index < expectedTypeArgs.length) {
256
+ let typeArgValue = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expectedTypeArgs[index]);
257
+ if (otherSubtypes.length > 0) {
258
+ typeArgValue = (0, types_1.combineTypes)([typeArgValue, ...otherSubtypes]);
259
+ }
260
+ if (liveTypeVarScopes) {
261
+ typeArgValue = (0, typeUtils_1.transformExpectedType)(typeArgValue, liveTypeVarScopes, usageOffset);
262
+ }
263
+ if (typeArgValue) {
264
+ const variance = types_1.TypeVarType.getVariance(typeVar);
265
+ // If this type variable already has a type, don't overwrite it. This can
266
+ // happen if a single type variable in the derived class is used multiple times
267
+ // in the specialized base class type (e.g. Mapping[T, T]).
268
+ if (constraints.getMainConstraintSet().getTypeVar(targetTypeVar)) {
269
+ isResultValid = false;
270
+ typeArgValue = types_1.UnknownType.create();
271
+ }
272
+ updateTypeVarType(evaluator, constraints, targetTypeVar, variance === 3 /* Variance.Covariant */ ? undefined : typeArgValue, variance === 4 /* Variance.Contravariant */ ? undefined : typeArgValue);
273
+ }
274
+ else {
275
+ isResultValid = false;
276
+ }
277
+ }
278
+ }
279
+ });
280
+ return isResultValid;
281
+ }
282
+ return false;
283
+ }
284
+ exports.addConstraintsForExpectedType = addConstraintsForExpectedType;
285
+ // If the constraint tracker contains any type variables whose types depend on
286
+ // unification vars used for bidirectional type inference, replace those
287
+ // with the solved type associated with those unification vars.
288
+ function applyUnificationVars(evaluator, constraints) {
289
+ constraints.doForEachConstraintSet((constraintSet) => {
290
+ if (!constraintSet.hasUnificationVars()) {
291
+ return;
292
+ }
293
+ constraintSet.getTypeVars().forEach((entry) => {
294
+ if (!types_1.TypeVarType.isUnification(entry.typeVar)) {
295
+ const newLowerBound = entry.lowerBound
296
+ ? applyUnificationVarsToType(evaluator, entry.lowerBound, constraintSet)
297
+ : undefined;
298
+ const newLowerBoundNoLiterals = entry.lowerBoundNoLiterals
299
+ ? applyUnificationVarsToType(evaluator, entry.lowerBoundNoLiterals, constraintSet)
300
+ : undefined;
301
+ const newUpperBound = entry.upperBound
302
+ ? applyUnificationVarsToType(evaluator, entry.upperBound, constraintSet)
303
+ : undefined;
304
+ constraintSet.setBounds(entry.typeVar, newLowerBound, newLowerBoundNoLiterals, newUpperBound);
125
305
  }
306
+ });
307
+ });
308
+ }
309
+ exports.applyUnificationVars = applyUnificationVars;
310
+ function getTypeVarType(evaluator, constraintSet, typeVar, useLowerBoundOnly) {
311
+ var _a, _b;
312
+ const entry = constraintSet.getTypeVar(typeVar);
313
+ if (!entry) {
314
+ return undefined;
315
+ }
316
+ if ((0, types_1.isParamSpec)(typeVar)) {
317
+ if (!entry.lowerBound) {
318
+ return undefined;
126
319
  }
320
+ if ((0, types_1.isFunction)(entry.lowerBound)) {
321
+ return entry.lowerBound;
322
+ }
323
+ if ((0, types_1.isAnyOrUnknown)(entry.lowerBound)) {
324
+ return types_1.ParamSpecType.getUnknown();
325
+ }
326
+ }
327
+ if (useLowerBoundOnly) {
328
+ return entry.lowerBound;
329
+ }
330
+ // Prefer the lower bound with no literals. It will be undefined
331
+ // if the literal type couldn't be widened due to constraints imposed
332
+ // by the upper bound.
333
+ return (_b = (_a = entry.lowerBoundNoLiterals) !== null && _a !== void 0 ? _a : entry.lowerBound) !== null && _b !== void 0 ? _b : entry.upperBound;
334
+ }
335
+ // Handles an assignment to a TypeVar that is "bound" rather than "free".
336
+ // In general, such assignments are not allowed, but there are some special
337
+ // cases to be handled.
338
+ function assignBoundTypeVar(evaluator, destType, srcType, diag, flags) {
339
+ // Handle Any as a source.
340
+ if ((0, types_1.isAnyOrUnknown)(srcType) || ((0, types_1.isClass)(srcType) && types_1.ClassType.derivesFromAnyOrUnknown(srcType))) {
341
+ return true;
342
+ }
343
+ // Is this the equivalent of an "Unknown" for a ParamSpec?
344
+ if ((0, types_1.isParamSpec)(destType) &&
345
+ (0, types_1.isFunction)(srcType) &&
346
+ types_1.FunctionType.isParamSpecValue(srcType) &&
347
+ types_1.FunctionType.isGradualCallableForm(srcType)) {
348
+ return true;
127
349
  }
128
- // If we're assigning an unpacked TypeVarTuple to a regular TypeVar,
129
- // we need to treat it as a union of the unpacked TypeVarTuple.
130
- if ((0, types_1.isTypeVarTuple)(srcType) &&
131
- srcType.priv.isVariadicUnpacked &&
132
- !srcType.priv.isVariadicInUnion &&
133
- !(0, types_1.isTypeVarTuple)(destType)) {
134
- srcType = types_1.TypeVarType.cloneForUnpacked(srcType, /* isInUnion */ true);
350
+ // Never is always assignable in a covariant context.
351
+ const isCovariant = (flags & (1 /* AssignTypeFlags.EnforceInvariance */ | 2 /* AssignTypeFlags.ReverseTypeVarMatching */)) === 0;
352
+ if ((0, types_1.isNever)(srcType) && isCovariant) {
353
+ return true;
135
354
  }
136
- // Handle the constrained case. This case needs to be handled specially
137
- // because type narrowing isn't used in this case. For example, if the
138
- // source type is "Literal[1]" and the constraint list includes the type
139
- // "float", the resulting type is float.
140
- if (destType.shared.constraints.length > 0) {
141
- return assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, typeVarContext, flags, isTypeVarInScope, recursionCount);
355
+ // Handle a type[Any] as a source.
356
+ if ((0, types_1.isClassInstance)(srcType) && types_1.ClassType.isBuiltIn(srcType, 'type')) {
357
+ if (!srcType.priv.typeArgs || srcType.priv.typeArgs.length < 1 || (0, types_1.isAnyOrUnknown)(srcType.priv.typeArgs[0])) {
358
+ if (types_1.TypeBase.isInstantiable(destType)) {
359
+ return true;
360
+ }
361
+ }
142
362
  }
363
+ // Emit an error unless this is a synthesized type variable used
364
+ // for pseudo-generic classes.
365
+ if (!destType.shared.isSynthesized || types_1.TypeVarType.isSelf(destType)) {
366
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(srcType, destType)));
367
+ }
368
+ return false;
369
+ }
370
+ // Handles assignments to a TypeVarTuple or a TypeVar that does not have
371
+ // value constraints (but may have an upper bound).
372
+ function assignUnconstrainedTypeVar(evaluator, destType, srcType, diag, constraints, flags, recursionCount) {
373
+ const isInvariant = (flags & 1 /* AssignTypeFlags.EnforceInvariance */) !== 0;
374
+ const isContravariant = (flags & 2 /* AssignTypeFlags.ReverseTypeVarMatching */) !== 0 && !isInvariant;
143
375
  // Handle the unconstrained (but possibly bound) case.
144
- const curEntry = typeVarContext.getMainSolutionSet().getTypeVar(destType);
376
+ const curEntry = constraints === null || constraints === void 0 ? void 0 : constraints.getMainConstraintSet().getTypeVar(destType);
145
377
  let curUpperBound = curEntry === null || curEntry === void 0 ? void 0 : curEntry.upperBound;
146
- if (!curUpperBound && !destType.shared.isSynthesizedSelf) {
378
+ if (!curUpperBound && !types_1.TypeVarType.isSelf(destType)) {
147
379
  curUpperBound = destType.shared.boundType;
148
380
  }
149
381
  let curLowerBound = curEntry === null || curEntry === void 0 ? void 0 : curEntry.lowerBound;
@@ -207,14 +439,14 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
207
439
  }
208
440
  else if (!(0, types_1.isTypeSame)(curUpperBound, adjSrcType, {}, recursionCount)) {
209
441
  if (evaluator.assignType(curUpperBound, evaluator.makeTopLevelTypeVarsConcrete(adjSrcType), diagAddendum,
210
- /* destTypeVarContext */ undefined,
211
- /* srcTypeVarContext */ undefined, flags & 1024 /* AssignTypeFlags.IgnoreTypeVarScope */, recursionCount)) {
442
+ /* destConstraints */ undefined,
443
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
212
444
  // The srcType is narrower than the current upper bound, so replace it.
213
445
  newUpperTypeBound = adjSrcType;
214
446
  }
215
447
  else if (!evaluator.assignType(adjSrcType, curUpperBound, diagAddendum,
216
- /* destTypeVarContext */ undefined,
217
- /* srcTypeVarContext */ undefined, flags & 1024 /* AssignTypeFlags.IgnoreTypeVarScope */, recursionCount)) {
448
+ /* destConstraints */ undefined,
449
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
218
450
  if (diag && diagAddendum) {
219
451
  diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(curUpperBound, adjSrcType)));
220
452
  diag.addAddendum(diagAddendum);
@@ -226,8 +458,8 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
226
458
  if (curLowerBound) {
227
459
  if (!evaluator.assignType(newUpperTypeBound, curLowerBound,
228
460
  /* diag */ undefined,
229
- /* destTypeVarContext */ undefined,
230
- /* srcTypeVarContext */ undefined, flags & 1024 /* AssignTypeFlags.IgnoreTypeVarScope */, recursionCount)) {
461
+ /* destConstraints */ undefined,
462
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
231
463
  if (diag && diagAddendum) {
232
464
  diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(curLowerBound, newUpperTypeBound)));
233
465
  diag.addAddendum(diagAddendum);
@@ -250,26 +482,29 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
250
482
  }
251
483
  }
252
484
  else {
253
- if (evaluator.assignType(curLowerBound, adjSrcType, diagAddendum, typeVarContext,
254
- /* srcTypeVarContext */ undefined, flags, recursionCount)) {
485
+ if (evaluator.assignType(curLowerBound, adjSrcType, diagAddendum, constraints,
486
+ /* srcConstraints */ undefined, flags, recursionCount)) {
255
487
  // No need to widen. Stick with the existing type unless it's unknown
256
488
  // or partly unknown, in which case we'll replace it with a known type
257
489
  // as long as it doesn't violate the current lower bound.
258
490
  if ((0, typeUtils_1.isPartlyUnknown)(curLowerBound) &&
259
491
  !(0, types_1.isUnknown)(adjSrcType) &&
260
492
  evaluator.assignType(adjSrcType, curLowerBound,
261
- /* diag */ undefined, typeVarContext,
262
- /* srcTypeVarContext */ undefined, flags & 1024 /* AssignTypeFlags.IgnoreTypeVarScope */, recursionCount)) {
493
+ /* diag */ undefined, constraints,
494
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
263
495
  newLowerBound = adjSrcType;
264
496
  }
265
497
  else {
266
- newLowerBound = (0, typeUtils_1.applySolvedTypeVars)(curLowerBound, typeVarContext);
498
+ newLowerBound = curLowerBound;
499
+ if (constraints) {
500
+ newLowerBound = evaluator.solveAndApplyConstraints(newLowerBound, constraints);
501
+ }
267
502
  }
268
503
  }
269
504
  else if ((0, types_1.isTypeVar)(curLowerBound) &&
270
505
  !(0, types_1.isTypeVar)(adjSrcType) &&
271
- evaluator.assignType(evaluator.makeTopLevelTypeVarsConcrete(curLowerBound), adjSrcType, diagAddendum, typeVarContext,
272
- /* srcTypeVarContext */ undefined, flags, recursionCount)) {
506
+ evaluator.assignType(evaluator.makeTopLevelTypeVarsConcrete(curLowerBound), adjSrcType, diagAddendum, constraints,
507
+ /* srcConstraints */ undefined, flags, recursionCount)) {
273
508
  // If the existing lower bound was a TypeVar that is not
274
509
  // part of the current context we can replace it with the new
275
510
  // source type.
@@ -277,13 +512,13 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
277
512
  }
278
513
  else {
279
514
  // We need to widen the type.
280
- if (typeVarContext.isLocked()) {
515
+ if (constraints === null || constraints === void 0 ? void 0 : constraints.isLocked()) {
281
516
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(adjSrcType, curLowerBound)));
282
517
  return false;
283
518
  }
284
519
  if (evaluator.assignType(adjSrcType, curLowerBound,
285
- /* diag */ undefined, typeVarContext,
286
- /* srcTypeVarContext */ undefined, flags & 1024 /* AssignTypeFlags.IgnoreTypeVarScope */, recursionCount)) {
520
+ /* diag */ undefined, constraints,
521
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
287
522
  newLowerBound = adjSrcType;
288
523
  }
289
524
  else if ((0, types_1.isTypeVarTuple)(destType)) {
@@ -302,7 +537,10 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
302
537
  if (!newUpperTypeBound && isInvariant && (curEntry === null || curEntry === void 0 ? void 0 : curEntry.lowerBoundNoLiterals)) {
303
538
  curLowerBound = curEntry.lowerBoundNoLiterals;
304
539
  }
305
- const curSolvedLowerBound = (0, typeUtils_1.applySolvedTypeVars)(curLowerBound, typeVarContext);
540
+ let curSolvedLowerBound = curLowerBound;
541
+ if (constraints) {
542
+ curSolvedLowerBound = evaluator.solveAndApplyConstraints(curLowerBound, constraints);
543
+ }
306
544
  // In some extreme edge cases, the lower bound can become
307
545
  // a union with so many subtypes that performance grinds to a
308
546
  // halt. We'll detect this case and widen the resulting type
@@ -310,7 +548,7 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
310
548
  // is still a valid solution to the TypeVar.
311
549
  if ((0, types_1.isUnion)(curSolvedLowerBound) &&
312
550
  curSolvedLowerBound.priv.subtypes.length > typeEvaluatorTypes_1.maxSubtypesForInferredType &&
313
- destType.shared.boundType !== undefined &&
551
+ types_1.TypeVarType.hasBound(destType) &&
314
552
  (0, types_1.isClassInstance)(objectType)) {
315
553
  newLowerBound = (0, types_1.combineTypes)([curSolvedLowerBound, objectType], {
316
554
  maxSubtypeCount: maxSubtypeCountForTypeVarLowerBound,
@@ -328,8 +566,8 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
328
566
  // isn't too wide.
329
567
  if (isInvariant && newLowerBound) {
330
568
  if (!evaluator.assignType(adjSrcType, newLowerBound, diag === null || diag === void 0 ? void 0 : diag.createAddendum(),
331
- /* destTypeVarContext */ undefined,
332
- /* srcTypeVarContext */ undefined, 1024 /* AssignTypeFlags.IgnoreTypeVarScope */, recursionCount)) {
569
+ /* destConstraints */ undefined,
570
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
333
571
  if (diag && diagAddendum) {
334
572
  diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(newLowerBound, adjSrcType)));
335
573
  }
@@ -342,13 +580,13 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
342
580
  let adjUpperBound = evaluator.makeTopLevelTypeVarsConcrete(curUpperBound,
343
581
  /* makeParamSpecsConcrete */ true);
344
582
  // Convert any remaining (non-top-level) TypeVars in the upper
345
- // bound to in-scope placeholders.
583
+ // bound to unification vars.
346
584
  adjUpperBound = (0, typeUtils_1.transformExpectedType)(adjUpperBound,
347
585
  /* liveTypeVarScopes */ [],
348
586
  /* usageOffset */ undefined);
349
587
  if (!evaluator.assignType(adjUpperBound, newLowerBound, diag === null || diag === void 0 ? void 0 : diag.createAddendum(),
350
- /* destTypeVarContext */ undefined,
351
- /* srcTypeVarContext */ undefined, 1024 /* AssignTypeFlags.IgnoreTypeVarScope */, recursionCount)) {
588
+ /* destConstraints */ undefined,
589
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
352
590
  if (diag && diagAddendum) {
353
591
  diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(newLowerBound, adjUpperBound)));
354
592
  }
@@ -366,17 +604,15 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
366
604
  // If the dest is a Type[T] but the source is not a valid Type,
367
605
  // skip the assignType check and the diagnostic addendum, which will
368
606
  // be confusing and inaccurate.
369
- if (types_1.TypeBase.isInstantiable(destType) && !types_1.TypeBase.isInstantiable(srcType)) {
607
+ if (types_1.TypeBase.isInstantiable(destType) && !(0, typeUtils_1.isEffectivelyInstantiable)(srcType)) {
370
608
  return false;
371
609
  }
372
610
  // In general, bound types cannot be generic, but the "Self" type is an
373
- // exception. In this case, we need to use the original TypeVarContext
611
+ // exception. In this case, we need to use the original constraints
374
612
  // to solve for the generic type variable(s) in the bound type.
375
- const effectiveTypeVarContext = destType.shared.isSynthesizedSelf
376
- ? typeVarContext
377
- : new typeVarContext_1.TypeVarContext(destType.priv.scopeId);
378
- if (!evaluator.assignType(destType.shared.boundType, evaluator.makeTopLevelTypeVarsConcrete(updatedType), diag === null || diag === void 0 ? void 0 : diag.createAddendum(), effectiveTypeVarContext,
379
- /* srcTypeVarContext */ undefined, flags & 1024 /* AssignTypeFlags.IgnoreTypeVarScope */, recursionCount)) {
613
+ const effectiveConstraints = types_1.TypeVarType.isSelf(destType) ? constraints : undefined;
614
+ if (!evaluator.assignType(destType.shared.boundType, evaluator.makeTopLevelTypeVarsConcrete(updatedType), diag === null || diag === void 0 ? void 0 : diag.createAddendum(), effectiveConstraints,
615
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
380
616
  // Avoid adding a message that will confuse users if the TypeVar was
381
617
  // synthesized for internal purposes.
382
618
  if (!destType.shared.isSynthesized) {
@@ -389,50 +625,24 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
389
625
  return false;
390
626
  }
391
627
  }
392
- if (!typeVarContext.isLocked() && isTypeVarInScope) {
393
- updateTypeVarType(evaluator, typeVarContext, destType, newLowerBound, newUpperTypeBound, (flags & (2048 /* AssignTypeFlags.PopulatingExpectedType */ | 256 /* AssignTypeFlags.RetainLiteralsForTypeVar */)) !== 0);
394
- }
395
- if (logTypeVarContextUpdates) {
396
- const indent = ' '.repeat(recursionCount * 2);
397
- console.log(`${indent}`);
398
- logTypeVarContext(evaluator, typeVarContext, indent);
628
+ if (constraints && !constraints.isLocked()) {
629
+ updateTypeVarType(evaluator, constraints, destType, newLowerBound, newUpperTypeBound, (flags & (2048 /* AssignTypeFlags.PopulatingExpectedType */ | 256 /* AssignTypeFlags.RetainLiteralsForTypeVar */)) !== 0);
399
630
  }
400
631
  return true;
401
632
  }
402
- exports.assignTypeToTypeVar = assignTypeToTypeVar;
403
- // Updates the lower and upper bounds for a type variable. It also calculates the
404
- // lowerBoundNoLiterals, which is a variant of the lower bound that has
405
- // literals stripped. By default, the constraint solver always uses the "no literals"
406
- // type in its solutions unless the version with literals is required to satisfy
407
- // the upper bound.
408
- function updateTypeVarType(evaluator, typeVarContext, destType, lowerBound, upperBound, forceRetainLiterals = false) {
409
- let lowerBoundNoLiterals;
410
- if (lowerBound && !forceRetainLiterals) {
411
- const strippedLiteral = (0, types_1.isTypeVarTuple)(destType)
412
- ? stripLiteralValueForUnpackedTuple(evaluator, lowerBound)
413
- : evaluator.stripLiteralValue(lowerBound);
414
- // Strip the literals from the lower bound and see if it is still
415
- // narrower than the upper bound.
416
- if (strippedLiteral !== lowerBound) {
417
- if (!upperBound || evaluator.assignType(upperBound, strippedLiteral)) {
418
- lowerBoundNoLiterals = strippedLiteral;
419
- }
420
- }
421
- }
422
- typeVarContext.setTypeVarType(destType, lowerBound, lowerBoundNoLiterals, upperBound); //, tupleTypes);
423
- }
424
- exports.updateTypeVarType = updateTypeVarType;
425
- function assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, typeVarContext, flags, isTypeVarInScope, recursionCount) {
633
+ // Handles assignments to a TypeVar with value constraints.
634
+ function assignConstrainedTypeVar(evaluator, destType, srcType, diag, constraints, flags, recursionCount) {
426
635
  let constrainedType;
427
636
  const concreteSrcType = evaluator.makeTopLevelTypeVarsConcrete(srcType);
428
- const curEntry = typeVarContext.getMainSolutionSet().getTypeVar(destType);
637
+ const curEntry = constraints === null || constraints === void 0 ? void 0 : constraints.getMainConstraintSet().getTypeVar(destType);
429
638
  const curUpperBound = curEntry === null || curEntry === void 0 ? void 0 : curEntry.upperBound;
430
639
  const curLowerBound = curEntry === null || curEntry === void 0 ? void 0 : curEntry.lowerBound;
431
640
  let forceRetainLiterals = false;
432
641
  if ((0, types_1.isTypeVar)(srcType)) {
433
642
  if (evaluator.assignType(destType, concreteSrcType,
434
- /* diag */ undefined, new typeVarContext_1.TypeVarContext(destType.priv.scopeId),
435
- /* srcTypeVarContext */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
643
+ /* diag */ undefined,
644
+ /* destConstraints */ undefined,
645
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
436
646
  constrainedType = srcType;
437
647
  // If the source and dest are both instantiables (type[T]), then
438
648
  // we need to convert to an instance (T).
@@ -460,15 +670,15 @@ function assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, type
460
670
  : constraint;
461
671
  if (evaluator.assignType(adjustedConstraint, srcSubtype,
462
672
  /* diag */ undefined,
463
- /* destTypeVarContext */ undefined,
464
- /* srcTypeVarContext */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
673
+ /* destConstraints */ undefined,
674
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
465
675
  if (!constrainedSubtype ||
466
676
  evaluator.assignType(types_1.TypeBase.isInstantiable(destType)
467
677
  ? (0, typeUtils_1.convertToInstantiable)(constrainedSubtype)
468
678
  : constrainedSubtype, adjustedConstraint,
469
679
  /* diag */ undefined,
470
- /* destTypeVarContext */ undefined,
471
- /* srcTypeVarContext */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
680
+ /* destConstraints */ undefined,
681
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
472
682
  constrainedSubtype = (0, typeUtils_1.addConditionToType)(constraint, (0, typeUtils_1.getTypeCondition)(srcSubtype));
473
683
  constraintIndexUsed = i;
474
684
  }
@@ -505,8 +715,8 @@ function assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, type
505
715
  : constraint;
506
716
  return evaluator.assignType(adjustedConstraint, concreteSrcType,
507
717
  /* diag */ undefined,
508
- /* destTypeVarContext */ undefined,
509
- /* srcTypeVarContext */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount);
718
+ /* destConstraints */ undefined,
719
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount);
510
720
  });
511
721
  }
512
722
  }
@@ -526,17 +736,17 @@ function assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, type
526
736
  if (curLowerBound && !(0, types_1.isAnyOrUnknown)(curLowerBound)) {
527
737
  if (!evaluator.assignType(curLowerBound, constrainedType,
528
738
  /* diag */ undefined,
529
- /* destTypeVarContext */ undefined,
530
- /* srcTypeVarContext */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
739
+ /* destConstraints */ undefined,
740
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
531
741
  // Handle the case where one of the constrained types is a wider
532
742
  // version of another constrained type that was previously assigned
533
743
  // to the type variable.
534
744
  if (evaluator.assignType(constrainedType, curLowerBound,
535
745
  /* diag */ undefined,
536
- /* destTypeVarContext */ undefined,
537
- /* srcTypeVarContext */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
538
- if (!typeVarContext.isLocked() && isTypeVarInScope) {
539
- updateTypeVarType(evaluator, typeVarContext, destType, constrainedType, curUpperBound);
746
+ /* destConstraints */ undefined,
747
+ /* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
748
+ if (constraints && !constraints.isLocked()) {
749
+ updateTypeVarType(evaluator, constraints, destType, constrainedType, curUpperBound);
540
750
  }
541
751
  }
542
752
  else {
@@ -550,21 +760,32 @@ function assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, type
550
760
  }
551
761
  else {
552
762
  // Assign the type to the type var.
553
- if (!typeVarContext.isLocked() && isTypeVarInScope) {
554
- updateTypeVarType(evaluator, typeVarContext, destType, constrainedType, curUpperBound, forceRetainLiterals);
763
+ if (constraints && !constraints.isLocked()) {
764
+ updateTypeVarType(evaluator, constraints, destType, constrainedType, curUpperBound, forceRetainLiterals);
555
765
  }
556
766
  }
557
767
  return true;
558
768
  }
559
- function assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContext, recursionCount = 0) {
769
+ // Handles assignments to a ParamSpec.
770
+ function assignParamSpec(evaluator, destType, srcType, diag, constraints, recursionCount = 0) {
771
+ // If there is no constraint tracker, there's nothing to do because
772
+ // param specs have no upper bounds or constraints.
773
+ if (!constraints) {
774
+ return true;
775
+ }
560
776
  let isAssignable = true;
561
- const adjSrcType = (0, types_1.isFunction)(srcType) ? (0, typeUtils_1.convertParamSpecValueToType)(srcType) : srcType;
562
- typeVarContext.doForEachSolutionSet((solutionSet) => {
777
+ let adjSrcType = (0, types_1.isParamSpec)(srcType) ? srcType : (0, typeUtils_1.convertTypeToParamSpecValue)(srcType);
778
+ if ((0, types_1.isFunction)(adjSrcType)) {
779
+ adjSrcType = (0, typeUtils_1.simplifyFunctionToParamSpec)(adjSrcType);
780
+ }
781
+ constraints.doForEachConstraintSet((constraintSet) => {
782
+ var _a, _b;
563
783
  if ((0, types_1.isParamSpec)(adjSrcType)) {
564
- const existingType = solutionSet.getTypeVarType(destType);
784
+ const existingType = (_a = constraintSet.getTypeVar(destType)) === null || _a === void 0 ? void 0 : _a.lowerBound;
565
785
  if (existingType) {
566
- const existingTypeParamSpec = types_1.FunctionType.getParamSpecFromArgsKwargs(existingType);
567
- const existingTypeWithoutArgsKwargs = types_1.FunctionType.cloneRemoveParamSpecArgsKwargs(existingType);
786
+ const paramSpecValue = (0, typeUtils_1.convertTypeToParamSpecValue)(existingType);
787
+ const existingTypeParamSpec = types_1.FunctionType.getParamSpecFromArgsKwargs(paramSpecValue);
788
+ const existingTypeWithoutArgsKwargs = types_1.FunctionType.cloneRemoveParamSpecArgsKwargs(paramSpecValue);
568
789
  if (existingTypeWithoutArgsKwargs.shared.parameters.length === 0 && existingTypeParamSpec) {
569
790
  // If there's an existing entry that matches, that's fine.
570
791
  if ((0, types_1.isTypeSame)(existingTypeParamSpec, adjSrcType, {}, recursionCount)) {
@@ -573,8 +794,8 @@ function assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContex
573
794
  }
574
795
  }
575
796
  else {
576
- if (!typeVarContext.isLocked() && typeVarContext.hasSolveForScope(destType.priv.scopeId)) {
577
- solutionSet.setTypeVarType(destType, (0, typeUtils_1.convertTypeToParamSpecValue)(adjSrcType));
797
+ if (!constraints.isLocked()) {
798
+ constraintSet.setBounds(destType, adjSrcType);
578
799
  }
579
800
  return;
580
801
  }
@@ -582,19 +803,19 @@ function assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContex
582
803
  else if ((0, types_1.isFunction)(adjSrcType)) {
583
804
  const newFunction = adjSrcType;
584
805
  let updateContextWithNewFunction = false;
585
- const existingType = solutionSet.getTypeVarType(destType);
806
+ const existingType = (_b = constraintSet.getTypeVar(destType)) === null || _b === void 0 ? void 0 : _b.lowerBound;
586
807
  if (existingType) {
587
808
  // Convert the remaining portion of the signature to a function
588
809
  // for comparison purposes.
589
- const existingFunction = (0, typeUtils_1.convertParamSpecValueToType)(existingType);
810
+ const existingFunction = (0, typeUtils_1.simplifyFunctionToParamSpec)((0, typeUtils_1.convertTypeToParamSpecValue)(existingType));
590
811
  const isNewNarrower = evaluator.assignType(existingFunction, newFunction,
591
812
  /* diag */ undefined,
592
- /* destTypeVarContext */ undefined,
593
- /* srcTypeVarContext */ undefined, 64 /* AssignTypeFlags.SkipReturnTypeCheck */, recursionCount);
813
+ /* destConstraints */ undefined,
814
+ /* srcConstraints */ undefined, 64 /* AssignTypeFlags.SkipReturnTypeCheck */, recursionCount);
594
815
  const isNewWider = evaluator.assignType(newFunction, existingFunction,
595
816
  /* diag */ undefined,
596
- /* destTypeVarContext */ undefined,
597
- /* srcTypeVarContext */ undefined, 64 /* AssignTypeFlags.SkipReturnTypeCheck */, recursionCount);
817
+ /* destConstraints */ undefined,
818
+ /* srcConstraints */ undefined, 64 /* AssignTypeFlags.SkipReturnTypeCheck */, recursionCount);
598
819
  // Should we widen the type?
599
820
  if (isNewNarrower && isNewWider) {
600
821
  // The new type is both a supertype and a subtype of the existing type.
@@ -622,8 +843,8 @@ function assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContex
622
843
  updateContextWithNewFunction = true;
623
844
  }
624
845
  if (updateContextWithNewFunction) {
625
- if (!typeVarContext.isLocked() && typeVarContext.hasSolveForScope(destType.priv.scopeId)) {
626
- solutionSet.setTypeVarType(destType, newFunction);
846
+ if (!constraints.isLocked()) {
847
+ constraintSet.setBounds(destType, newFunction);
627
848
  }
628
849
  return;
629
850
  }
@@ -637,149 +858,26 @@ function assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContex
637
858
  }));
638
859
  isAssignable = false;
639
860
  });
640
- if (logTypeVarContextUpdates) {
641
- const indent = ' '.repeat(recursionCount * 2);
642
- console.log(`${indent}`);
643
- console.log(`${indent}post-call typeVarContext: `);
644
- logTypeVarContext(evaluator, typeVarContext, indent);
645
- }
646
861
  return isAssignable;
647
862
  }
648
- // In cases where the expected type is a specialized base class of the
649
- // source type, we need to determine which type arguments in the derived
650
- // class will make it compatible with the specialized base class. This method
651
- // performs this reverse mapping of type arguments and populates the type var
652
- // map for the target type. If the type is not assignable to the expected type,
653
- // it returns false.
654
- function addConstraintsForExpectedType(evaluator, type, expectedType, typeVarContext, liveTypeVarScopes, usageOffset = undefined) {
655
- if ((0, types_1.isAny)(expectedType)) {
656
- type.shared.typeParams.forEach((typeParam) => {
657
- updateTypeVarType(evaluator, typeVarContext, typeParam, expectedType, expectedType);
658
- });
659
- return true;
863
+ class UnificationVarTransformer extends typeUtils_1.TypeVarTransformer {
864
+ constructor(_evaluator, _constraintSet) {
865
+ super();
866
+ this._evaluator = _evaluator;
867
+ this._constraintSet = _constraintSet;
660
868
  }
661
- if ((0, types_1.isTypeVar)(expectedType) && expectedType.shared.isSynthesizedSelf && expectedType.shared.boundType) {
662
- expectedType = expectedType.shared.boundType;
663
- }
664
- if (!(0, types_1.isClass)(expectedType)) {
665
- return false;
666
- }
667
- // If the expected type is generic (but not specialized), we can't proceed.
668
- const expectedTypeArgs = expectedType.priv.typeArgs;
669
- if (!expectedTypeArgs) {
670
- return evaluator.assignType(type, expectedType,
671
- /* diag */ undefined, typeVarContext,
672
- /* srcTypeVarContext */ undefined, 2048 /* AssignTypeFlags.PopulatingExpectedType */);
673
- }
674
- evaluator.inferVarianceForClass(type);
675
- // If the expected type is the same as the target type (commonly the case),
676
- // we can use a faster method.
677
- if (types_1.ClassType.isSameGenericClass(expectedType, type)) {
678
- const sameClassTypeVarContext = (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(expectedType);
679
- sameClassTypeVarContext
680
- .getMainSolutionSet()
681
- .getTypeVars()
682
- .forEach((entry) => {
683
- let typeArgValue = sameClassTypeVarContext.getMainSolutionSet().getTypeVarType(entry.typeVar);
684
- if (typeArgValue && liveTypeVarScopes) {
685
- typeArgValue = (0, typeUtils_1.transformExpectedType)(typeArgValue, liveTypeVarScopes, usageOffset);
686
- }
687
- if (typeArgValue) {
688
- const variance = types_1.TypeVarType.getVariance(entry.typeVar);
689
- updateTypeVarType(evaluator, typeVarContext, entry.typeVar, variance === 3 /* Variance.Covariant */ ? undefined : typeArgValue, variance === 4 /* Variance.Contravariant */ ? undefined : typeArgValue);
690
- }
691
- });
692
- return true;
693
- }
694
- // Create a generic version of the expected type.
695
- const expectedTypeScopeId = (0, typeUtils_1.getTypeVarScopeId)(expectedType);
696
- const synthExpectedTypeArgs = types_1.ClassType.getTypeParams(expectedType).map((typeParam, index) => {
697
- const typeVar = types_1.TypeVarType.createInstance(`__dest${index}`, (0, types_1.isParamSpec)(typeParam) ? types_1.TypeVarKind.ParamSpec : types_1.TypeVarKind.TypeVar);
698
- typeVar.shared.isSynthesized = true;
699
- // Use invariance here so we set the lower and upper bound on the TypeVar.
700
- typeVar.shared.declaredVariance = 2 /* Variance.Invariant */;
701
- typeVar.priv.scopeId = expectedTypeScopeId;
702
- return typeVar;
703
- });
704
- const genericExpectedType = types_1.ClassType.specialize(expectedType, synthExpectedTypeArgs);
705
- // For each type param in the target type, create a placeholder type variable.
706
- const typeArgs = types_1.ClassType.getTypeParams(type).map((typeParam, index) => {
707
- const typeVar = types_1.TypeVarType.createInstance(`__source${index}`, (0, types_1.isParamSpec)(typeParam) ? types_1.TypeVarKind.ParamSpec : types_1.TypeVarKind.TypeVar);
708
- typeVar.shared.isSynthesized = true;
709
- typeVar.shared.synthesizedIndex = index;
710
- typeVar.shared.isExemptFromBoundCheck = true;
711
- return types_1.TypeVarType.cloneAsInScopePlaceholder(typeVar);
712
- });
713
- const specializedType = types_1.ClassType.specialize(type, typeArgs);
714
- const syntheticTypeVarContext = new typeVarContext_1.TypeVarContext(expectedTypeScopeId);
715
- if (evaluator.assignType(genericExpectedType, specializedType,
716
- /* diag */ undefined, syntheticTypeVarContext,
717
- /* srcTypeVarContext */ undefined, 2048 /* AssignTypeFlags.PopulatingExpectedType */)) {
718
- let isResultValid = true;
719
- synthExpectedTypeArgs.forEach((typeVar, index) => {
720
- let synthTypeVar = syntheticTypeVarContext.getMainSolutionSet().getTypeVarType(typeVar);
721
- const otherSubtypes = [];
722
- // If the resulting type is a union, try to find a matching type var and move
723
- // the remaining subtypes to the "otherSubtypes" array.
724
- if (synthTypeVar) {
725
- if ((0, types_1.isParamSpec)(typeVar) && (0, types_1.isFunction)(synthTypeVar)) {
726
- synthTypeVar = (0, typeUtils_1.convertParamSpecValueToType)(synthTypeVar);
727
- }
728
- if ((0, types_1.isUnion)(synthTypeVar)) {
729
- let foundSynthTypeVar;
730
- (0, typeUtils_1.sortTypes)(synthTypeVar.priv.subtypes).forEach((subtype) => {
731
- if ((0, types_1.isTypeVar)(subtype) &&
732
- subtype.shared.isSynthesized &&
733
- subtype.shared.synthesizedIndex !== undefined &&
734
- !foundSynthTypeVar) {
735
- foundSynthTypeVar = subtype;
736
- }
737
- else {
738
- otherSubtypes.push(subtype);
739
- }
740
- });
741
- if (foundSynthTypeVar) {
742
- synthTypeVar = foundSynthTypeVar;
743
- }
744
- }
745
- }
746
- // Is this one of the synthesized type vars we allocated above? If so,
747
- // the type arg that corresponds to this type var maps back to the target type.
748
- if (synthTypeVar &&
749
- (0, types_1.isTypeVar)(synthTypeVar) &&
750
- synthTypeVar.shared.isSynthesized &&
751
- synthTypeVar.shared.synthesizedIndex !== undefined) {
752
- const targetTypeVar = types_1.ClassType.getTypeParams(specializedType)[synthTypeVar.shared.synthesizedIndex];
753
- if (index < expectedTypeArgs.length) {
754
- let typeArgValue = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expectedTypeArgs[index]);
755
- if (otherSubtypes.length > 0) {
756
- typeArgValue = (0, types_1.combineTypes)([typeArgValue, ...otherSubtypes]);
757
- }
758
- if (liveTypeVarScopes) {
759
- typeArgValue = (0, typeUtils_1.transformExpectedType)(typeArgValue, liveTypeVarScopes, usageOffset);
760
- }
761
- if (typeArgValue) {
762
- const variance = types_1.TypeVarType.getVariance(typeVar);
763
- // If this type variable already has a type, don't overwrite it. This can
764
- // happen if a single type variable in the derived class is used multiple times
765
- // in the specialized base class type (e.g. Mapping[T, T]).
766
- if (typeVarContext.getMainSolutionSet().getTypeVarType(targetTypeVar)) {
767
- isResultValid = false;
768
- typeArgValue = types_1.UnknownType.create();
769
- }
770
- updateTypeVarType(evaluator, typeVarContext, targetTypeVar, variance === 3 /* Variance.Covariant */ ? undefined : typeArgValue, variance === 4 /* Variance.Contravariant */ ? undefined : typeArgValue);
771
- }
772
- else {
773
- isResultValid = false;
774
- }
775
- }
776
- }
777
- });
778
- return isResultValid;
869
+ transformTypeVar(typeVar) {
870
+ var _a;
871
+ if (types_1.TypeVarType.isUnification(typeVar)) {
872
+ return (_a = getTypeVarType(this._evaluator, this._constraintSet, typeVar)) !== null && _a !== void 0 ? _a : typeVar;
873
+ }
874
+ return undefined;
779
875
  }
780
- return false;
781
876
  }
782
- exports.addConstraintsForExpectedType = addConstraintsForExpectedType;
877
+ function applyUnificationVarsToType(evaluator, type, constraintSet) {
878
+ const transformer = new UnificationVarTransformer(evaluator, constraintSet);
879
+ return transformer.apply(type, 0);
880
+ }
783
881
  // For normal TypeVars, the constraint solver can widen a type by combining
784
882
  // two otherwise incompatible types into a union. For TypeVarTuples, we need
785
883
  // to do the equivalent operation for unpacked tuples.
@@ -829,23 +927,23 @@ function stripLiteralValueForUnpackedTuple(evaluator, type) {
829
927
  return (0, typeUtils_1.specializeTupleClass)(type, tupleTypeArgs, /* isTypeArgExplicit */ true, /* isUnpackedTuple */ true);
830
928
  }
831
929
  // This function is used for debugging only. It dumps the current contents of
832
- // the TypeVarContext to the console.
833
- function logTypeVarContext(evaluator, typeVarContext, indent) {
834
- const solutionSetCount = typeVarContext.getSolutionSets().length;
835
- if (solutionSetCount === 0) {
930
+ // the constraints to the console.
931
+ function logConstraints(evaluator, constraints, indent) {
932
+ const constraintSetCount = constraints.getConstraintSets().length;
933
+ if (constraintSetCount === 0) {
836
934
  console.log(`${indent} no signatures`);
837
935
  }
838
- else if (solutionSetCount === 1) {
839
- logTypeVarSolutionSet(evaluator, typeVarContext.getSolutionSets()[0], `${indent} `);
936
+ else if (constraintSetCount === 1) {
937
+ logTypeVarConstraintSet(evaluator, constraints.getConstraintSets()[0], `${indent} `);
840
938
  }
841
939
  else {
842
- typeVarContext.doForEachSolutionSet((solutionSet, index) => {
940
+ constraints.doForEachConstraintSet((set, index) => {
843
941
  console.log(`${indent} signature ${index}`);
844
- logTypeVarSolutionSet(evaluator, solutionSet, `${indent} `);
942
+ logTypeVarConstraintSet(evaluator, set, `${indent} `);
845
943
  });
846
944
  }
847
945
  }
848
- function logTypeVarSolutionSet(evaluator, context, indent) {
946
+ function logTypeVarConstraintSet(evaluator, context, indent) {
849
947
  let loggedConstraint = false;
850
948
  context.getTypeVars().forEach((entry) => {
851
949
  var _a;