Skip to content

Commit 9be16b2

Browse files
committed
[Type checker] Move conformance resolution during application into Solution.
While this doesn't completely use the solution's set of known conformances, it moves the logic for handling the lookup into the right place.
1 parent bbcaf8c commit 9be16b2

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

lib/Sema/CSApply.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ Solution::computeSubstitutions(GenericSignature sig,
8787
return ProtocolConformanceRef(protoType);
8888
}
8989

90+
// FIXME: Retrieve the conformance from the solution itself.
9091
return TypeChecker::conformsToProtocol(replacement, protoType,
9192
getConstraintSystem().DC,
9293
ConformanceCheckFlags::InExpression);
@@ -7345,6 +7346,37 @@ class SetExprTypes : public ASTWalker {
73457346
};
73467347
}
73477348

7349+
ProtocolConformanceRef Solution::resolveConformance(
7350+
ConstraintLocator *locator, ProtocolDecl *proto) {
7351+
for (const auto &conformance : Conformances) {
7352+
if (conformance.first != locator)
7353+
continue;
7354+
if (conformance.second.getRequirement() != proto)
7355+
continue;
7356+
7357+
// If the conformance doesn't require substitution, return it immediately.
7358+
auto conformanceRef = conformance.second;
7359+
if (conformanceRef.isAbstract())
7360+
return conformanceRef;
7361+
7362+
auto concrete = conformanceRef.getConcrete();
7363+
auto conformingType = concrete->getType();
7364+
if (!conformingType->hasTypeVariable())
7365+
return conformanceRef;
7366+
7367+
// Substitute into the conformance type, then look for a conformance
7368+
// again.
7369+
// FIXME: Should be able to perform the substitution using the Solution
7370+
// itself rather than another conforms-to-protocol check.
7371+
Type substConformingType = simplifyType(conformingType);
7372+
return TypeChecker::conformsToProtocol(
7373+
substConformingType, proto, constraintSystem->DC,
7374+
ConformanceCheckFlags::InExpression);
7375+
}
7376+
7377+
return ProtocolConformanceRef::forInvalid();
7378+
}
7379+
73487380
void Solution::setExprTypes(Expr *expr) const {
73497381
if (!expr)
73507382
return;

lib/Sema/ConstraintSystem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,11 @@ class Solution {
898898
return None;
899899
}
900900

901+
/// Retrieve a fully-resolved protocol conformance at the given locator
902+
/// and with the given protocol.
903+
ProtocolConformanceRef resolveConformance(ConstraintLocator *locator,
904+
ProtocolDecl *proto);
905+
901906
void setExprTypes(Expr *expr) const;
902907

903908
SWIFT_DEBUG_DUMP;

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3040,17 +3040,15 @@ auto TypeChecker::typeCheckForEachBinding(
30403040
Stmt->setPattern(pattern);
30413041

30423042
// Get the conformance of the sequence type to the Sequence protocol.
3043-
// FIXME: Get this from the solution and substitute into that.
3044-
SequenceConformance = TypeChecker::conformsToProtocol(
3045-
SequenceType, SequenceProto, cs.DC,
3046-
ConformanceCheckFlags::InExpression,
3047-
expr->getLoc());
3043+
SequenceConformance = solution.resolveConformance(
3044+
ContextualLocator, SequenceProto);
30483045
assert(!SequenceConformance.isInvalid() &&
30493046
"Couldn't find sequence conformance");
30503047
Stmt->setSequenceConformance(SequenceConformance);
30513048

30523049
// Retrieve the conformance of the iterator type to IteratorProtocol.
3053-
// FIXME: Get this from the solution and substitute into that.
3050+
// FIXME: We probably don't even need this. If we do, get it from
3051+
// SequenceConformance instead.
30543052
IteratorConformance = TypeChecker::conformsToProtocol(
30553053
IteratorType, IteratorProto, cs.DC,
30563054
ConformanceCheckFlags::InExpression,

0 commit comments

Comments
 (0)