Simplified code in the typeVarContext module.

This commit is contained in:
Eric Traut 2024-06-02 19:31:54 -07:00
parent 409df8ff72
commit a572c05b26
6 changed files with 14 additions and 69 deletions

View File

@ -75,9 +75,7 @@ const logTypeVarContextUpdates = false;
// Assigns the source type to the dest type var in the type var context. If an existing
// type is already associated with that type var name, it attempts to either widen or
// narrow the type (depending on the value of the isContravariant parameter). The goal is
// to produce the narrowest type that meets all of the requirements. If the type var context
// has been "locked", it simply validates that the srcType is compatible (with no attempt
// to widen or narrow).
// to produce the narrowest type that meets all of the requirements.
export function assignTypeToTypeVar(
evaluator: TypeEvaluator,
destType: TypeVarType,
@ -445,16 +443,6 @@ export function assignTypeToTypeVar(
// source type.
newNarrowTypeBound = adjSrcType;
} else {
// We need to widen the type.
if (typeVarContext.isLocked()) {
diag?.addMessage(
LocAddendum.typeAssignmentMismatch().format(
evaluator.printSrcDestTypes(adjSrcType, curNarrowTypeBound)
)
);
return false;
}
if (
evaluator.assignType(
adjSrcType,
@ -615,7 +603,7 @@ export function assignTypeToTypeVar(
}
}
if (!typeVarContext.isLocked() && isTypeVarInScope) {
if (isTypeVarInScope) {
updateTypeVarType(
evaluator,
typeVarContext,
@ -850,7 +838,7 @@ function assignTypeToConstrainedTypeVar(
recursionCount
)
) {
if (!typeVarContext.isLocked() && isTypeVarInScope) {
if (isTypeVarInScope) {
updateTypeVarType(evaluator, typeVarContext, destType, constrainedType, curWideTypeBound);
}
} else {
@ -865,7 +853,7 @@ function assignTypeToConstrainedTypeVar(
}
} else {
// Assign the type to the type var.
if (!typeVarContext.isLocked() && isTypeVarInScope) {
if (isTypeVarInScope) {
updateTypeVarType(
evaluator,
typeVarContext,
@ -902,7 +890,7 @@ function assignTypeToParamSpec(
}
}
} else {
if (!typeVarContext.isLocked() && typeVarContext.hasSolveForScope(destType.scopeId)) {
if (typeVarContext.hasSolveForScope(destType.scopeId)) {
signatureContext.setTypeVarType(destType, convertTypeToParamSpecValue(srcType));
}
return;
@ -991,7 +979,7 @@ function assignTypeToParamSpec(
}
if (updateContextWithNewFunction) {
if (!typeVarContext.isLocked() && typeVarContext.hasSolveForScope(destType.scopeId)) {
if (typeVarContext.hasSolveForScope(destType.scopeId)) {
signatureContext.setTypeVarType(destType, newFunction);
}
return;

View File

@ -449,7 +449,6 @@ function validateNewMethod(
argumentErrors = true;
// Evaluate the arguments in a non-speculative manner to generate any diagnostics.
typeVarContext.unlock();
evaluator.validateCallArguments(
errorNode,
argList,

View File

@ -738,7 +738,7 @@ function assignClassToProtocolInternal(
) {
typesAreConsistent = false;
}
} else if (destTypeVarContext && !destTypeVarContext.isLocked()) {
} else if (destTypeVarContext) {
for (const typeParam of destType.details.typeParameters) {
const typeArgEntry = protocolTypeVarContext.getPrimarySignature().getTypeVar(typeParam);

View File

@ -8714,7 +8714,6 @@ export function createTypeEvaluator(
const effectiveTypeVarContext =
typeVarContext?.clone() ?? new TypeVarContext(getTypeVarScopeId(overload));
effectiveTypeVarContext.addSolveForScope(getTypeVarScopeIds(overload));
effectiveTypeVarContext.unlock();
// Use speculative mode so we don't output any diagnostics or
// record any final types in the type cache.
@ -8847,7 +8846,6 @@ export function createTypeEvaluator(
// And run through the first expanded argument list one more time to
// populate the type cache.
const finalTypeVarContext = typeVarContext ?? matchedOverloads[0].typeVarContext;
finalTypeVarContext.unlock();
finalTypeVarContext.addSolveForScope(getTypeVarScopeId(matchedOverloads[0].overload));
const finalCallResult = validateFunctionArgumentTypesWithContext(
errorNode,
@ -9109,7 +9107,6 @@ export function createTypeEvaluator(
const effectiveTypeVarContext = typeVarContext ?? new TypeVarContext();
effectiveTypeVarContext.addSolveForScope(getTypeVarScopeIds(bestMatch.overload));
effectiveTypeVarContext.unlock();
return validateFunctionArgumentTypesWithContext(
errorNode,
@ -11513,10 +11510,6 @@ export function createTypeEvaluator(
});
});
}
// Lock the type var map so it cannot be modified when revalidating
// the arguments in a second pass.
typeVarContext.lock();
}
let sawParamSpecArgs = false;
@ -23076,7 +23069,7 @@ export function createTypeEvaluator(
);
}
if (destTypeVarContext && curSrcType.typeArguments && !destTypeVarContext.isLocked()) {
if (destTypeVarContext && curSrcType.typeArguments) {
// Populate the typeVar map with type arguments of the source.
const srcTypeArgs = curSrcType.typeArguments;
for (let i = 0; i < destType.details.typeParameters.length; i++) {
@ -26905,14 +26898,12 @@ export function createTypeEvaluator(
// contain references to themselves or their subclasses, so if
// we attempt to call assignType, we'll risk infinite recursion.
// Instead, we'll assume it's assignable.
if (!typeVarContext.isLocked()) {
typeVarContext.setTypeVarType(
memberTypeFirstParamType,
TypeBase.isInstantiable(memberTypeFirstParamType)
? convertToInstance(firstParamType)
: firstParamType
);
}
typeVarContext.setTypeVarType(
memberTypeFirstParamType,
TypeBase.isInstantiable(memberTypeFirstParamType)
? convertToInstance(firstParamType)
: firstParamType
);
} else {
const subDiag = diag?.createAddendum();

View File

@ -2075,10 +2075,6 @@ export function setTypeArgumentsRecursive(
}
recursionCount++;
if (typeVarContext.isLocked()) {
return;
}
switch (destType.category) {
case TypeCategory.Union:
doForEachSubtype(destType, (subtype) => {

View File

@ -314,7 +314,6 @@ export class TypeVarContext {
static nextTypeVarContextId = 1;
private _id;
private _solveForScopes: TypeVarScopeId[] | undefined;
private _isLocked = false;
private _signatureContexts: TypeVarSignatureContext[];
constructor(solveForScopes?: TypeVarScopeId[] | TypeVarScopeId) {
@ -338,7 +337,6 @@ export class TypeVarContext {
}
newTypeVarMap._signatureContexts = this._signatureContexts.map((context) => context.clone());
newTypeVarMap._isLocked = this._isLocked;
return newTypeVarMap;
}
@ -366,7 +364,6 @@ export class TypeVarContext {
// Copies a cloned type var context back into this object.
copyFromClone(clone: TypeVarContext) {
this._signatureContexts = clone._signatureContexts.map((context) => context.clone());
this._isLocked = clone._isLocked;
}
// Copy the specified signature contexts into this type var context.
@ -433,21 +430,6 @@ export class TypeVarContext {
}
}
lock() {
// Locks the type var map, preventing any further changes.
assert(!this._isLocked);
this._isLocked = true;
}
unlock() {
// Unlocks the type var map, allowing further changes.
this._isLocked = false;
}
isLocked(): boolean {
return this._isLocked;
}
isEmpty() {
return this._signatureContexts.every((context) => context.isEmpty());
}
@ -459,16 +441,12 @@ export class TypeVarContext {
wideBound?: Type,
tupleTypes?: TupleTypeArgument[]
) {
assert(!this._isLocked);
return this._signatureContexts.forEach((context) => {
context.setTypeVarType(reference, narrowBound, narrowBoundNoLiterals, wideBound, tupleTypes);
});
}
setTupleTypeVar(reference: TypeVarType, tupleTypes: TupleTypeArgument[]) {
assert(!this._isLocked);
return this._signatureContexts.forEach((context) => {
context.setTupleTypeVar(reference, tupleTypes);
});
@ -494,16 +472,9 @@ export class TypeVarContext {
}
doForEachSignatureContext(callback: (signature: TypeVarSignatureContext, signatureIndex: number) => void) {
const wasLocked = this.isLocked();
this.unlock();
this.getSignatureContexts().forEach((signature, signatureIndex) => {
callback(signature, signatureIndex);
});
if (wasLocked) {
this.lock();
}
}
getSignatureContext(index: number) {