Skip to content

Commit 4917d43

Browse files
committed
[ConstraintSystem] Use new ConformanceRequirement to record checked conformances and conditional requirements
1 parent dbfeb5e commit 4917d43

File tree

4 files changed

+43
-41
lines changed

4 files changed

+43
-41
lines changed

lib/Sema/CSApply.cpp

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7971,10 +7971,12 @@ static Optional<SolutionApplicationTarget> applySolutionToForEachStmt(
79717971
auto stmt = forEachStmtInfo.stmt;
79727972
auto sequenceProto = TypeChecker::getProtocol(
79737973
cs.getASTContext(), stmt->getForLoc(), KnownProtocolKind::Sequence);
7974-
auto contextualLocator = cs.getConstraintLocator(
7975-
target.getAsExpr(), LocatorPathElt::ContextualType());
7976-
auto sequenceConformance = solution.resolveConformance(
7977-
contextualLocator, sequenceProto);
7974+
auto contextualLocator = solution.getConstraintLocator(
7975+
target.getAsExpr(),
7976+
{LocatorPathElt::ContextualType(),
7977+
LocatorPathElt::ConformanceRequirement(sequenceProto)});
7978+
auto sequenceConformance =
7979+
solution.resolveConformance(contextualLocator, sequenceProto);
79787980
assert(!sequenceConformance.isInvalid() &&
79797981
"Couldn't find sequence conformance");
79807982

@@ -8385,32 +8387,30 @@ Expr *Solution::coerceToType(Expr *expr, Type toType,
83858387

83868388
ProtocolConformanceRef Solution::resolveConformance(
83878389
ConstraintLocator *locator, ProtocolDecl *proto) {
8388-
for (const auto &conformance : Conformances) {
8389-
if (conformance.first != locator)
8390-
continue;
8391-
if (conformance.second.getRequirement() != proto)
8392-
continue;
8393-
8394-
// If the conformance doesn't require substitution, return it immediately.
8395-
auto conformanceRef = conformance.second;
8396-
if (conformanceRef.isAbstract())
8397-
return conformanceRef;
8398-
8399-
auto concrete = conformanceRef.getConcrete();
8400-
auto conformingType = concrete->getType();
8401-
if (!conformingType->hasTypeVariable())
8402-
return conformanceRef;
8403-
8404-
// Substitute into the conformance type, then look for a conformance
8405-
// again.
8406-
// FIXME: Should be able to perform the substitution using the Solution
8407-
// itself rather than another conforms-to-protocol check.
8408-
Type substConformingType = simplifyType(conformingType);
8409-
return TypeChecker::conformsToProtocol(
8410-
substConformingType, proto, constraintSystem->DC);
8411-
}
8412-
8413-
return ProtocolConformanceRef::forInvalid();
8390+
auto conformance = llvm::find_if(Conformances, [&locator](const auto &elt) {
8391+
return elt.first == locator;
8392+
});
8393+
8394+
if (conformance == Conformances.end())
8395+
return ProtocolConformanceRef::forInvalid();
8396+
8397+
// If the conformance doesn't require substitution, return it immediately.
8398+
auto conformanceRef = conformance->second;
8399+
if (conformanceRef.isAbstract())
8400+
return conformanceRef;
8401+
8402+
auto concrete = conformanceRef.getConcrete();
8403+
auto conformingType = concrete->getType();
8404+
if (!conformingType->hasTypeVariable())
8405+
return conformanceRef;
8406+
8407+
// Substitute into the conformance type, then look for a conformance
8408+
// again.
8409+
// FIXME: Should be able to perform the substitution using the Solution
8410+
// itself rather than another conforms-to-protocol check.
8411+
Type substConformingType = simplifyType(conformingType);
8412+
return TypeChecker::conformsToProtocol(substConformingType, proto,
8413+
constraintSystem->DC);
84148414
}
84158415

84168416
bool Solution::hasType(ASTNode node) const {

lib/Sema/CSDiagnostics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,12 @@ ProtocolConformance *RequirementFailure::getConformanceForConditionalReq(
211211
return nullptr;
212212

213213
auto path = locator->getPath();
214-
auto *typeReqLoc = getConstraintLocator(getRawAnchor(), path.drop_back());
214+
auto *conformanceLoc = getConstraintLocator(getRawAnchor(), path.drop_back());
215215

216216
auto result = llvm::find_if(
217217
solution.Conformances,
218218
[&](const std::pair<ConstraintLocator *, ProtocolConformanceRef>
219-
&conformance) { return conformance.first == typeReqLoc; });
219+
&conformance) { return conformance.first == conformanceLoc; });
220220
assert(result != solution.Conformances.end());
221221

222222
auto conformance = result->second;

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5710,21 +5710,23 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
57105710
/// Record the given conformance as the result, adding any conditional
57115711
/// requirements if necessary.
57125712
auto recordConformance = [&](ProtocolConformanceRef conformance) {
5713+
auto *conformanceLoc = getConstraintLocator(
5714+
loc, LocatorPathElt::ConformanceRequirement(protocol));
57135715
// Record the conformance.
5714-
CheckedConformances.push_back({loc, conformance});
5716+
CheckedConformances.push_back({conformanceLoc, conformance});
57155717

5716-
if (isConformanceUnavailable(conformance, loc))
5718+
if (isConformanceUnavailable(conformance, conformanceLoc))
57175719
increaseScore(SK_Unavailable);
57185720

57195721
// This conformance may be conditional, in which case we need to consider
57205722
// those requirements as constraints too.
57215723
if (conformance.isConcrete()) {
57225724
unsigned index = 0;
57235725
for (const auto &req : conformance.getConditionalRequirements()) {
5724-
addConstraint(req,
5725-
locator.withPathElement(
5726-
LocatorPathElt::ConditionalRequirement(
5727-
index++, req.getKind())));
5726+
addConstraint(
5727+
req, getConstraintLocator(conformanceLoc,
5728+
LocatorPathElt::ConditionalRequirement(
5729+
index++, req.getKind())));
57285730
}
57295731
}
57305732

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5180,15 +5180,15 @@ static Optional<Requirement> getRequirement(ConstraintSystem &cs,
51805180

51815181
if (reqLoc->isConditionalRequirement()) {
51825182
auto path = reqLocator->getPath();
5183-
auto *typeReqLoc =
5183+
auto *conformanceLoc =
51845184
cs.getConstraintLocator(reqLocator->getAnchor(), path.drop_back());
51855185

51865186
auto conformances = cs.getCheckedConformances();
51875187
auto result = llvm::find_if(
51885188
conformances,
5189-
[&typeReqLoc](
5189+
[&conformanceLoc](
51905190
const std::pair<ConstraintLocator *, ProtocolConformanceRef>
5191-
&conformance) { return conformance.first == typeReqLoc; });
5191+
&conformance) { return conformance.first == conformanceLoc; });
51925192
assert(result != conformances.end());
51935193

51945194
auto conformance = result->second;

0 commit comments

Comments
 (0)