@@ -541,32 +541,47 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
541
541
542
542
auto *concrete = conformance.getConcrete ();
543
543
544
- recordConcreteConformanceRule (concreteRuleID, conformanceRuleID, proto,
545
- inducedRules);
546
-
547
544
// Record the conformance for use by
548
545
// PropertyBag::getConformsToExcludingSuperclassConformances().
549
546
conformances.push_back (concrete);
550
547
548
+ // All subsequent logic just records new rewrite rules, and can be
549
+ // skipped if we've already processed this pair of rules.
550
+ if (!ConcreteConformanceRules.insert (
551
+ std::make_pair (concreteRuleID, conformanceRuleID)).second ) {
552
+ // We've already processed this pair of rules.
553
+ continue ;
554
+ }
555
+
556
+ auto concreteConformanceSymbol = Symbol::forConcreteConformance (
557
+ concreteType, substitutions, proto, Context);
558
+
559
+ recordConcreteConformanceRule (concreteRuleID, conformanceRuleID,
560
+ requirementKind, concreteConformanceSymbol,
561
+ inducedRules);
562
+
551
563
auto assocTypes = proto->getAssociatedTypeMembers ();
552
564
if (assocTypes.empty ())
553
565
continue ;
554
566
555
567
for (auto *assocType : assocTypes) {
556
568
concretizeTypeWitnessInConformance (key, requirementKind,
557
- concreteType, substitutions ,
558
- proto, concrete, assocType,
569
+ concreteConformanceSymbol ,
570
+ concrete, assocType,
559
571
inducedRules);
560
572
}
561
573
}
562
574
}
563
575
564
576
void PropertyMap::concretizeTypeWitnessInConformance (
565
577
Term key, RequirementKind requirementKind,
566
- CanType concreteType, ArrayRef<Term> substitutions ,
567
- const ProtocolDecl *proto, ProtocolConformance *concrete,
578
+ Symbol concreteConformanceSymbol ,
579
+ ProtocolConformance *concrete,
568
580
AssociatedTypeDecl *assocType,
569
581
SmallVectorImpl<InducedRule> &inducedRules) const {
582
+ auto concreteType = concreteConformanceSymbol.getConcreteType ();
583
+ auto substitutions = concreteConformanceSymbol.getSubstitutions ();
584
+ auto *proto = concreteConformanceSymbol.getProtocol ();
570
585
571
586
if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
572
587
llvm::dbgs () << " ^^ " << " Looking up type witness for "
@@ -591,7 +606,9 @@ void PropertyMap::concretizeTypeWitnessInConformance(
591
606
<< " of " << concreteType << " is " << typeWitness << " \n " ;
592
607
}
593
608
609
+ // Build the term T.[concrete: C : P].[P:X].
594
610
MutableTerm subjectType (key);
611
+ subjectType.add (concreteConformanceSymbol);
595
612
subjectType.add (Symbol::forAssociatedType (proto, assocType->getName (),
596
613
Context));
597
614
@@ -682,19 +699,26 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
682
699
// The type witness is a type parameter of the form τ_0_n.X.Y...Z,
683
700
// where 'n' is an index into the substitution array.
684
701
//
685
- // Add a rule T => S.X.Y...Z, where S is the nth substitution term.
702
+ // Add a rule:
703
+ //
704
+ // T.[concrete: C : P].[P:X] => S[n].X.Y...Z
705
+ //
706
+ // Where S[n] is the nth substitution term.
686
707
return Context.getRelativeTermForType (typeWitness, substitutions);
687
708
}
688
709
689
710
// The type witness is a concrete type.
711
+ //
712
+ // Add a rule:
713
+ //
714
+ // T.[concrete: C : P].[P:X].[concrete: Foo.A] => T.[concrete: C : P].[P:A].
690
715
MutableTerm constraintType = subjectType;
691
716
692
717
SmallVector<Term, 3 > result;
693
718
auto typeWitnessSchema =
694
719
remapConcreteSubstitutionSchema (typeWitness, substitutions,
695
720
Context, result);
696
721
697
- // Add a rule T.[P:A].[concrete: Foo.A] => T.[P:A].
698
722
constraintType.add (
699
723
Symbol::forConcreteType (
700
724
typeWitnessSchema, result, Context));
@@ -705,24 +729,28 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
705
729
void PropertyMap::recordConcreteConformanceRule (
706
730
unsigned concreteRuleID,
707
731
unsigned conformanceRuleID,
708
- const ProtocolDecl *proto,
709
- SmallVectorImpl<InducedRule> &inducedRules) {
710
- if (!ConcreteConformanceRules.insert (
711
- std::make_pair (concreteRuleID, conformanceRuleID)).second ) {
712
- // We've already emitted this rule.
713
- return ;
714
- }
715
-
732
+ RequirementKind requirementKind,
733
+ Symbol concreteConformanceSymbol,
734
+ SmallVectorImpl<InducedRule> &inducedRules) const {
716
735
const auto &concreteRule = System.getRule (concreteRuleID);
717
736
const auto &conformanceRule = System.getRule (conformanceRuleID);
718
737
719
- auto conformanceSymbol = *conformanceRule.isPropertyRule ();
720
- assert (conformanceSymbol.getKind () == Symbol::Kind::Protocol);
721
- assert (conformanceSymbol.getProtocol () == proto);
722
-
723
- auto concreteSymbol = *concreteRule.isPropertyRule ();
724
- assert (concreteSymbol.getKind () == Symbol::Kind::ConcreteType ||
725
- concreteSymbol.getKind () == Symbol::Kind::Superclass);
738
+ #ifndef NDEBUG
739
+ {
740
+ auto conformanceSymbol = *conformanceRule.isPropertyRule ();
741
+ assert (conformanceSymbol.getKind () == Symbol::Kind::Protocol);
742
+ assert (conformanceSymbol.getProtocol () ==
743
+ concreteConformanceSymbol.getProtocol ());
744
+
745
+ auto concreteSymbol = *concreteRule.isPropertyRule ();
746
+ if (concreteSymbol.getKind () == Symbol::Kind::Superclass)
747
+ assert (requirementKind == RequirementKind::Superclass);
748
+ else {
749
+ assert (concreteSymbol.getKind () == Symbol::Kind::ConcreteType);
750
+ assert (requirementKind == RequirementKind::SameType);
751
+ }
752
+ }
753
+ #endif
726
754
727
755
RewritePath path;
728
756
@@ -752,32 +780,18 @@ void PropertyMap::recordConcreteConformanceRule(
752
780
// than T.
753
781
unsigned adjustment = rhs.size () - concreteRule.getRHS ().size ();
754
782
if (adjustment > 0 &&
755
- !concreteSymbol .getSubstitutions ().empty ()) {
783
+ !concreteConformanceSymbol .getSubstitutions ().empty ()) {
756
784
path.add (RewriteStep::forAdjustment (adjustment, /* endOffset=*/ 1 ,
757
785
/* inverse=*/ false ));
758
-
759
- concreteSymbol = concreteSymbol.prependPrefixToConcreteSubstitutions (
760
- MutableTerm (rhs.begin (), rhs.begin () + adjustment),
761
- Context);
762
786
}
763
787
764
788
// Now, transform T''.[concrete: C].[P] into T''.[concrete: C : P].
765
- Symbol concreteConformanceSymbol = [&]() {
766
- if (concreteSymbol.getKind () == Symbol::Kind::ConcreteType) {
767
- path.add (RewriteStep::forConcreteConformance (/* inverse=*/ false ));
768
- return Symbol::forConcreteConformance (
769
- concreteSymbol.getConcreteType (),
770
- concreteSymbol.getSubstitutions (),
771
- proto, Context);
772
- } else {
773
- assert (concreteSymbol.getKind () == Symbol::Kind::Superclass);
774
- path.add (RewriteStep::forSuperclassConformance (/* inverse=*/ false ));
775
- return Symbol::forConcreteConformance (
776
- concreteSymbol.getSuperclass (),
777
- concreteSymbol.getSubstitutions (),
778
- proto, Context);
779
- }
780
- }();
789
+ if (requirementKind == RequirementKind::Superclass) {
790
+ path.add (RewriteStep::forSuperclassConformance (/* inverse=*/ false ));
791
+ } else {
792
+ assert (requirementKind == RequirementKind::SameType);
793
+ path.add (RewriteStep::forConcreteConformance (/* inverse=*/ false ));
794
+ }
781
795
782
796
MutableTerm lhs (rhs);
783
797
lhs.add (concreteConformanceSymbol);
0 commit comments