@@ -89,7 +89,7 @@ void RewriteLoop::findProtocolConformanceRules(
89
89
for (unsigned ruleID : redundantRules) {
90
90
const auto &rule = system.getRule (ruleID);
91
91
92
- if (auto *proto = rule.isProtocolConformanceRule ()) {
92
+ if (auto *proto = rule.isAnyConformanceRule ()) {
93
93
if (rule.isIdentityConformanceRule ()) {
94
94
result[proto].SawIdentityConformance = true ;
95
95
continue ;
@@ -116,7 +116,7 @@ void RewriteLoop::findProtocolConformanceRules(
116
116
if (rule.isIdentityConformanceRule ())
117
117
break ;
118
118
119
- if (auto *proto = rule.isProtocolConformanceRule ()) {
119
+ if (auto *proto = rule.isAnyConformanceRule ()) {
120
120
if (step.StartOffset > 0 &&
121
121
step.EndOffset == 0 ) {
122
122
// Record the prefix term that is left unchanged by this rewrite step.
@@ -171,7 +171,7 @@ RewriteSystem::decomposeTermIntoConformanceRuleLeftHandSides(
171
171
172
172
#ifndef NDEBUG
173
173
const auto &rule = getRule (step.RuleID );
174
- assert (rule.isProtocolConformanceRule ());
174
+ assert (rule.isAnyConformanceRule ());
175
175
assert (!rule.isIdentityConformanceRule ());
176
176
#endif
177
177
@@ -199,7 +199,7 @@ RewriteSystem::decomposeTermIntoConformanceRuleLeftHandSides(
199
199
MutableTerm term, unsigned ruleID,
200
200
SmallVectorImpl<unsigned > &result) const {
201
201
const auto &rule = getRule (ruleID);
202
- assert (rule.isProtocolConformanceRule ());
202
+ assert (rule.isAnyConformanceRule ());
203
203
assert (!rule.isIdentityConformanceRule ());
204
204
205
205
// Compute domain(V).
@@ -412,15 +412,27 @@ void RewriteSystem::computeCandidateConformancePaths(
412
412
bool RewriteSystem::isValidConformancePath (
413
413
llvm::SmallDenseSet<unsigned , 4 > &visited,
414
414
llvm::DenseSet<unsigned > &redundantConformances,
415
- const llvm::SmallVectorImpl<unsigned > &path,
415
+ const llvm::SmallVectorImpl<unsigned > &path, bool allowConcrete,
416
416
const llvm::MapVector<unsigned , SmallVector<unsigned , 2 >> &parentPaths,
417
417
const llvm::MapVector<unsigned ,
418
418
std::vector<SmallVector<unsigned , 2 >>>
419
419
&conformancePaths) const {
420
- for (unsigned ruleID : path) {
420
+
421
+ unsigned lastIdx = path.size () - 1 ;
422
+
423
+ for (unsigned ruleIdx : indices (path)) {
424
+ unsigned ruleID = path[ruleIdx];
421
425
if (visited.count (ruleID) > 0 )
422
426
return false ;
423
427
428
+ bool isLastElement = (ruleIdx == lastIdx);
429
+
430
+ if (!allowConcrete || !isLastElement) {
431
+ if (getRule (ruleID).getLHS ().back ().getKind ()
432
+ == Symbol::Kind::ConcreteConformance)
433
+ return false ;
434
+ }
435
+
424
436
if (redundantConformances.count (ruleID)) {
425
437
SWIFT_DEFER {
426
438
visited.erase (ruleID);
@@ -433,6 +445,7 @@ bool RewriteSystem::isValidConformancePath(
433
445
bool foundValidConformancePath = false ;
434
446
for (const auto &otherPath : found->second ) {
435
447
if (isValidConformancePath (visited, redundantConformances, otherPath,
448
+ allowConcrete && isLastElement,
436
449
parentPaths, conformancePaths)) {
437
450
foundValidConformancePath = true ;
438
451
break ;
@@ -454,6 +467,7 @@ bool RewriteSystem::isValidConformancePath(
454
467
// `T.[P.]A : Q', we want to make sure that we have a
455
468
// non-redundant derivation for 'T : P'.
456
469
if (!isValidConformancePath (visited, redundantConformances, found->second ,
470
+ /* allowConcrete=*/ false ,
457
471
parentPaths, conformancePaths)) {
458
472
return false ;
459
473
}
@@ -581,7 +595,8 @@ void RewriteSystem::verifyGeneratingConformanceEquations(
581
595
static const ProtocolDecl *getParentConformanceForTerm (Term lhs) {
582
596
// The last element is a protocol symbol, because this is the left hand side
583
597
// of a conformance rule.
584
- assert (lhs.back ().getKind () == Symbol::Kind::Protocol);
598
+ assert (lhs.back ().getKind () == Symbol::Kind::Protocol ||
599
+ lhs.back ().getKind () == Symbol::Kind::ConcreteConformance);
585
600
586
601
// The second to last symbol is either an associated type, protocol or generic
587
602
// parameter symbol.
@@ -664,7 +679,7 @@ void RewriteSystem::computeGeneratingConformances(
664
679
if (rule.containsUnresolvedSymbols ())
665
680
continue ;
666
681
667
- if (!rule.isProtocolConformanceRule ())
682
+ if (!rule.isAnyConformanceRule ())
668
683
continue ;
669
684
670
685
conformanceRules.push_back (ruleID);
@@ -757,6 +772,7 @@ void RewriteSystem::computeGeneratingConformances(
757
772
visited.insert (ruleID);
758
773
759
774
if (isValidConformancePath (visited, redundantConformances, path,
775
+ /* allowConcrete=*/ true ,
760
776
parentPaths, conformancePaths)) {
761
777
redundantConformances.insert (ruleID);
762
778
break ;
0 commit comments