@@ -89,7 +89,7 @@ void RewriteLoop::findProtocolConformanceRules(
8989 for (unsigned ruleID : redundantRules) {
9090 const auto &rule = system.getRule (ruleID);
9191
92- if (auto *proto = rule.isProtocolConformanceRule ()) {
92+ if (auto *proto = rule.isAnyConformanceRule ()) {
9393 if (rule.isIdentityConformanceRule ()) {
9494 result[proto].SawIdentityConformance = true ;
9595 continue ;
@@ -116,7 +116,7 @@ void RewriteLoop::findProtocolConformanceRules(
116116 if (rule.isIdentityConformanceRule ())
117117 break ;
118118
119- if (auto *proto = rule.isProtocolConformanceRule ()) {
119+ if (auto *proto = rule.isAnyConformanceRule ()) {
120120 if (step.StartOffset > 0 &&
121121 step.EndOffset == 0 ) {
122122 // Record the prefix term that is left unchanged by this rewrite step.
@@ -171,7 +171,7 @@ RewriteSystem::decomposeTermIntoConformanceRuleLeftHandSides(
171171
172172#ifndef NDEBUG
173173 const auto &rule = getRule (step.RuleID );
174- assert (rule.isProtocolConformanceRule ());
174+ assert (rule.isAnyConformanceRule ());
175175 assert (!rule.isIdentityConformanceRule ());
176176#endif
177177
@@ -199,7 +199,7 @@ RewriteSystem::decomposeTermIntoConformanceRuleLeftHandSides(
199199 MutableTerm term, unsigned ruleID,
200200 SmallVectorImpl<unsigned > &result) const {
201201 const auto &rule = getRule (ruleID);
202- assert (rule.isProtocolConformanceRule ());
202+ assert (rule.isAnyConformanceRule ());
203203 assert (!rule.isIdentityConformanceRule ());
204204
205205 // Compute domain(V).
@@ -412,15 +412,27 @@ void RewriteSystem::computeCandidateConformancePaths(
412412bool RewriteSystem::isValidConformancePath (
413413 llvm::SmallDenseSet<unsigned , 4 > &visited,
414414 llvm::DenseSet<unsigned > &redundantConformances,
415- const llvm::SmallVectorImpl<unsigned > &path,
415+ const llvm::SmallVectorImpl<unsigned > &path, bool allowConcrete,
416416 const llvm::MapVector<unsigned , SmallVector<unsigned , 2 >> &parentPaths,
417417 const llvm::MapVector<unsigned ,
418418 std::vector<SmallVector<unsigned , 2 >>>
419419 &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];
421425 if (visited.count (ruleID) > 0 )
422426 return false ;
423427
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+
424436 if (redundantConformances.count (ruleID)) {
425437 SWIFT_DEFER {
426438 visited.erase (ruleID);
@@ -433,6 +445,7 @@ bool RewriteSystem::isValidConformancePath(
433445 bool foundValidConformancePath = false ;
434446 for (const auto &otherPath : found->second ) {
435447 if (isValidConformancePath (visited, redundantConformances, otherPath,
448+ allowConcrete && isLastElement,
436449 parentPaths, conformancePaths)) {
437450 foundValidConformancePath = true ;
438451 break ;
@@ -454,6 +467,7 @@ bool RewriteSystem::isValidConformancePath(
454467 // `T.[P.]A : Q', we want to make sure that we have a
455468 // non-redundant derivation for 'T : P'.
456469 if (!isValidConformancePath (visited, redundantConformances, found->second ,
470+ /* allowConcrete=*/ false ,
457471 parentPaths, conformancePaths)) {
458472 return false ;
459473 }
@@ -581,7 +595,8 @@ void RewriteSystem::verifyGeneratingConformanceEquations(
581595static const ProtocolDecl *getParentConformanceForTerm (Term lhs) {
582596 // The last element is a protocol symbol, because this is the left hand side
583597 // 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);
585600
586601 // The second to last symbol is either an associated type, protocol or generic
587602 // parameter symbol.
@@ -664,7 +679,7 @@ void RewriteSystem::computeGeneratingConformances(
664679 if (rule.containsUnresolvedSymbols ())
665680 continue ;
666681
667- if (!rule.isProtocolConformanceRule ())
682+ if (!rule.isAnyConformanceRule ())
668683 continue ;
669684
670685 conformanceRules.push_back (ruleID);
@@ -757,6 +772,7 @@ void RewriteSystem::computeGeneratingConformances(
757772 visited.insert (ruleID);
758773
759774 if (isValidConformancePath (visited, redundantConformances, path,
775+ /* allowConcrete=*/ true ,
760776 parentPaths, conformancePaths)) {
761777 redundantConformances.insert (ruleID);
762778 break ;
0 commit comments