[ConstraintSystem] Record holes in the constraint system using a new flag in

`TypeVariableOptions` rather than using a separate data structure in the
constraint system.
This commit is contained in:
Holly Borla
2019-11-11 14:41:54 -08:00
parent ea1a46c84d
commit c0312b9c0e
10 changed files with 65 additions and 72 deletions

View File

@@ -867,9 +867,7 @@ public:
auto *argType =
CS.createTypeVariable(argLoc, TVO_CanBindToInOut | TVO_CanBindToLValue |
TVO_CanBindToNoEscape);
CS.recordPotentialHole(argType);
TVO_CanBindToNoEscape | TVO_CanBindToHole);
Arguments.push_back(param.withType(argType));
++NumSynthesizedArgs;
@@ -4954,6 +4952,12 @@ ConstraintSystem::simplifyFunctionComponentConstraint(
// Track how many times we do this so that we can record a fix for each.
++unwrapCount;
}
if (simplified->isHole()) {
if (auto *typeVar = second->getAs<TypeVariableType>())
recordPotentialHole(typeVar);
return SolutionKind::Solved;
}
}
if (simplified->isTypeVariableOrMember()) {
@@ -6743,9 +6747,12 @@ ConstraintSystem::simplifyKeyPathConstraint(
}
if (shouldAttemptFixes()) {
auto *componentLoc = getConstraintLocator(
keyPath, {LocatorPathElt::KeyPathComponent(i),
LocatorPathElt::KeyPathComponentResult()});
auto typeVar =
llvm::find_if(componentTypeVars, [&](TypeVariableType *typeVar) {
auto *locator = typeVar->getImpl().getLocator();
auto elt = locator->findLast<LocatorPathElt::KeyPathComponent>();
return elt && elt->getIndex() == i;
});
// If one of the components haven't been resolved, let's check
// whether it has been determined to be a "hole" and if so,
@@ -6753,7 +6760,8 @@ ConstraintSystem::simplifyKeyPathConstraint(
//
// This helps to, for example, diagnose problems with missing
// members used as part of a key path.
if (isPotentialHoleAt(componentLoc)) {
if (typeVar != componentTypeVars.end() &&
(*typeVar)->getImpl().canBindToHole()) {
anyComponentsUnresolved = true;
capability = ReadOnly;
continue;
@@ -7152,25 +7160,6 @@ ConstraintSystem::simplifyApplicableFnConstraint(
// following: $T1 -> $T2.
auto func1 = type1->castTo<FunctionType>();
// Let's check if this member couldn't be found and is fixed
// to exist based on its usage.
if (auto *memberTy = type2->getAs<TypeVariableType>()) {
if (isPotentialHole(memberTy)) {
auto *funcTy = type1->castTo<FunctionType>();
auto *locator = memberTy->getImpl().getLocator();
// Bind type variable associated with member to a type of argument
// application, which makes it seem like member exists with the
// types of the parameters matching argument types exactly.
addConstraint(ConstraintKind::Bind, memberTy, funcTy, locator);
// There might be no contextual type for result of the application,
// in cases like `let _ = x.foo()`, so let's record a potential hole.
auto resultTy = funcTy->getResult();
if (auto *typeVar = resultTy->getAs<TypeVariableType>())
recordPotentialHole(typeVar);
return SolutionKind::Solved;
}
}
// Before stripping lvalue-ness and optional types, save the original second
// type for handling `func callAsFunction` and `@dynamicCallable`
// applications. This supports the following cases:
@@ -8184,7 +8173,7 @@ bool ConstraintSystem::recordFix(ConstraintFix *fix, unsigned impact) {
void ConstraintSystem::recordPotentialHole(TypeVariableType *typeVar) {
assert(typeVar);
Holes.insert(typeVar->getImpl().getLocator());
typeVar->getImpl().enableCanBindToHole(getSavedBindings());
}
ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(