@zzzen/pyright-internal 1.2.0-dev.20240721 → 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.
- package/dist/analyzer/analyzerNodeInfo.js +2 -2
- package/dist/analyzer/analyzerNodeInfo.js.map +1 -1
- package/dist/analyzer/binder.js +15 -12
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/cacheManager.js +3 -0
- package/dist/analyzer/cacheManager.js.map +1 -1
- package/dist/analyzer/checker.d.ts +5 -3
- package/dist/analyzer/checker.js +238 -193
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.d.ts +2 -2
- package/dist/analyzer/codeFlowEngine.js +53 -46
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/codeFlowTypes.js +1 -1
- package/dist/analyzer/codeFlowTypes.js.map +1 -1
- package/dist/analyzer/constraintSolution.d.ts +21 -0
- package/dist/analyzer/constraintSolution.js +71 -0
- package/dist/analyzer/constraintSolution.js.map +1 -0
- package/dist/analyzer/constraintSolver.d.ts +10 -6
- package/dist/analyzer/constraintSolver.js +520 -462
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constraintTracker.d.ts +44 -0
- package/dist/analyzer/constraintTracker.js +230 -0
- package/dist/analyzer/constraintTracker.js.map +1 -0
- package/dist/analyzer/constructorTransform.d.ts +2 -2
- package/dist/analyzer/constructorTransform.js +25 -25
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/constructors.d.ts +3 -3
- package/dist/analyzer/constructors.js +80 -64
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/dataClasses.d.ts +2 -2
- package/dist/analyzer/dataClasses.js +87 -61
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/declaration.d.ts +9 -9
- package/dist/analyzer/declaration.js +9 -9
- package/dist/analyzer/declaration.js.map +1 -1
- package/dist/analyzer/declarationUtils.d.ts +1 -1
- package/dist/analyzer/declarationUtils.js +6 -6
- package/dist/analyzer/declarationUtils.js.map +1 -1
- package/dist/analyzer/decorators.js +5 -5
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/docStringConversion.js +2 -2
- package/dist/analyzer/docStringConversion.js.map +1 -1
- package/dist/analyzer/enums.d.ts +2 -2
- package/dist/analyzer/enums.js +6 -6
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/functionTransform.d.ts +2 -2
- package/dist/analyzer/functionTransform.js +5 -5
- package/dist/analyzer/functionTransform.js.map +1 -1
- package/dist/analyzer/importResolver.js +5 -3
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/namedTuples.d.ts +3 -3
- package/dist/analyzer/namedTuples.js +21 -22
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/operations.d.ts +1 -2
- package/dist/analyzer/operations.js +105 -82
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/packageTypeVerifier.js +16 -12
- package/dist/analyzer/packageTypeVerifier.js.map +1 -1
- package/dist/analyzer/parameterUtils.d.ts +12 -12
- package/dist/analyzer/parameterUtils.js +67 -69
- package/dist/analyzer/parameterUtils.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +6 -6
- package/dist/analyzer/parseTreeUtils.js +22 -22
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +122 -101
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.js +11 -4
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.d.ts +3 -2
- package/dist/analyzer/properties.js +27 -27
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +3 -3
- package/dist/analyzer/protocols.js +58 -57
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/pythonPathUtils.js +1 -1
- package/dist/analyzer/pythonPathUtils.js.map +1 -1
- package/dist/analyzer/service.d.ts +3 -7
- package/dist/analyzer/service.js +28 -30
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/serviceUtils.d.ts +8 -0
- package/dist/analyzer/serviceUtils.js +31 -0
- package/dist/analyzer/serviceUtils.js.map +1 -0
- package/dist/analyzer/sourceFile.js +5 -19
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/sourceMapper.d.ts +1 -1
- package/dist/analyzer/sourceMapper.js +4 -4
- package/dist/analyzer/sourceMapper.js.map +1 -1
- package/dist/analyzer/staticExpressions.js +1 -1
- package/dist/analyzer/staticExpressions.js.map +1 -1
- package/dist/analyzer/tracePrinter.js +4 -4
- package/dist/analyzer/tracePrinter.js.map +1 -1
- package/dist/analyzer/tuples.d.ts +9 -0
- package/dist/analyzer/tuples.js +253 -0
- package/dist/analyzer/tuples.js.map +1 -0
- package/dist/analyzer/typeComplexity.d.ts +2 -0
- package/dist/analyzer/typeComplexity.js +94 -0
- package/dist/analyzer/typeComplexity.js.map +1 -0
- package/dist/analyzer/typeEvaluator.js +1758 -1979
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +69 -45
- package/dist/analyzer/typeEvaluatorTypes.js +7 -1
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +157 -121
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.d.ts +1 -1
- package/dist/analyzer/typePrinter.js +64 -61
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeStubWriter.d.ts +3 -3
- package/dist/analyzer/typeStubWriter.js +15 -15
- package/dist/analyzer/typeStubWriter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +45 -41
- package/dist/analyzer/typeUtils.js +511 -748
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeWalker.js +4 -4
- package/dist/analyzer/typeWalker.js.map +1 -1
- package/dist/analyzer/typedDicts.d.ts +4 -4
- package/dist/analyzer/typedDicts.js +73 -77
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +97 -72
- package/dist/analyzer/types.js +217 -208
- package/dist/analyzer/types.js.map +1 -1
- package/dist/commands/dumpFileDebugInfoCommand.js +11 -11
- package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
- package/dist/common/configOptions.d.ts +1 -0
- package/dist/common/configOptions.js +5 -0
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/diagnosticRules.d.ts +1 -0
- package/dist/common/diagnosticRules.js +1 -0
- package/dist/common/diagnosticRules.js.map +1 -1
- package/dist/common/fileSystem.d.ts +0 -1
- package/dist/common/fileSystem.js.map +1 -1
- package/dist/common/languageServerInterface.d.ts +13 -0
- package/dist/common/languageServerInterface.js +15 -1
- package/dist/common/languageServerInterface.js.map +1 -1
- package/dist/common/lspUtils.js +2 -2
- package/dist/common/memUtils.d.ts +4 -0
- package/dist/common/memUtils.js +33 -2
- package/dist/common/memUtils.js.map +1 -1
- package/dist/common/serviceKeys.d.ts +3 -0
- package/dist/common/serviceKeys.js +2 -0
- package/dist/common/serviceKeys.js.map +1 -1
- package/dist/common/serviceProviderExtensions.js +7 -0
- package/dist/common/serviceProviderExtensions.js.map +1 -1
- package/dist/languageServerBase.d.ts +5 -4
- package/dist/languageServerBase.js +19 -12
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/autoImporter.d.ts +3 -2
- package/dist/languageService/autoImporter.js +5 -1
- package/dist/languageService/autoImporter.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +5 -3
- package/dist/languageService/completionProvider.js +39 -38
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/completionProviderUtils.d.ts +1 -1
- package/dist/languageService/completionProviderUtils.js +3 -3
- package/dist/languageService/completionProviderUtils.js.map +1 -1
- package/dist/languageService/fileWatcherDynamicFeature.js +2 -2
- package/dist/languageService/fileWatcherDynamicFeature.js.map +1 -1
- package/dist/languageService/hoverProvider.js +3 -3
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/referencesProvider.js +2 -2
- package/dist/languageService/signatureHelpProvider.js +1 -1
- package/dist/languageService/signatureHelpProvider.js.map +1 -1
- package/dist/languageService/tooltipUtils.js +3 -3
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/localization/localize.d.ts +5 -0
- package/dist/localization/localize.js +6 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +5 -1
- package/dist/localization/package.nls.de.json +5 -1
- package/dist/localization/package.nls.en-us.json +5 -0
- package/dist/localization/package.nls.es.json +5 -1
- package/dist/localization/package.nls.fr.json +5 -1
- package/dist/localization/package.nls.it.json +5 -1
- package/dist/localization/package.nls.ja.json +5 -1
- package/dist/localization/package.nls.ko.json +5 -1
- package/dist/localization/package.nls.pl.json +5 -1
- package/dist/localization/package.nls.pt-br.json +5 -1
- package/dist/localization/package.nls.qps-ploc.json +5 -1
- package/dist/localization/package.nls.ru.json +5 -1
- package/dist/localization/package.nls.tr.json +5 -1
- package/dist/localization/package.nls.zh-cn.json +5 -1
- package/dist/localization/package.nls.zh-tw.json +5 -1
- package/dist/parser/parseNodes.d.ts +9 -9
- package/dist/parser/parseNodes.js +20 -20
- package/dist/parser/parseNodes.js.map +1 -1
- package/dist/parser/parser.js +30 -30
- package/dist/parser/parser.js.map +1 -1
- package/dist/tests/checker.test.js +12 -4
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/fourslash/signature.builtinDocstrings.fourslash.js +4 -21
- package/dist/tests/fourslash/signature.builtinDocstrings.fourslash.js.map +1 -1
- package/dist/tests/fourslash/signature.complicated.fourslash.js +1 -1
- package/dist/tests/fourslash/signature.complicated.fourslash.js.map +1 -1
- package/dist/tests/harness/fourslash/fourSlashParser.js +1 -1
- package/dist/tests/harness/fourslash/fourSlashParser.js.map +1 -1
- package/dist/tests/harness/fourslash/testStateUtils.js +2 -2
- package/dist/tests/harness/fourslash/testStateUtils.js.map +1 -1
- package/dist/tests/harness/vfs/filesystem.d.ts +0 -1
- package/dist/tests/harness/vfs/filesystem.js +0 -4
- package/dist/tests/harness/vfs/filesystem.js.map +1 -1
- package/dist/tests/importResolver.test.js +62 -15
- package/dist/tests/importResolver.test.js.map +1 -1
- package/dist/tests/lsp/languageServerTestUtils.js +1 -1
- package/dist/tests/lsp/languageServerTestUtils.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +1 -1
- package/dist/tests/typeEvaluator2.test.js +12 -0
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +5 -1
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +10 -2
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +9 -3
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/tests/typeEvaluator6.test.js +72 -60
- package/dist/tests/typeEvaluator6.test.js.map +1 -1
- package/dist/tests/typeEvaluator7.test.js +6 -2
- package/dist/tests/typeEvaluator7.test.js.map +1 -1
- package/dist/tests/typeEvaluator8.test.js +4 -0
- package/dist/tests/typeEvaluator8.test.js.map +1 -1
- package/dist/tests/typePrinter.test.js +13 -18
- package/dist/tests/typePrinter.test.js.map +1 -1
- package/dist/workspaceFactory.d.ts +3 -2
- package/dist/workspaceFactory.js +15 -2
- package/dist/workspaceFactory.js.map +1 -1
- package/package.json +1 -1
- package/dist/analyzer/typeVarContext.d.ts +0 -60
- package/dist/analyzer/typeVarContext.js +0 -392
- package/dist/analyzer/typeVarContext.js.map +0 -1
@@ -10,152 +10,382 @@
|
|
10
10
|
*
|
11
11
|
*/
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
13
|
-
exports.addConstraintsForExpectedType = exports.updateTypeVarType = exports.
|
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
|
-
|
20
|
-
// As we widen the narrow bound of a type variable, we may end up with
|
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
|
-
const
|
24
|
-
// This debugging switch enables logging of the
|
24
|
+
const maxSubtypeCountForTypeVarLowerBound = 64;
|
25
|
+
// This debugging switch enables logging of the constraints before and
|
25
26
|
// after it is updated by the constraint solver.
|
26
|
-
const
|
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
|
34
|
-
|
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}
|
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
|
-
|
42
|
-
|
43
|
-
|
43
|
+
if (constraints) {
|
44
|
+
logConstraints(evaluator, constraints, indent);
|
45
|
+
}
|
44
46
|
}
|
45
|
-
let isTypeVarInScope = true;
|
46
|
-
const isInvariant = (flags & 1 /* AssignTypeFlags.EnforceInvariance */) !== 0;
|
47
|
-
const isContravariant = (flags & 2 /* AssignTypeFlags.ReverseTypeVarMatching */) !== 0 && !isInvariant;
|
48
47
|
// If the TypeVar doesn't have a scope ID, then it's being used
|
49
48
|
// outside of a valid TypeVar scope. This will be reported as a
|
50
49
|
// separate error. Just ignore this case to avoid redundant errors.
|
51
50
|
if (!destType.priv.scopeId) {
|
52
51
|
return true;
|
53
52
|
}
|
53
|
+
if (types_1.TypeVarType.isBound(destType) && !types_1.TypeVarType.isUnification(destType)) {
|
54
|
+
return assignBoundTypeVar(evaluator, destType, srcType, diag, flags);
|
55
|
+
}
|
54
56
|
// Handle type[T] as a dest and a special form as a source.
|
55
57
|
if (types_1.TypeBase.isInstantiable(destType) &&
|
56
58
|
(0, types_1.isInstantiableClass)(srcType) &&
|
57
59
|
evaluator.isSpecialFormClass(srcType, flags)) {
|
58
60
|
return false;
|
59
61
|
}
|
60
|
-
//
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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));
|
75
78
|
}
|
76
79
|
}
|
77
|
-
//
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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);
|
83
87
|
}
|
84
|
-
//
|
85
|
-
//
|
86
|
-
|
87
|
-
|
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);
|
88
94
|
}
|
89
|
-
|
90
|
-
|
91
|
-
if ((flags & 1024 /* AssignTypeFlags.IgnoreTypeVarScope */) !== 0) {
|
92
|
-
return true;
|
95
|
+
else {
|
96
|
+
isAssignable = assignUnconstrainedTypeVar(evaluator, destType, srcType, diag, constraints, flags, recursionCount);
|
93
97
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
98
|
+
}
|
99
|
+
if (logConstraintsUpdates) {
|
100
|
+
const indent = ' '.repeat(recursionCount * 2);
|
101
|
+
console.log(`${indent}`);
|
102
|
+
if (constraints) {
|
103
|
+
logConstraints(evaluator, constraints, indent);
|
100
104
|
}
|
101
105
|
}
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
+
});
|
105
163
|
return true;
|
106
164
|
}
|
107
|
-
if ((
|
108
|
-
|
109
|
-
|
110
|
-
|
165
|
+
if ((0, types_1.isTypeVar)(expectedType) && types_1.TypeVarType.isSelf(expectedType) && expectedType.shared.boundType) {
|
166
|
+
expectedType = expectedType.shared.boundType;
|
167
|
+
}
|
168
|
+
if (!(0, types_1.isClass)(expectedType)) {
|
169
|
+
return false;
|
111
170
|
}
|
112
|
-
|
113
|
-
|
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 */);
|
114
177
|
}
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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);
|
123
188
|
}
|
124
|
-
|
125
|
-
|
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);
|
126
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;
|
127
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);
|
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;
|
128
315
|
}
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
316
|
+
if ((0, types_1.isParamSpec)(typeVar)) {
|
317
|
+
if (!entry.lowerBound) {
|
318
|
+
return undefined;
|
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;
|
137
349
|
}
|
138
|
-
//
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
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;
|
354
|
+
}
|
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
|
+
}
|
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)));
|
144
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;
|
145
375
|
// Handle the unconstrained (but possibly bound) case.
|
146
|
-
const curEntry =
|
147
|
-
let
|
148
|
-
if (!
|
149
|
-
|
150
|
-
}
|
151
|
-
let
|
152
|
-
let
|
153
|
-
let
|
376
|
+
const curEntry = constraints === null || constraints === void 0 ? void 0 : constraints.getMainConstraintSet().getTypeVar(destType);
|
377
|
+
let curUpperBound = curEntry === null || curEntry === void 0 ? void 0 : curEntry.upperBound;
|
378
|
+
if (!curUpperBound && !types_1.TypeVarType.isSelf(destType)) {
|
379
|
+
curUpperBound = destType.shared.boundType;
|
380
|
+
}
|
381
|
+
let curLowerBound = curEntry === null || curEntry === void 0 ? void 0 : curEntry.lowerBound;
|
382
|
+
let newLowerBound = curLowerBound;
|
383
|
+
let newUpperTypeBound = curUpperBound;
|
154
384
|
const diagAddendum = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
|
155
385
|
let adjSrcType = srcType;
|
156
386
|
// If the source is a class that is missing type arguments, fill
|
157
387
|
// in missing type arguments with Unknown.
|
158
|
-
if ((flags & 8192 /* AssignTypeFlags.
|
388
|
+
if ((flags & 8192 /* AssignTypeFlags.AllowUnspecifiedTypeArgs */) === 0) {
|
159
389
|
if ((0, types_1.isClass)(adjSrcType) && adjSrcType.priv.includeSubclasses) {
|
160
390
|
adjSrcType = (0, typeUtils_1.specializeWithDefaultTypeArgs)(adjSrcType);
|
161
391
|
}
|
@@ -187,51 +417,51 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
|
|
187
417
|
return true;
|
188
418
|
}
|
189
419
|
// If we're populating the expected type, constrain either the
|
190
|
-
//
|
420
|
+
// lower type bound, upper type bound or both. Don't overwrite
|
191
421
|
// an existing entry.
|
192
422
|
if (!curEntry) {
|
193
423
|
if (isInvariant) {
|
194
|
-
|
195
|
-
|
424
|
+
newLowerBound = adjSrcType;
|
425
|
+
newUpperTypeBound = adjSrcType;
|
196
426
|
}
|
197
427
|
else if (isContravariant) {
|
198
|
-
|
428
|
+
newLowerBound = adjSrcType;
|
199
429
|
}
|
200
430
|
else {
|
201
|
-
|
431
|
+
newUpperTypeBound = adjSrcType;
|
202
432
|
}
|
203
433
|
}
|
204
434
|
}
|
205
435
|
else if (isContravariant) {
|
206
|
-
// Update the
|
207
|
-
if (!
|
208
|
-
|
209
|
-
}
|
210
|
-
else if (!(0, types_1.isTypeSame)(
|
211
|
-
if (evaluator.assignType(
|
212
|
-
/*
|
213
|
-
/*
|
214
|
-
// The srcType is narrower than the current
|
215
|
-
|
216
|
-
}
|
217
|
-
else if (!evaluator.assignType(adjSrcType,
|
218
|
-
/*
|
219
|
-
/*
|
436
|
+
// Update the upper bound.
|
437
|
+
if (!curUpperBound || (0, types_1.isTypeSame)(destType, curUpperBound)) {
|
438
|
+
newUpperTypeBound = adjSrcType;
|
439
|
+
}
|
440
|
+
else if (!(0, types_1.isTypeSame)(curUpperBound, adjSrcType, {}, recursionCount)) {
|
441
|
+
if (evaluator.assignType(curUpperBound, evaluator.makeTopLevelTypeVarsConcrete(adjSrcType), diagAddendum,
|
442
|
+
/* destConstraints */ undefined,
|
443
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
444
|
+
// The srcType is narrower than the current upper bound, so replace it.
|
445
|
+
newUpperTypeBound = adjSrcType;
|
446
|
+
}
|
447
|
+
else if (!evaluator.assignType(adjSrcType, curUpperBound, diagAddendum,
|
448
|
+
/* destConstraints */ undefined,
|
449
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
220
450
|
if (diag && diagAddendum) {
|
221
|
-
diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(
|
451
|
+
diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(curUpperBound, adjSrcType)));
|
222
452
|
diag.addAddendum(diagAddendum);
|
223
453
|
}
|
224
454
|
return false;
|
225
455
|
}
|
226
456
|
}
|
227
|
-
// Make sure we haven't narrowed it beyond the current
|
228
|
-
if (
|
229
|
-
if (!evaluator.assignType(
|
457
|
+
// Make sure we haven't narrowed it beyond the current lower bound.
|
458
|
+
if (curLowerBound) {
|
459
|
+
if (!evaluator.assignType(newUpperTypeBound, curLowerBound,
|
230
460
|
/* diag */ undefined,
|
231
|
-
/*
|
232
|
-
/*
|
461
|
+
/* destConstraints */ undefined,
|
462
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
233
463
|
if (diag && diagAddendum) {
|
234
|
-
diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(
|
464
|
+
diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(curLowerBound, newUpperTypeBound)));
|
235
465
|
diag.addAddendum(diagAddendum);
|
236
466
|
}
|
237
467
|
return false;
|
@@ -239,152 +469,150 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
|
|
239
469
|
}
|
240
470
|
}
|
241
471
|
else {
|
242
|
-
if (!
|
243
|
-
// There was previously no
|
244
|
-
|
472
|
+
if (!curLowerBound || (0, types_1.isTypeSame)(destType, curLowerBound)) {
|
473
|
+
// There was previously no lower bound. We've now established one.
|
474
|
+
newLowerBound = adjSrcType;
|
245
475
|
}
|
246
|
-
else if ((0, types_1.isTypeSame)(
|
247
|
-
// If this is an invariant context and there is currently no
|
248
|
-
// established, use the "no literals" version of the
|
476
|
+
else if ((0, types_1.isTypeSame)(curLowerBound, adjSrcType, {}, recursionCount)) {
|
477
|
+
// If this is an invariant context and there is currently no upper bound
|
478
|
+
// established, use the "no literals" version of the lower bound rather
|
249
479
|
// than a version that has literals.
|
250
|
-
if (!
|
251
|
-
|
480
|
+
if (!newUpperTypeBound && isInvariant && (curEntry === null || curEntry === void 0 ? void 0 : curEntry.lowerBoundNoLiterals)) {
|
481
|
+
newLowerBound = curEntry.lowerBoundNoLiterals;
|
252
482
|
}
|
253
483
|
}
|
254
484
|
else {
|
255
|
-
if ((
|
256
|
-
|
257
|
-
// during the construction of a tuple, the resulting tuple type must
|
258
|
-
// be tuple[Any, ...], which is compatible with any tuple.
|
259
|
-
newNarrowTypeBound = adjSrcType;
|
260
|
-
}
|
261
|
-
else if (evaluator.assignType(curNarrowTypeBound, adjSrcType, diagAddendum, typeVarContext,
|
262
|
-
/* srcTypeVarContext */ undefined, flags, recursionCount)) {
|
485
|
+
if (evaluator.assignType(curLowerBound, adjSrcType, diagAddendum, constraints,
|
486
|
+
/* srcConstraints */ undefined, flags, recursionCount)) {
|
263
487
|
// No need to widen. Stick with the existing type unless it's unknown
|
264
488
|
// or partly unknown, in which case we'll replace it with a known type
|
265
|
-
// as long as it doesn't violate the current
|
266
|
-
if ((0, typeUtils_1.isPartlyUnknown)(
|
489
|
+
// as long as it doesn't violate the current lower bound.
|
490
|
+
if ((0, typeUtils_1.isPartlyUnknown)(curLowerBound) &&
|
267
491
|
!(0, types_1.isUnknown)(adjSrcType) &&
|
268
|
-
evaluator.assignType(adjSrcType,
|
269
|
-
/* diag */ undefined,
|
270
|
-
/*
|
271
|
-
|
492
|
+
evaluator.assignType(adjSrcType, curLowerBound,
|
493
|
+
/* diag */ undefined, constraints,
|
494
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
495
|
+
newLowerBound = adjSrcType;
|
272
496
|
}
|
273
497
|
else {
|
274
|
-
|
498
|
+
newLowerBound = curLowerBound;
|
499
|
+
if (constraints) {
|
500
|
+
newLowerBound = evaluator.solveAndApplyConstraints(newLowerBound, constraints);
|
501
|
+
}
|
275
502
|
}
|
276
503
|
}
|
277
|
-
else if ((0, types_1.isTypeVar)(
|
504
|
+
else if ((0, types_1.isTypeVar)(curLowerBound) &&
|
278
505
|
!(0, types_1.isTypeVar)(adjSrcType) &&
|
279
|
-
evaluator.assignType(evaluator.makeTopLevelTypeVarsConcrete(
|
280
|
-
/*
|
281
|
-
// If the existing
|
506
|
+
evaluator.assignType(evaluator.makeTopLevelTypeVarsConcrete(curLowerBound), adjSrcType, diagAddendum, constraints,
|
507
|
+
/* srcConstraints */ undefined, flags, recursionCount)) {
|
508
|
+
// If the existing lower bound was a TypeVar that is not
|
282
509
|
// part of the current context we can replace it with the new
|
283
510
|
// source type.
|
284
|
-
|
511
|
+
newLowerBound = adjSrcType;
|
285
512
|
}
|
286
513
|
else {
|
287
514
|
// We need to widen the type.
|
288
|
-
if (
|
289
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(adjSrcType,
|
515
|
+
if (constraints === null || constraints === void 0 ? void 0 : constraints.isLocked()) {
|
516
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(adjSrcType, curLowerBound)));
|
290
517
|
return false;
|
291
518
|
}
|
292
|
-
if (evaluator.assignType(adjSrcType,
|
293
|
-
/* diag */ undefined,
|
294
|
-
/*
|
295
|
-
|
519
|
+
if (evaluator.assignType(adjSrcType, curLowerBound,
|
520
|
+
/* diag */ undefined, constraints,
|
521
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
522
|
+
newLowerBound = adjSrcType;
|
296
523
|
}
|
297
|
-
else if ((0, types_1.
|
298
|
-
const widenedType =
|
524
|
+
else if ((0, types_1.isTypeVarTuple)(destType)) {
|
525
|
+
const widenedType = widenTypeForTypeVarTuple(evaluator, curLowerBound, adjSrcType);
|
299
526
|
if (!widenedType) {
|
300
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(
|
527
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(curLowerBound, adjSrcType)));
|
301
528
|
return false;
|
302
529
|
}
|
303
|
-
|
530
|
+
newLowerBound = widenedType;
|
304
531
|
}
|
305
532
|
else {
|
306
533
|
const objectType = evaluator.getObjectType();
|
307
|
-
// If this is an invariant context and there is currently no
|
308
|
-
// established, use the "no literals" version of the
|
534
|
+
// If this is an invariant context and there is currently no upper bound
|
535
|
+
// established, use the "no literals" version of the lower bound rather
|
309
536
|
// than a version that has literals.
|
310
|
-
if (!
|
311
|
-
|
537
|
+
if (!newUpperTypeBound && isInvariant && (curEntry === null || curEntry === void 0 ? void 0 : curEntry.lowerBoundNoLiterals)) {
|
538
|
+
curLowerBound = curEntry.lowerBoundNoLiterals;
|
539
|
+
}
|
540
|
+
let curSolvedLowerBound = curLowerBound;
|
541
|
+
if (constraints) {
|
542
|
+
curSolvedLowerBound = evaluator.solveAndApplyConstraints(curLowerBound, constraints);
|
312
543
|
}
|
313
|
-
|
314
|
-
// In some extreme edge cases, the narrow type bound can become
|
544
|
+
// In some extreme edge cases, the lower bound can become
|
315
545
|
// a union with so many subtypes that performance grinds to a
|
316
546
|
// halt. We'll detect this case and widen the resulting type
|
317
547
|
// to an 'object' instead of making the union even bigger. This
|
318
548
|
// is still a valid solution to the TypeVar.
|
319
|
-
if ((0, types_1.isUnion)(
|
320
|
-
|
321
|
-
|
549
|
+
if ((0, types_1.isUnion)(curSolvedLowerBound) &&
|
550
|
+
curSolvedLowerBound.priv.subtypes.length > typeEvaluatorTypes_1.maxSubtypesForInferredType &&
|
551
|
+
types_1.TypeVarType.hasBound(destType) &&
|
322
552
|
(0, types_1.isClassInstance)(objectType)) {
|
323
|
-
|
324
|
-
maxSubtypeCount:
|
553
|
+
newLowerBound = (0, types_1.combineTypes)([curSolvedLowerBound, objectType], {
|
554
|
+
maxSubtypeCount: maxSubtypeCountForTypeVarLowerBound,
|
325
555
|
});
|
326
556
|
}
|
327
557
|
else {
|
328
|
-
|
329
|
-
maxSubtypeCount:
|
558
|
+
newLowerBound = (0, types_1.combineTypes)([curSolvedLowerBound, adjSrcType], {
|
559
|
+
maxSubtypeCount: maxSubtypeCountForTypeVarLowerBound,
|
330
560
|
});
|
331
561
|
}
|
332
562
|
}
|
333
563
|
}
|
334
564
|
}
|
335
|
-
// If this is an invariant context, make sure the
|
565
|
+
// If this is an invariant context, make sure the lower bound
|
336
566
|
// isn't too wide.
|
337
|
-
if (isInvariant &&
|
338
|
-
if (!evaluator.assignType(adjSrcType,
|
339
|
-
/*
|
340
|
-
/*
|
567
|
+
if (isInvariant && newLowerBound) {
|
568
|
+
if (!evaluator.assignType(adjSrcType, newLowerBound, diag === null || diag === void 0 ? void 0 : diag.createAddendum(),
|
569
|
+
/* destConstraints */ undefined,
|
570
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
341
571
|
if (diag && diagAddendum) {
|
342
|
-
diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(
|
572
|
+
diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(newLowerBound, adjSrcType)));
|
343
573
|
}
|
344
574
|
return false;
|
345
575
|
}
|
346
576
|
}
|
347
|
-
// Make sure we don't exceed the
|
348
|
-
if (
|
349
|
-
if (!(0, types_1.isTypeSame)(
|
350
|
-
let
|
577
|
+
// Make sure we don't exceed the upper bound.
|
578
|
+
if (curUpperBound && newLowerBound) {
|
579
|
+
if (!(0, types_1.isTypeSame)(curUpperBound, newLowerBound, {}, recursionCount)) {
|
580
|
+
let adjUpperBound = evaluator.makeTopLevelTypeVarsConcrete(curUpperBound,
|
351
581
|
/* makeParamSpecsConcrete */ true);
|
352
|
-
// Convert any remaining (non-top-level) TypeVars in the
|
353
|
-
// bound to
|
354
|
-
|
582
|
+
// Convert any remaining (non-top-level) TypeVars in the upper
|
583
|
+
// bound to unification vars.
|
584
|
+
adjUpperBound = (0, typeUtils_1.transformExpectedType)(adjUpperBound,
|
355
585
|
/* liveTypeVarScopes */ [],
|
356
586
|
/* usageOffset */ undefined);
|
357
|
-
if (!evaluator.assignType(
|
358
|
-
/*
|
359
|
-
/*
|
587
|
+
if (!evaluator.assignType(adjUpperBound, newLowerBound, diag === null || diag === void 0 ? void 0 : diag.createAddendum(),
|
588
|
+
/* destConstraints */ undefined,
|
589
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
360
590
|
if (diag && diagAddendum) {
|
361
|
-
diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(
|
591
|
+
diag.addMessage(localize_1.LocAddendum.typeAssignmentMismatch().format(evaluator.printSrcDestTypes(newLowerBound, adjUpperBound)));
|
362
592
|
}
|
363
593
|
return false;
|
364
594
|
}
|
365
595
|
}
|
366
596
|
}
|
367
597
|
}
|
368
|
-
if (!
|
369
|
-
|
598
|
+
if (!newUpperTypeBound && isInvariant) {
|
599
|
+
newUpperTypeBound = newLowerBound;
|
370
600
|
}
|
371
601
|
// If there's a bound type, make sure the source is assignable to it.
|
372
602
|
if (destType.shared.boundType) {
|
373
|
-
const updatedType = (
|
603
|
+
const updatedType = (newLowerBound || newUpperTypeBound);
|
374
604
|
// If the dest is a Type[T] but the source is not a valid Type,
|
375
605
|
// skip the assignType check and the diagnostic addendum, which will
|
376
606
|
// be confusing and inaccurate.
|
377
|
-
if (types_1.TypeBase.isInstantiable(destType) && !
|
607
|
+
if (types_1.TypeBase.isInstantiable(destType) && !(0, typeUtils_1.isEffectivelyInstantiable)(srcType)) {
|
378
608
|
return false;
|
379
609
|
}
|
380
610
|
// In general, bound types cannot be generic, but the "Self" type is an
|
381
|
-
// exception. In this case, we need to use the original
|
611
|
+
// exception. In this case, we need to use the original constraints
|
382
612
|
// to solve for the generic type variable(s) in the bound type.
|
383
|
-
const
|
384
|
-
|
385
|
-
|
386
|
-
if (!evaluator.assignType(destType.shared.boundType, evaluator.makeTopLevelTypeVarsConcrete(updatedType), diag === null || diag === void 0 ? void 0 : diag.createAddendum(), effectiveTypeVarContext,
|
387
|
-
/* 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)) {
|
388
616
|
// Avoid adding a message that will confuse users if the TypeVar was
|
389
617
|
// synthesized for internal purposes.
|
390
618
|
if (!destType.shared.isSynthesized) {
|
@@ -397,61 +625,24 @@ function assignTypeToTypeVar(evaluator, destType, srcType, diag, typeVarContext,
|
|
397
625
|
return false;
|
398
626
|
}
|
399
627
|
}
|
400
|
-
|
401
|
-
|
402
|
-
// tuple is indeterminate.
|
403
|
-
let newTupleTypes = curEntry === null || curEntry === void 0 ? void 0 : curEntry.tupleTypes;
|
404
|
-
if (newTupleTypes) {
|
405
|
-
const updatedType = newNarrowTypeBound !== null && newNarrowTypeBound !== void 0 ? newNarrowTypeBound : newWideTypeBound;
|
406
|
-
if (updatedType) {
|
407
|
-
newTupleTypes = [{ type: updatedType, isUnbounded: true }];
|
408
|
-
}
|
409
|
-
}
|
410
|
-
if (!typeVarContext.isLocked() && isTypeVarInScope) {
|
411
|
-
updateTypeVarType(evaluator, typeVarContext, destType, newNarrowTypeBound, newWideTypeBound, newTupleTypes, (flags & (2048 /* AssignTypeFlags.PopulatingExpectedType */ | 256 /* AssignTypeFlags.RetainLiteralsForTypeVar */)) !== 0);
|
412
|
-
}
|
413
|
-
if (logTypeVarContextUpdates) {
|
414
|
-
const indent = ' '.repeat(recursionCount * 2);
|
415
|
-
console.log(`${indent}`);
|
416
|
-
console.log(`${indent}post-call context #${typeVarContext.getId()}: `);
|
417
|
-
logTypeVarContext(evaluator, typeVarContext, indent);
|
628
|
+
if (constraints && !constraints.isLocked()) {
|
629
|
+
updateTypeVarType(evaluator, constraints, destType, newLowerBound, newUpperTypeBound, (flags & (2048 /* AssignTypeFlags.PopulatingExpectedType */ | 256 /* AssignTypeFlags.RetainLiteralsForTypeVar */)) !== 0);
|
418
630
|
}
|
419
631
|
return true;
|
420
632
|
}
|
421
|
-
|
422
|
-
|
423
|
-
// narrowTypeBoundNoLiterals, which is a variant of the narrow type bound that has
|
424
|
-
// literals stripped. By default, the constraint solver always uses the "no literals"
|
425
|
-
// type in its solutions unless the version with literals is required to satisfy
|
426
|
-
// the wide type bound.
|
427
|
-
function updateTypeVarType(evaluator, typeVarContext, destType, narrowTypeBound, wideTypeBound, tupleTypes = undefined, forceRetainLiterals = false) {
|
428
|
-
let narrowTypeBoundNoLiterals;
|
429
|
-
if (narrowTypeBound && !forceRetainLiterals) {
|
430
|
-
const strippedLiteral = (0, types_1.isVariadicTypeVar)(destType)
|
431
|
-
? stripLiteralValueForUnpackedTuple(evaluator, narrowTypeBound)
|
432
|
-
: evaluator.stripLiteralValue(narrowTypeBound);
|
433
|
-
// Strip the literals from the narrow type bound and see if it is still
|
434
|
-
// narrower than the wide bound.
|
435
|
-
if (strippedLiteral !== narrowTypeBound) {
|
436
|
-
if (!wideTypeBound || evaluator.assignType(wideTypeBound, strippedLiteral)) {
|
437
|
-
narrowTypeBoundNoLiterals = strippedLiteral;
|
438
|
-
}
|
439
|
-
}
|
440
|
-
}
|
441
|
-
typeVarContext.setTypeVarType(destType, narrowTypeBound, narrowTypeBoundNoLiterals, wideTypeBound, tupleTypes);
|
442
|
-
}
|
443
|
-
exports.updateTypeVarType = updateTypeVarType;
|
444
|
-
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) {
|
445
635
|
let constrainedType;
|
446
636
|
const concreteSrcType = evaluator.makeTopLevelTypeVarsConcrete(srcType);
|
447
|
-
const curEntry =
|
448
|
-
const
|
449
|
-
const
|
637
|
+
const curEntry = constraints === null || constraints === void 0 ? void 0 : constraints.getMainConstraintSet().getTypeVar(destType);
|
638
|
+
const curUpperBound = curEntry === null || curEntry === void 0 ? void 0 : curEntry.upperBound;
|
639
|
+
const curLowerBound = curEntry === null || curEntry === void 0 ? void 0 : curEntry.lowerBound;
|
450
640
|
let forceRetainLiterals = false;
|
451
641
|
if ((0, types_1.isTypeVar)(srcType)) {
|
452
642
|
if (evaluator.assignType(destType, concreteSrcType,
|
453
|
-
/* diag */ undefined,
|
454
|
-
/*
|
643
|
+
/* diag */ undefined,
|
644
|
+
/* destConstraints */ undefined,
|
645
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
455
646
|
constrainedType = srcType;
|
456
647
|
// If the source and dest are both instantiables (type[T]), then
|
457
648
|
// we need to convert to an instance (T).
|
@@ -479,15 +670,15 @@ function assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, type
|
|
479
670
|
: constraint;
|
480
671
|
if (evaluator.assignType(adjustedConstraint, srcSubtype,
|
481
672
|
/* diag */ undefined,
|
482
|
-
/*
|
483
|
-
/*
|
673
|
+
/* destConstraints */ undefined,
|
674
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
484
675
|
if (!constrainedSubtype ||
|
485
676
|
evaluator.assignType(types_1.TypeBase.isInstantiable(destType)
|
486
677
|
? (0, typeUtils_1.convertToInstantiable)(constrainedSubtype)
|
487
678
|
: constrainedSubtype, adjustedConstraint,
|
488
679
|
/* diag */ undefined,
|
489
|
-
/*
|
490
|
-
/*
|
680
|
+
/* destConstraints */ undefined,
|
681
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
491
682
|
constrainedSubtype = (0, typeUtils_1.addConditionToType)(constraint, (0, typeUtils_1.getTypeCondition)(srcSubtype));
|
492
683
|
constraintIndexUsed = i;
|
493
684
|
}
|
@@ -524,8 +715,8 @@ function assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, type
|
|
524
715
|
: constraint;
|
525
716
|
return evaluator.assignType(adjustedConstraint, concreteSrcType,
|
526
717
|
/* diag */ undefined,
|
527
|
-
/*
|
528
|
-
/*
|
718
|
+
/* destConstraints */ undefined,
|
719
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount);
|
529
720
|
});
|
530
721
|
}
|
531
722
|
}
|
@@ -542,26 +733,26 @@ function assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, type
|
|
542
733
|
else if ((0, typeUtils_1.isLiteralTypeOrUnion)(constrainedType)) {
|
543
734
|
forceRetainLiterals = true;
|
544
735
|
}
|
545
|
-
if (
|
546
|
-
if (!evaluator.assignType(
|
736
|
+
if (curLowerBound && !(0, types_1.isAnyOrUnknown)(curLowerBound)) {
|
737
|
+
if (!evaluator.assignType(curLowerBound, constrainedType,
|
547
738
|
/* diag */ undefined,
|
548
|
-
/*
|
549
|
-
/*
|
739
|
+
/* destConstraints */ undefined,
|
740
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
550
741
|
// Handle the case where one of the constrained types is a wider
|
551
742
|
// version of another constrained type that was previously assigned
|
552
743
|
// to the type variable.
|
553
|
-
if (evaluator.assignType(constrainedType,
|
744
|
+
if (evaluator.assignType(constrainedType, curLowerBound,
|
554
745
|
/* diag */ undefined,
|
555
|
-
/*
|
556
|
-
/*
|
557
|
-
if (!
|
558
|
-
updateTypeVarType(evaluator,
|
746
|
+
/* destConstraints */ undefined,
|
747
|
+
/* srcConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
|
748
|
+
if (constraints && !constraints.isLocked()) {
|
749
|
+
updateTypeVarType(evaluator, constraints, destType, constrainedType, curUpperBound);
|
559
750
|
}
|
560
751
|
}
|
561
752
|
else {
|
562
753
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.LocAddendum.typeConstrainedTypeVar().format({
|
563
754
|
type: evaluator.printType(constrainedType),
|
564
|
-
name: evaluator.printType(
|
755
|
+
name: evaluator.printType(curLowerBound),
|
565
756
|
}));
|
566
757
|
return false;
|
567
758
|
}
|
@@ -569,22 +760,32 @@ function assignTypeToConstrainedTypeVar(evaluator, destType, srcType, diag, type
|
|
569
760
|
}
|
570
761
|
else {
|
571
762
|
// Assign the type to the type var.
|
572
|
-
if (!
|
573
|
-
updateTypeVarType(evaluator,
|
574
|
-
/* tupleTypes */ undefined, forceRetainLiterals);
|
763
|
+
if (constraints && !constraints.isLocked()) {
|
764
|
+
updateTypeVarType(evaluator, constraints, destType, constrainedType, curUpperBound, forceRetainLiterals);
|
575
765
|
}
|
576
766
|
}
|
577
767
|
return true;
|
578
768
|
}
|
579
|
-
|
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
|
+
}
|
580
776
|
let isAssignable = true;
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
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;
|
783
|
+
if ((0, types_1.isParamSpec)(adjSrcType)) {
|
784
|
+
const existingType = (_a = constraintSet.getTypeVar(destType)) === null || _a === void 0 ? void 0 : _a.lowerBound;
|
585
785
|
if (existingType) {
|
586
|
-
const
|
587
|
-
const
|
786
|
+
const paramSpecValue = (0, typeUtils_1.convertTypeToParamSpecValue)(existingType);
|
787
|
+
const existingTypeParamSpec = types_1.FunctionType.getParamSpecFromArgsKwargs(paramSpecValue);
|
788
|
+
const existingTypeWithoutArgsKwargs = types_1.FunctionType.cloneRemoveParamSpecArgsKwargs(paramSpecValue);
|
588
789
|
if (existingTypeWithoutArgsKwargs.shared.parameters.length === 0 && existingTypeParamSpec) {
|
589
790
|
// If there's an existing entry that matches, that's fine.
|
590
791
|
if ((0, types_1.isTypeSame)(existingTypeParamSpec, adjSrcType, {}, recursionCount)) {
|
@@ -593,8 +794,8 @@ function assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContex
|
|
593
794
|
}
|
594
795
|
}
|
595
796
|
else {
|
596
|
-
if (!
|
597
|
-
|
797
|
+
if (!constraints.isLocked()) {
|
798
|
+
constraintSet.setBounds(destType, adjSrcType);
|
598
799
|
}
|
599
800
|
return;
|
600
801
|
}
|
@@ -602,19 +803,19 @@ function assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContex
|
|
602
803
|
else if ((0, types_1.isFunction)(adjSrcType)) {
|
603
804
|
const newFunction = adjSrcType;
|
604
805
|
let updateContextWithNewFunction = false;
|
605
|
-
const existingType =
|
806
|
+
const existingType = (_b = constraintSet.getTypeVar(destType)) === null || _b === void 0 ? void 0 : _b.lowerBound;
|
606
807
|
if (existingType) {
|
607
808
|
// Convert the remaining portion of the signature to a function
|
608
809
|
// for comparison purposes.
|
609
|
-
const existingFunction = (0, typeUtils_1.
|
810
|
+
const existingFunction = (0, typeUtils_1.simplifyFunctionToParamSpec)((0, typeUtils_1.convertTypeToParamSpecValue)(existingType));
|
610
811
|
const isNewNarrower = evaluator.assignType(existingFunction, newFunction,
|
611
812
|
/* diag */ undefined,
|
612
|
-
/*
|
613
|
-
/*
|
813
|
+
/* destConstraints */ undefined,
|
814
|
+
/* srcConstraints */ undefined, 64 /* AssignTypeFlags.SkipReturnTypeCheck */, recursionCount);
|
614
815
|
const isNewWider = evaluator.assignType(newFunction, existingFunction,
|
615
816
|
/* diag */ undefined,
|
616
|
-
/*
|
617
|
-
/*
|
817
|
+
/* destConstraints */ undefined,
|
818
|
+
/* srcConstraints */ undefined, 64 /* AssignTypeFlags.SkipReturnTypeCheck */, recursionCount);
|
618
819
|
// Should we widen the type?
|
619
820
|
if (isNewNarrower && isNewWider) {
|
620
821
|
// The new type is both a supertype and a subtype of the existing type.
|
@@ -642,8 +843,8 @@ function assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContex
|
|
642
843
|
updateContextWithNewFunction = true;
|
643
844
|
}
|
644
845
|
if (updateContextWithNewFunction) {
|
645
|
-
if (!
|
646
|
-
|
846
|
+
if (!constraints.isLocked()) {
|
847
|
+
constraintSet.setBounds(destType, newFunction);
|
647
848
|
}
|
648
849
|
return;
|
649
850
|
}
|
@@ -657,173 +858,30 @@ function assignTypeToParamSpec(evaluator, destType, srcType, diag, typeVarContex
|
|
657
858
|
}));
|
658
859
|
isAssignable = false;
|
659
860
|
});
|
660
|
-
if (logTypeVarContextUpdates) {
|
661
|
-
const indent = ' '.repeat(recursionCount * 2);
|
662
|
-
console.log(`${indent}`);
|
663
|
-
console.log(`${indent}post-call typeVarContext: `);
|
664
|
-
logTypeVarContext(evaluator, typeVarContext, indent);
|
665
|
-
}
|
666
861
|
return isAssignable;
|
667
862
|
}
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
// it returns false.
|
674
|
-
function addConstraintsForExpectedType(evaluator, type, expectedType, typeVarContext, liveTypeVarScopes, usageOffset = undefined) {
|
675
|
-
if ((0, types_1.isAny)(expectedType)) {
|
676
|
-
type.shared.typeParameters.forEach((typeParam) => {
|
677
|
-
updateTypeVarType(evaluator, typeVarContext, typeParam, expectedType, expectedType);
|
678
|
-
});
|
679
|
-
return true;
|
680
|
-
}
|
681
|
-
if ((0, types_1.isTypeVar)(expectedType) && expectedType.shared.isSynthesizedSelf && expectedType.shared.boundType) {
|
682
|
-
expectedType = expectedType.shared.boundType;
|
683
|
-
}
|
684
|
-
if (!(0, types_1.isClass)(expectedType)) {
|
685
|
-
return false;
|
686
|
-
}
|
687
|
-
// If the expected type is generic (but not specialized), we can't proceed.
|
688
|
-
const expectedTypeArgs = expectedType.priv.typeArguments;
|
689
|
-
if (!expectedTypeArgs) {
|
690
|
-
return evaluator.assignType(type, expectedType,
|
691
|
-
/* diag */ undefined, typeVarContext,
|
692
|
-
/* srcTypeVarContext */ undefined, 2048 /* AssignTypeFlags.PopulatingExpectedType */);
|
863
|
+
class UnificationVarTransformer extends typeUtils_1.TypeVarTransformer {
|
864
|
+
constructor(_evaluator, _constraintSet) {
|
865
|
+
super();
|
866
|
+
this._evaluator = _evaluator;
|
867
|
+
this._constraintSet = _constraintSet;
|
693
868
|
}
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
const sameClassTypeVarContext = (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(expectedType);
|
699
|
-
sameClassTypeVarContext
|
700
|
-
.getPrimarySignature()
|
701
|
-
.getTypeVars()
|
702
|
-
.forEach((entry) => {
|
703
|
-
let typeArgValue = sameClassTypeVarContext.getPrimarySignature().getTypeVarType(entry.typeVar);
|
704
|
-
if (typeArgValue && liveTypeVarScopes) {
|
705
|
-
typeArgValue = (0, typeUtils_1.transformExpectedType)(typeArgValue, liveTypeVarScopes, usageOffset);
|
706
|
-
}
|
707
|
-
if (typeArgValue) {
|
708
|
-
const variance = types_1.TypeVarType.getVariance(entry.typeVar);
|
709
|
-
updateTypeVarType(evaluator, typeVarContext, entry.typeVar, variance === 3 /* Variance.Covariant */ ? undefined : typeArgValue, variance === 4 /* Variance.Contravariant */ ? undefined : typeArgValue);
|
710
|
-
if (entry.tupleTypes) {
|
711
|
-
typeVarContext.setTupleTypeVar(entry.typeVar, entry.tupleTypes.map((tupleEntry) => {
|
712
|
-
let tupleType = tupleEntry.type;
|
713
|
-
if (liveTypeVarScopes) {
|
714
|
-
tupleType = (0, typeUtils_1.transformExpectedType)(tupleEntry.type, liveTypeVarScopes, usageOffset);
|
715
|
-
}
|
716
|
-
return {
|
717
|
-
type: tupleType,
|
718
|
-
isUnbounded: tupleEntry.isUnbounded,
|
719
|
-
isOptional: tupleEntry.isOptional,
|
720
|
-
};
|
721
|
-
}));
|
722
|
-
}
|
723
|
-
}
|
724
|
-
});
|
725
|
-
return true;
|
726
|
-
}
|
727
|
-
// Create a generic version of the expected type.
|
728
|
-
const expectedTypeScopeId = (0, typeUtils_1.getTypeVarScopeId)(expectedType);
|
729
|
-
const synthExpectedTypeArgs = types_1.ClassType.getTypeParameters(expectedType).map((typeParam, index) => {
|
730
|
-
const typeVar = types_1.TypeVarType.createInstance(`__dest${index}`);
|
731
|
-
typeVar.shared.isSynthesized = true;
|
732
|
-
if (typeParam.shared.isParamSpec) {
|
733
|
-
typeVar.shared.isParamSpec = true;
|
734
|
-
}
|
735
|
-
// Use invariance here so we set the narrow and wide values on the TypeVar.
|
736
|
-
typeVar.shared.declaredVariance = 2 /* Variance.Invariant */;
|
737
|
-
typeVar.priv.scopeId = expectedTypeScopeId;
|
738
|
-
return typeVar;
|
739
|
-
});
|
740
|
-
const genericExpectedType = types_1.ClassType.cloneForSpecialization(expectedType, synthExpectedTypeArgs,
|
741
|
-
/* isTypeArgumentExplicit */ true);
|
742
|
-
// For each type param in the target type, create a placeholder type variable.
|
743
|
-
const typeArgs = types_1.ClassType.getTypeParameters(type).map((typeParam, index) => {
|
744
|
-
const typeVar = types_1.TypeVarType.createInstance(`__source${index}`);
|
745
|
-
typeVar.shared.isSynthesized = true;
|
746
|
-
typeVar.shared.synthesizedIndex = index;
|
747
|
-
typeVar.shared.isExemptFromBoundCheck = true;
|
748
|
-
if (typeParam.shared.isParamSpec) {
|
749
|
-
typeVar.shared.isParamSpec = true;
|
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;
|
750
873
|
}
|
751
|
-
return
|
752
|
-
});
|
753
|
-
const specializedType = types_1.ClassType.cloneForSpecialization(type, typeArgs, /* isTypeArgumentExplicit */ true);
|
754
|
-
const syntheticTypeVarContext = new typeVarContext_1.TypeVarContext(expectedTypeScopeId);
|
755
|
-
if (evaluator.assignType(genericExpectedType, specializedType,
|
756
|
-
/* diag */ undefined, syntheticTypeVarContext,
|
757
|
-
/* srcTypeVarContext */ undefined, 2048 /* AssignTypeFlags.PopulatingExpectedType */)) {
|
758
|
-
let isResultValid = true;
|
759
|
-
synthExpectedTypeArgs.forEach((typeVar, index) => {
|
760
|
-
let synthTypeVar = syntheticTypeVarContext.getPrimarySignature().getTypeVarType(typeVar);
|
761
|
-
const otherSubtypes = [];
|
762
|
-
// If the resulting type is a union, try to find a matching type var and move
|
763
|
-
// the remaining subtypes to the "otherSubtypes" array.
|
764
|
-
if (synthTypeVar) {
|
765
|
-
if (typeVar.shared.isParamSpec && (0, types_1.isFunction)(synthTypeVar)) {
|
766
|
-
synthTypeVar = (0, typeUtils_1.convertParamSpecValueToType)(synthTypeVar);
|
767
|
-
}
|
768
|
-
if ((0, types_1.isUnion)(synthTypeVar)) {
|
769
|
-
let foundSynthTypeVar;
|
770
|
-
(0, typeUtils_1.sortTypes)(synthTypeVar.priv.subtypes).forEach((subtype) => {
|
771
|
-
if ((0, types_1.isTypeVar)(subtype) &&
|
772
|
-
subtype.shared.isSynthesized &&
|
773
|
-
subtype.shared.synthesizedIndex !== undefined &&
|
774
|
-
!foundSynthTypeVar) {
|
775
|
-
foundSynthTypeVar = subtype;
|
776
|
-
}
|
777
|
-
else {
|
778
|
-
otherSubtypes.push(subtype);
|
779
|
-
}
|
780
|
-
});
|
781
|
-
if (foundSynthTypeVar) {
|
782
|
-
synthTypeVar = foundSynthTypeVar;
|
783
|
-
}
|
784
|
-
}
|
785
|
-
}
|
786
|
-
// Is this one of the synthesized type vars we allocated above? If so,
|
787
|
-
// the type arg that corresponds to this type var maps back to the target type.
|
788
|
-
if (synthTypeVar &&
|
789
|
-
(0, types_1.isTypeVar)(synthTypeVar) &&
|
790
|
-
synthTypeVar.shared.isSynthesized &&
|
791
|
-
synthTypeVar.shared.synthesizedIndex !== undefined) {
|
792
|
-
const targetTypeVar = types_1.ClassType.getTypeParameters(specializedType)[synthTypeVar.shared.synthesizedIndex];
|
793
|
-
if (index < expectedTypeArgs.length) {
|
794
|
-
let typeArgValue = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expectedTypeArgs[index]);
|
795
|
-
if (otherSubtypes.length > 0) {
|
796
|
-
typeArgValue = (0, types_1.combineTypes)([typeArgValue, ...otherSubtypes]);
|
797
|
-
}
|
798
|
-
if (liveTypeVarScopes) {
|
799
|
-
typeArgValue = (0, typeUtils_1.transformExpectedType)(typeArgValue, liveTypeVarScopes, usageOffset);
|
800
|
-
}
|
801
|
-
if (typeArgValue) {
|
802
|
-
const variance = types_1.TypeVarType.getVariance(typeVar);
|
803
|
-
// If this type variable already has a type, don't overwrite it. This can
|
804
|
-
// happen if a single type variable in the derived class is used multiple times
|
805
|
-
// in the specialized base class type (e.g. Mapping[T, T]).
|
806
|
-
if (typeVarContext.getPrimarySignature().getTypeVarType(targetTypeVar)) {
|
807
|
-
isResultValid = false;
|
808
|
-
typeArgValue = types_1.UnknownType.create();
|
809
|
-
}
|
810
|
-
updateTypeVarType(evaluator, typeVarContext, targetTypeVar, variance === 3 /* Variance.Covariant */ ? undefined : typeArgValue, variance === 4 /* Variance.Contravariant */ ? undefined : typeArgValue);
|
811
|
-
}
|
812
|
-
else {
|
813
|
-
isResultValid = false;
|
814
|
-
}
|
815
|
-
}
|
816
|
-
}
|
817
|
-
});
|
818
|
-
return isResultValid;
|
874
|
+
return undefined;
|
819
875
|
}
|
820
|
-
return false;
|
821
876
|
}
|
822
|
-
|
877
|
+
function applyUnificationVarsToType(evaluator, type, constraintSet) {
|
878
|
+
const transformer = new UnificationVarTransformer(evaluator, constraintSet);
|
879
|
+
return transformer.apply(type, 0);
|
880
|
+
}
|
823
881
|
// For normal TypeVars, the constraint solver can widen a type by combining
|
824
882
|
// two otherwise incompatible types into a union. For TypeVarTuples, we need
|
825
883
|
// to do the equivalent operation for unpacked tuples.
|
826
|
-
function
|
884
|
+
function widenTypeForTypeVarTuple(evaluator, type1, type2) {
|
827
885
|
// The typing spec indicates that the type should always be "exactly
|
828
886
|
// the same type" if a TypeVarTuple is used in multiple locations.
|
829
887
|
// This is problematic for a number of reasons, but in the interest
|
@@ -833,9 +891,9 @@ function widenTypeForVariadicTypeVar(evaluator, type1, type2) {
|
|
833
891
|
return undefined;
|
834
892
|
}
|
835
893
|
// If the two unpacked tuples are not the same length, we can't combine them.
|
836
|
-
if (!type1.priv.
|
837
|
-
!type2.priv.
|
838
|
-
type1.priv.
|
894
|
+
if (!type1.priv.tupleTypeArgs ||
|
895
|
+
!type2.priv.tupleTypeArgs ||
|
896
|
+
type1.priv.tupleTypeArgs.length !== type2.priv.tupleTypeArgs.length) {
|
839
897
|
return undefined;
|
840
898
|
}
|
841
899
|
const strippedType1 = stripLiteralValueForUnpackedTuple(evaluator, type1);
|
@@ -848,11 +906,11 @@ function widenTypeForVariadicTypeVar(evaluator, type1, type2) {
|
|
848
906
|
// If the provided type is an unpacked tuple, this function strips the
|
849
907
|
// literals from types of the corresponding elements.
|
850
908
|
function stripLiteralValueForUnpackedTuple(evaluator, type) {
|
851
|
-
if (!(0, types_1.isUnpackedClass)(type) || !type.priv.
|
909
|
+
if (!(0, types_1.isUnpackedClass)(type) || !type.priv.tupleTypeArgs) {
|
852
910
|
return type;
|
853
911
|
}
|
854
912
|
let strippedLiteral = false;
|
855
|
-
const tupleTypeArgs = type.priv.
|
913
|
+
const tupleTypeArgs = type.priv.tupleTypeArgs.map((arg) => {
|
856
914
|
const strippedType = evaluator.stripLiteralValue(arg.type);
|
857
915
|
if (strippedType !== arg.type) {
|
858
916
|
strippedLiteral = true;
|
@@ -866,44 +924,44 @@ function stripLiteralValueForUnpackedTuple(evaluator, type) {
|
|
866
924
|
if (!strippedLiteral) {
|
867
925
|
return type;
|
868
926
|
}
|
869
|
-
return (0, typeUtils_1.specializeTupleClass)(type, tupleTypeArgs, /*
|
927
|
+
return (0, typeUtils_1.specializeTupleClass)(type, tupleTypeArgs, /* isTypeArgExplicit */ true, /* isUnpackedTuple */ true);
|
870
928
|
}
|
871
929
|
// This function is used for debugging only. It dumps the current contents of
|
872
|
-
// the
|
873
|
-
function
|
874
|
-
const
|
875
|
-
if (
|
930
|
+
// the constraints to the console.
|
931
|
+
function logConstraints(evaluator, constraints, indent) {
|
932
|
+
const constraintSetCount = constraints.getConstraintSets().length;
|
933
|
+
if (constraintSetCount === 0) {
|
876
934
|
console.log(`${indent} no signatures`);
|
877
935
|
}
|
878
|
-
else if (
|
879
|
-
|
936
|
+
else if (constraintSetCount === 1) {
|
937
|
+
logTypeVarConstraintSet(evaluator, constraints.getConstraintSets()[0], `${indent} `);
|
880
938
|
}
|
881
939
|
else {
|
882
|
-
|
883
|
-
console.log(`${indent} signature ${
|
884
|
-
|
940
|
+
constraints.doForEachConstraintSet((set, index) => {
|
941
|
+
console.log(`${indent} signature ${index}`);
|
942
|
+
logTypeVarConstraintSet(evaluator, set, `${indent} `);
|
885
943
|
});
|
886
944
|
}
|
887
945
|
}
|
888
|
-
function
|
946
|
+
function logTypeVarConstraintSet(evaluator, context, indent) {
|
889
947
|
let loggedConstraint = false;
|
890
948
|
context.getTypeVars().forEach((entry) => {
|
891
949
|
var _a;
|
892
950
|
const typeVarName = `${indent}${entry.typeVar.shared.name}`;
|
893
|
-
const
|
894
|
-
const
|
895
|
-
// Log the
|
896
|
-
if (
|
897
|
-
console.log(`${typeVarName} = ${evaluator.printType(
|
951
|
+
const lowerBound = (_a = entry.lowerBoundNoLiterals) !== null && _a !== void 0 ? _a : entry.lowerBound;
|
952
|
+
const upperBound = entry.upperBound;
|
953
|
+
// Log the lower and upper bounds.
|
954
|
+
if (lowerBound && upperBound && (0, types_1.isTypeSame)(lowerBound, upperBound)) {
|
955
|
+
console.log(`${typeVarName} = ${evaluator.printType(lowerBound)}`);
|
898
956
|
loggedConstraint = true;
|
899
957
|
}
|
900
958
|
else {
|
901
|
-
if (
|
902
|
-
console.log(`${typeVarName} ≤ ${evaluator.printType(
|
959
|
+
if (lowerBound) {
|
960
|
+
console.log(`${typeVarName} ≤ ${evaluator.printType(lowerBound)}`);
|
903
961
|
loggedConstraint = true;
|
904
962
|
}
|
905
|
-
if (
|
906
|
-
console.log(`${typeVarName} ≥ ${evaluator.printType(
|
963
|
+
if (upperBound) {
|
964
|
+
console.log(`${typeVarName} ≥ ${evaluator.printType(upperBound)}`);
|
907
965
|
loggedConstraint = true;
|
908
966
|
}
|
909
967
|
}
|