Skip to content

Commit ae56af3

Browse files
committed
RequirementMachine: Workaround invariant violation when requirement signature completion fails
- If P is declared to inherit from Q and Q has an associated type named U, then isValidTypeInContext() returns true for a type 'T.U' where 'T' is a generic parameter conforming to P, and 'U' is the unresolved DependentMemberType, and the type 'T.U' will simplify to the term 'T.[P:U]'. - However, if completion failed while building the rewrite system for P's requirement signature, then the requirement signature for P won't have a rule [P].[Q] => [P]. As a result, getTypeForTerm() will fail when given 'T.[P:U]', because the property map entry for 'T' will not contain a conformance to Q. Work around this by manually adding protocol inheritance rules when building a signature from a protocol whose requirement signature failed to compute. This was triggered by the test case I added in the previous commit to test/Generics/non_confluent.swift.
1 parent 0111618 commit ae56af3

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

lib/AST/RequirementMachine/RuleBuilder.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,21 @@ void RuleBuilder::initWithProtocolSignatureRequirements(
101101
addPermanentProtocolRules(proto);
102102

103103
auto reqs = proto->getRequirementSignature();
104+
105+
// If completion failed, we'll have a totally empty requirement signature,
106+
// but to maintain invariants around what constitutes a valid rewrite term
107+
// between getTypeForTerm() and isValidTypeInContext(), we need to add rules
108+
// for inherited protocols.
109+
if (reqs.getErrors().contains(GenericSignatureErrorFlags::CompletionFailed)) {
110+
for (auto *inheritedProto : Context.getInheritedProtocols(proto)) {
111+
Requirement req(RequirementKind::Conformance,
112+
proto->getSelfInterfaceType(),
113+
inheritedProto->getDeclaredInterfaceType());
114+
115+
addRequirement(req.getCanonical(), proto);
116+
}
117+
}
118+
104119
for (auto req : reqs.getRequirements())
105120
addRequirement(req.getCanonical(), proto);
106121
for (auto alias : reqs.getTypeAliases())

0 commit comments

Comments
 (0)