Skip to content

Commit f9c2d9f

Browse files
committed
RequirementMachine: Introduce Rule::isProtocolTypeAliasRule()
There are two kinds of protocol typealiases: 1) The underlying type is a type parameter. These rules look like [P].A => X where X is the underlying type. 2) The underlying type is a concrete type. These rules look like [P].A.[concrete: C] => [P].A. The isProtocolTypeAliasRule() predicate detects both cases and returns the type alias name ('A', in the above examples). For now it's not used anywhere, since we don't actually introduce these rules for any reason.
1 parent cc3d02b commit f9c2d9f

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

lib/AST/RequirementMachine/RewriteSystem.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,48 @@ bool Rule::isProtocolRefinementRule() const {
120120
return false;
121121
}
122122

123+
/// A protocol typealias rule takes one of the following two forms,
124+
/// where T is a name symbol:
125+
///
126+
/// 1) [P].T => X
127+
/// 2) [P].T.[concrete: C] => [P].T
128+
///
129+
/// The first case is where the protocol's underlying type is another
130+
/// type parameter. The second case is where the protocol's underlying
131+
/// type is a concrete type.
132+
///
133+
/// In the first case, X must be fully resolved, that is, it must not
134+
/// contain any name symbols.
135+
///
136+
/// If this rule is a protocol typealias rule, returns its name. Otherwise
137+
/// returns None.
138+
Optional<Identifier> Rule::isProtocolTypeAliasRule() const {
139+
if (LHS.size() != 2 && LHS.size() != 3)
140+
return None;
141+
142+
if (LHS[0].getKind() != Symbol::Kind::Protocol ||
143+
LHS[1].getKind() != Symbol::Kind::Name)
144+
return None;
145+
146+
if (LHS.size() == 2) {
147+
// This is the case where the underlying type is a type parameter.
148+
//
149+
// We shouldn't have unresolved symbols on the right hand side;
150+
// they should have been simplified away.
151+
if (RHS.containsUnresolvedSymbols())
152+
return None;
153+
} else {
154+
// This is the case where the underlying type is concrete.
155+
assert(LHS.size() == 3);
156+
157+
auto prop = isPropertyRule();
158+
if (!prop || prop->getKind() != Symbol::Kind::ConcreteType)
159+
return None;
160+
}
161+
162+
return LHS[1].getName();
163+
}
164+
123165
/// Returns the length of the left hand side.
124166
unsigned Rule::getDepth() const {
125167
auto result = LHS.size();

lib/AST/RequirementMachine/RewriteSystem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ class Rule final {
140140
RHS.containsUnresolvedSymbols());
141141
}
142142

143+
Optional<Identifier> isProtocolTypeAliasRule() const;
144+
143145
void markLHSSimplified() {
144146
assert(!LHSSimplified);
145147
LHSSimplified = true;

0 commit comments

Comments
 (0)