mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
RequirementMachine: Refine 'derived via protocol typealias' criterion
Preserves concrete type rules on associated types that were derived
from rules indirectly formed from protocol typealias rules.
That is, if you have a pair of rules in another minimization domain:
[P].A.[concrete: C] => [P].A
[Q:T].[P] => [Q:T]
Then completion will introduce a new rule:
[Q:T].A.[concrete: C] => [Q:T].A
Since this rule is outside of our minimization domain, we don't record
a rewrite loop for it, and it will never become redundant.
Now if we have a rule in our own minimization domain:
T.[Q:T].A => T.[Q:U]
Then we get a new rule:
T.[Q:U].[concrete: C] => T.[Q:U]
Make sure we keep this rule around on account of it being derived from
([Q:T].A.[concrete: C] => [Q:T].A).
This commit is contained in:
@@ -193,6 +193,29 @@ Optional<Identifier> Rule::isProtocolTypeAliasRule() const {
|
||||
return LHS[1].getName();
|
||||
}
|
||||
|
||||
/// A rule was derived from a concrete protocol typealias if it
|
||||
/// takes the following form:
|
||||
///
|
||||
/// T.A.[concrete: C] => T.A
|
||||
///
|
||||
/// Where the prefix term T does not contain any name symbols, and
|
||||
/// A is a name symbol.
|
||||
bool Rule::isDerivedFromConcreteProtocolTypeAliasRule() const {
|
||||
auto optSymbol = isPropertyRule();
|
||||
if (!optSymbol || optSymbol->getKind() != Symbol::Kind::ConcreteType)
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0, e = RHS.size() - 1; i < e; ++i) {
|
||||
if (RHS[i].getKind() == Symbol::Kind::Name)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RHS.back().getKind() != Symbol::Kind::Name)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Returns the length of the left hand side.
|
||||
unsigned Rule::getDepth() const {
|
||||
auto result = LHS.size();
|
||||
|
||||
Reference in New Issue
Block a user