|
28 | 28 | #include "swift/AST/DiagnosticsSema.h"
|
29 | 29 | #include "swift/AST/ExistentialLayout.h"
|
30 | 30 | #include "swift/AST/Requirement.h"
|
| 31 | +#include "swift/AST/RequirementSignature.h" |
31 | 32 | #include "swift/AST/TypeCheckRequests.h"
|
32 | 33 | #include "swift/AST/TypeMatcher.h"
|
33 | 34 | #include "swift/AST/TypeRepr.h"
|
@@ -1014,6 +1015,38 @@ void RuleBuilder::addRequirement(const StructuralRequirement &req,
|
1014 | 1015 | addRequirement(req.req.getCanonical(), proto);
|
1015 | 1016 | }
|
1016 | 1017 |
|
| 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 | + |
1017 | 1050 | /// Record information about a protocol if we have no seen it yet.
|
1018 | 1051 | void RuleBuilder::addProtocol(const ProtocolDecl *proto,
|
1019 | 1052 | bool initialComponent) {
|
@@ -1077,6 +1110,8 @@ void RuleBuilder::collectRulesFromReferencedProtocols() {
|
1077 | 1110 | auto reqs = proto->getRequirementSignature();
|
1078 | 1111 | for (auto req : reqs.getRequirements())
|
1079 | 1112 | addRequirement(req.getCanonical(), proto);
|
| 1113 | + for (auto alias : reqs.getTypeAliases()) |
| 1114 | + addTypeAlias(alias, proto); |
1080 | 1115 | }
|
1081 | 1116 |
|
1082 | 1117 | if (Dump) {
|
|
0 commit comments