mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CS] Use subclasses to expose locator element info
Instead of adding specific accessors directly to ConstraintLocator::PathElement, add subclasses that expose these accessors.
This commit is contained in:
@@ -763,13 +763,17 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
|
||||
isa<CallExpr>(callExpr) ? cast<CallExpr>(callExpr)->getDirectCallee()
|
||||
: callExpr);
|
||||
} else if (auto keyPath = dyn_cast<KeyPathExpr>(callExpr)) {
|
||||
if (path.size() != 2 ||
|
||||
path[0].getKind() != ConstraintLocator::KeyPathComponent ||
|
||||
path[1].getKind() != ConstraintLocator::ApplyArgument)
|
||||
if (path.size() != 2)
|
||||
return std::make_tuple(nullptr, /*hasAppliedSelf=*/false, argLabels,
|
||||
hasTrailingClosure, nullptr);
|
||||
|
||||
auto componentIndex = path[0].getKeyPathComponentIdx();
|
||||
// We must have a KeyPathComponent followed by an ApplyArgument.
|
||||
auto componentElt = path[0].getAs<LocatorPathElt::KeyPathComponent>();
|
||||
if (!componentElt || path[1].getKind() != ConstraintLocator::ApplyArgument)
|
||||
return std::make_tuple(nullptr, /*hasAppliedSelf=*/false, argLabels,
|
||||
hasTrailingClosure, nullptr);
|
||||
|
||||
auto componentIndex = componentElt->getIndex();
|
||||
if (componentIndex >= keyPath->getComponents().size())
|
||||
return std::make_tuple(nullptr, /*hasAppliedSelf=*/false, argLabels,
|
||||
hasTrailingClosure, nullptr);
|
||||
@@ -1006,9 +1010,8 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
|
||||
|
||||
// Compare each of the bound arguments for this parameter.
|
||||
for (auto argIdx : parameterBindings[paramIdx]) {
|
||||
auto loc = locator.withPathElement(LocatorPathElt::
|
||||
getApplyArgToParam(argIdx,
|
||||
paramIdx));
|
||||
auto loc = locator.withPathElement(
|
||||
LocatorPathElt::ApplyArgToParam(argIdx, paramIdx));
|
||||
auto argTy = argsWithLabels[argIdx].getOldType();
|
||||
|
||||
bool matchingAutoClosureResult = param.isAutoClosure();
|
||||
@@ -1103,7 +1106,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
|
||||
// Compare the element types.
|
||||
auto result = matchTypes(elt1.getType(), elt2.getType(), kind, subflags,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getTupleElement(i)));
|
||||
LocatorPathElt::TupleElement(i)));
|
||||
if (result.isFailure())
|
||||
return result;
|
||||
}
|
||||
@@ -1164,7 +1167,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
|
||||
const auto &elt2 = tuple2->getElement(idx2);
|
||||
auto result = matchTypes(elt1.getType(), elt2.getType(), subKind, subflags,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getTupleElement(idx1)));
|
||||
LocatorPathElt::TupleElement(idx1)));
|
||||
if (result.isFailure())
|
||||
return result;
|
||||
}
|
||||
@@ -1293,7 +1296,7 @@ static bool fixMissingArguments(ConstraintSystem &cs, Expr *anchor,
|
||||
|
||||
for (unsigned i = args.size(), n = params.size(); i != n; ++i) {
|
||||
auto *argLoc = cs.getConstraintLocator(
|
||||
anchor, LocatorPathElt::getSynthesizedArgument(i));
|
||||
anchor, LocatorPathElt::SynthesizedArgument(i));
|
||||
args.push_back(params[i].withType(cs.createTypeVariable(argLoc,
|
||||
TVO_CanBindToNoEscape)));
|
||||
}
|
||||
@@ -1441,7 +1444,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
|
||||
// arguments, this makes it easier to diagnose cases where we attempt
|
||||
// a single tuple element formed when no arguments were present.
|
||||
auto argLoc = argumentLocator.withPathElement(
|
||||
LocatorPathElt::getSynthesizedArgument(0));
|
||||
LocatorPathElt::SynthesizedArgument(0));
|
||||
auto *typeVar = createTypeVariable(getConstraintLocator(argLoc),
|
||||
TVO_CanBindToNoEscape);
|
||||
params.emplace_back(typeVar);
|
||||
@@ -1582,7 +1585,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
|
||||
(func1Params.size() == 1
|
||||
? argumentLocator
|
||||
: argumentLocator.withPathElement(
|
||||
LocatorPathElt::getTupleElement(i))));
|
||||
LocatorPathElt::TupleElement(i))));
|
||||
if (result.isFailure())
|
||||
return result;
|
||||
}
|
||||
@@ -1638,7 +1641,7 @@ static ConstraintSystem::TypeMatchResult matchDeepTypeArguments(
|
||||
for (unsigned i = 0, n = args1.size(); i != n; ++i) {
|
||||
auto result = cs.matchTypes(
|
||||
args1[i], args2[i], ConstraintKind::Bind, subflags,
|
||||
locator.withPathElement(LocatorPathElt::getGenericArgument(i)));
|
||||
locator.withPathElement(LocatorPathElt::GenericArgument(i)));
|
||||
|
||||
if (result.isFailure()) {
|
||||
recordMismatch(i);
|
||||
@@ -1747,8 +1750,7 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2,
|
||||
if (shouldAttemptFixes()) {
|
||||
bool forRequirement = false;
|
||||
if (auto last = locator.last()) {
|
||||
forRequirement = last->isTypeParameterRequirement() ||
|
||||
last->isConditionalRequirement();
|
||||
forRequirement = last->is<LocatorPathElt::AnyRequirement>();
|
||||
}
|
||||
|
||||
// Optionals and arrays have a lot of special diagnostics and only one
|
||||
@@ -2092,7 +2094,7 @@ static ConstraintFix *fixRequirementFailure(ConstraintSystem &cs, Type type1,
|
||||
if (type1->isTypeVariableOrMember() || type2->isTypeVariableOrMember())
|
||||
return nullptr;
|
||||
|
||||
auto req = path.back();
|
||||
auto req = path.back().castTo<LocatorPathElt::AnyRequirement>();
|
||||
if (req.isConditionalRequirement()) {
|
||||
// path is - ... -> open generic -> type req # -> cond req #,
|
||||
// to identify type requirement we only need `open generic -> type req #`
|
||||
@@ -2451,7 +2453,7 @@ bool ConstraintSystem::repairFailures(
|
||||
|
||||
case ConstraintLocator::FunctionArgument: {
|
||||
auto *argLoc = getConstraintLocator(
|
||||
locator.withPathElement(LocatorPathElt::getSynthesizedArgument(0)));
|
||||
locator.withPathElement(LocatorPathElt::SynthesizedArgument(0)));
|
||||
|
||||
// Let's drop the last element which points to a single argument
|
||||
// and see if this is a contextual mismatch.
|
||||
@@ -2501,7 +2503,8 @@ bool ConstraintSystem::repairFailures(
|
||||
if (lhs->hasDependentMember() || rhs->hasDependentMember())
|
||||
break;
|
||||
|
||||
auto reqKind = static_cast<RequirementKind>(elt.getValue2());
|
||||
auto reqElt = elt.castTo<LocatorPathElt::AnyRequirement>();
|
||||
auto reqKind = reqElt.getRequirementKind();
|
||||
if (hasFixedRequirement(lhs, reqKind, rhs))
|
||||
return true;
|
||||
|
||||
@@ -3716,7 +3719,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
|
||||
for (const auto &req : conformance.getConditionalRequirements()) {
|
||||
addConstraint(req,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getConditionalRequirementComponent(
|
||||
LocatorPathElt::ConditionalRequirement(
|
||||
index++, req.getKind())));
|
||||
}
|
||||
}
|
||||
@@ -3763,8 +3766,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
|
||||
// optional doesn't; suggest forcing if that's the case.
|
||||
auto result = simplifyConformsToConstraint(
|
||||
optionalObjectType, protocol, kind,
|
||||
locator.withPathElement(LocatorPathElt::getGenericArgument(0)),
|
||||
subflags);
|
||||
locator.withPathElement(LocatorPathElt::GenericArgument(0)), subflags);
|
||||
if (result == SolutionKind::Solved) {
|
||||
auto *fix = ForceOptional::create(*this, type, optionalObjectType,
|
||||
getConstraintLocator(locator));
|
||||
@@ -3795,8 +3797,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
|
||||
if (path.empty())
|
||||
return SolutionKind::Error;
|
||||
|
||||
if (path.back().isTypeParameterRequirement() ||
|
||||
path.back().isConditionalRequirement()) {
|
||||
if (path.back().is<LocatorPathElt::AnyRequirement>()) {
|
||||
if (auto *fix =
|
||||
fixRequirementFailure(*this, type, protocolTy, anchor, path)) {
|
||||
if (!recordFix(fix)) {
|
||||
@@ -4519,7 +4520,8 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
|
||||
// double check here that given keypath is appropriate for it.
|
||||
if (memberLocator && memberLocator->isForKeyPathDynamicMemberLookup()) {
|
||||
auto path = memberLocator->getPath();
|
||||
auto *keyPath = path.back().getKeyPath();
|
||||
auto kpElt = path.back().castTo<LocatorPathElt::KeyPathDynamicMember>();
|
||||
auto *keyPath = kpElt.getKeyPathDecl();
|
||||
if (auto *storage = dyn_cast<AbstractStorageDecl>(decl)) {
|
||||
// If this is an attempt to access read-only member via
|
||||
// writable key path, let's fail this choice early.
|
||||
@@ -5492,9 +5494,8 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
|
||||
// [AnyObject]
|
||||
addConstraint(ConstraintKind::Bind, fromBGT->getGenericArgs()[0],
|
||||
TC.Context.getAnyObjectType(),
|
||||
getConstraintLocator(
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getGenericArgument(0))));
|
||||
getConstraintLocator(locator.withPathElement(
|
||||
LocatorPathElt::GenericArgument(0))));
|
||||
} else if (fromBGT->getDecl() == TC.Context.getDictionaryDecl()) {
|
||||
// [NSObject : AnyObject]
|
||||
auto NSObjectType = TC.getNSObjectType(DC);
|
||||
@@ -5507,13 +5508,13 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
|
||||
NSObjectType,
|
||||
getConstraintLocator(
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getGenericArgument(0))));
|
||||
LocatorPathElt::GenericArgument(0))));
|
||||
|
||||
addConstraint(ConstraintKind::Bind, fromBGT->getGenericArgs()[1],
|
||||
TC.Context.getAnyObjectType(),
|
||||
getConstraintLocator(
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getGenericArgument(1))));
|
||||
LocatorPathElt::GenericArgument(1))));
|
||||
} else if (fromBGT->getDecl() == TC.Context.getSetDecl()) {
|
||||
auto NSObjectType = TC.getNSObjectType(DC);
|
||||
if (!NSObjectType) {
|
||||
@@ -5524,7 +5525,7 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
|
||||
NSObjectType,
|
||||
getConstraintLocator(
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getGenericArgument(0))));
|
||||
LocatorPathElt::GenericArgument(0))));
|
||||
} else {
|
||||
// Nothing special to do; matchTypes will match generic arguments.
|
||||
}
|
||||
@@ -5546,9 +5547,8 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
|
||||
if (auto toElement = isArrayType(unwrappedToType)) {
|
||||
countOptionalInjections();
|
||||
return simplifyBridgingConstraint(
|
||||
*fromElement, *toElement, subflags,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getGenericArgument(0)));
|
||||
*fromElement, *toElement, subflags,
|
||||
locator.withPathElement(LocatorPathElt::GenericArgument(0)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5558,11 +5558,11 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
|
||||
addExplicitConversionConstraint(fromKeyValue->first, toKeyValue->first,
|
||||
/*allowFixes=*/false,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getGenericArgument(0)));
|
||||
LocatorPathElt::GenericArgument(0)));
|
||||
addExplicitConversionConstraint(fromKeyValue->second, toKeyValue->second,
|
||||
/*allowFixes=*/false,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getGenericArgument(0)));
|
||||
LocatorPathElt::GenericArgument(0)));
|
||||
countOptionalInjections();
|
||||
return SolutionKind::Solved;
|
||||
}
|
||||
@@ -5573,9 +5573,8 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
|
||||
if (auto toElement = isSetType(unwrappedToType)) {
|
||||
countOptionalInjections();
|
||||
return simplifyBridgingConstraint(
|
||||
*fromElement, *toElement, subflags,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getGenericArgument(0)));
|
||||
*fromElement, *toElement, subflags,
|
||||
locator.withPathElement(LocatorPathElt::GenericArgument(0)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5688,11 +5687,12 @@ ConstraintSystem::simplifyKeyPathConstraint(Type keyPathTy,
|
||||
for (auto resolvedItem = resolvedOverloadSets; resolvedItem;
|
||||
resolvedItem = resolvedItem->Previous) {
|
||||
auto locator = resolvedItem->Locator;
|
||||
if (locator->getAnchor() == keyPath
|
||||
&& locator->getPath().size() <= 2
|
||||
&& locator->getPath()[0].getKind() == ConstraintLocator::KeyPathComponent) {
|
||||
auto idx = locator->getPath()[0].getKeyPathComponentIdx();
|
||||
choices[idx] = resolvedItem->Choice;
|
||||
auto path = locator->getPath();
|
||||
if (locator->getAnchor() != keyPath || path.size() > 2)
|
||||
continue;
|
||||
|
||||
if (auto kpElt = path[0].getAs<LocatorPathElt::KeyPathComponent>()) {
|
||||
choices[kpElt->getIndex()] = resolvedItem->Choice;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5804,7 +5804,7 @@ ConstraintSystem::simplifyKeyPathConstraint(Type keyPathTy,
|
||||
auto storage = dyn_cast<AbstractStorageDecl>(choices[i].getDecl());
|
||||
|
||||
auto *componentLoc = getConstraintLocator(
|
||||
locator.withPathElement(LocatorPathElt::getKeyPathComponent(i)));
|
||||
locator.withPathElement(LocatorPathElt::KeyPathComponent(i)));
|
||||
|
||||
if (auto *fix = AllowInvalidRefInKeyPath::forRef(
|
||||
*this, choices[i].getDecl(), componentLoc)) {
|
||||
@@ -6626,7 +6626,7 @@ ConstraintSystem::simplifyDynamicCallableApplicableFnConstraint(
|
||||
auto param = func1->getParams()[i];
|
||||
auto paramType = param.getPlainType();
|
||||
auto locatorBuilder =
|
||||
locator.withPathElement(LocatorPathElt::getTupleElement(i));
|
||||
locator.withPathElement(LocatorPathElt::TupleElement(i));
|
||||
addConstraint(ConstraintKind::ArgumentConversion, paramType,
|
||||
argumentType, locatorBuilder);
|
||||
}
|
||||
@@ -6769,7 +6769,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
|
||||
generic2->getGenericArgs()[0],
|
||||
matchKind, subflags,
|
||||
locator.withPathElement(
|
||||
LocatorPathElt::getGenericArgument(0)));
|
||||
LocatorPathElt::GenericArgument(0)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6899,7 +6899,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
|
||||
matchKind,
|
||||
subflags,
|
||||
locator.withPathElement(
|
||||
ConstraintLocator::PathElement::getGenericArgument(0)));
|
||||
LocatorPathElt::GenericArgument(0)));
|
||||
}
|
||||
|
||||
// K1 < K2 && V1 < V2 || K1 bridges to K2 && V1 bridges to V2 ===>
|
||||
@@ -6917,15 +6917,15 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
|
||||
increaseScore(SK_CollectionUpcastConversion);
|
||||
// The source key and value types must be subtypes of the destination
|
||||
// key and value types, respectively.
|
||||
auto result = matchTypes(key1, key2, subMatchKind, subflags,
|
||||
locator.withPathElement(
|
||||
ConstraintLocator::PathElement::getGenericArgument(0)));
|
||||
auto result =
|
||||
matchTypes(key1, key2, subMatchKind, subflags,
|
||||
locator.withPathElement(LocatorPathElt::GenericArgument(0)));
|
||||
if (result.isFailure())
|
||||
return result;
|
||||
|
||||
switch (matchTypes(value1, value2, subMatchKind, subflags,
|
||||
locator.withPathElement(
|
||||
ConstraintLocator::PathElement::getGenericArgument(1)))) {
|
||||
switch (matchTypes(
|
||||
value1, value2, subMatchKind, subflags,
|
||||
locator.withPathElement(LocatorPathElt::GenericArgument(1)))) {
|
||||
case SolutionKind::Solved:
|
||||
return result;
|
||||
|
||||
@@ -6947,8 +6947,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
|
||||
baseType2,
|
||||
matchKind,
|
||||
subflags,
|
||||
locator.withPathElement(
|
||||
ConstraintLocator::PathElement::getGenericArgument(0)));
|
||||
locator.withPathElement(LocatorPathElt::GenericArgument(0)));
|
||||
}
|
||||
|
||||
// T1 <c T2 && T2 : Hashable ===> T1 <c AnyHashable
|
||||
|
||||
Reference in New Issue
Block a user