Skip to content

Commit 4a06e21

Browse files
committed
RequirementMachine: Introduce rules for protocol typealiases from requirement signatures
When building a rewrite system for a generic signature or protocol, we would add requirements from the requirement signature of every protocol dependency. Now, also add protocol typealias rules as well.
1 parent a1c03db commit 4a06e21

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "swift/AST/DiagnosticsSema.h"
2929
#include "swift/AST/ExistentialLayout.h"
3030
#include "swift/AST/Requirement.h"
31+
#include "swift/AST/RequirementSignature.h"
3132
#include "swift/AST/TypeCheckRequests.h"
3233
#include "swift/AST/TypeMatcher.h"
3334
#include "swift/AST/TypeRepr.h"
@@ -1014,6 +1015,38 @@ void RuleBuilder::addRequirement(const StructuralRequirement &req,
10141015
addRequirement(req.req.getCanonical(), proto);
10151016
}
10161017

1018+
/// Lowers a protocol typealias to a rewrite rule.
1019+
void RuleBuilder::addTypeAlias(const ProtocolTypeAlias &alias,
1020+
const ProtocolDecl *proto) {
1021+
// Build the term [P].T, where P is the protocol and T is a name symbol.
1022+
MutableTerm subjectTerm;
1023+
subjectTerm.add(Symbol::forProtocol(proto, Context));
1024+
subjectTerm.add(Symbol::forName(alias.getName(), Context));
1025+
1026+
auto constraintType = alias.getUnderlyingType()->getCanonicalType();
1027+
MutableTerm constraintTerm;
1028+
1029+
if (constraintType->isTypeParameter()) {
1030+
// If the underlying type of the typealias is a type parameter X, build
1031+
// a rule [P].T => X, where X,
1032+
constraintTerm = Context.getMutableTermForType(
1033+
constraintType, proto);
1034+
} else {
1035+
// If the underlying type of the typealias is a concrete type C, build
1036+
// a rule [P].T.[concrete: C] => [P].T.
1037+
constraintTerm = subjectTerm;
1038+
1039+
SmallVector<Term, 1> result;
1040+
auto concreteType =
1041+
Context.getSubstitutionSchemaFromType(
1042+
constraintType, proto, result);
1043+
1044+
constraintTerm.add(Symbol::forConcreteType(concreteType, result, Context));
1045+
}
1046+
1047+
RequirementRules.emplace_back(subjectTerm, constraintTerm);
1048+
}
1049+
10171050
/// Record information about a protocol if we have no seen it yet.
10181051
void RuleBuilder::addProtocol(const ProtocolDecl *proto,
10191052
bool initialComponent) {
@@ -1077,6 +1110,8 @@ void RuleBuilder::collectRulesFromReferencedProtocols() {
10771110
auto reqs = proto->getRequirementSignature();
10781111
for (auto req : reqs.getRequirements())
10791112
addRequirement(req.getCanonical(), proto);
1113+
for (auto alias : reqs.getTypeAliases())
1114+
addTypeAlias(alias, proto);
10801115
}
10811116

10821117
if (Dump) {

lib/AST/RequirementMachine/RequirementLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace swift {
3030

3131
class AssociatedTypeDecl;
3232
class ProtocolDecl;
33+
class ProtocolTypeAlias;
3334
class Requirement;
3435

3536
namespace rewriting {
@@ -116,6 +117,8 @@ struct RuleBuilder {
116117
const ProtocolDecl *proto);
117118
void addRequirement(const StructuralRequirement &req,
118119
const ProtocolDecl *proto);
120+
void addTypeAlias(const ProtocolTypeAlias &alias,
121+
const ProtocolDecl *proto);
119122
void collectRulesFromReferencedProtocols();
120123
};
121124

0 commit comments

Comments
 (0)