@@ -83,11 +83,12 @@ static void recordRelation(Term key,
8383
8484 assert (key.size () >= lhsRule.getRHS ().size ());
8585
86- assert (lhsProperty.isProperty ());
87- assert (rhsProperty.isProperty ());
88- assert (lhsProperty.getKind () == rhsProperty.getKind () ||
86+ assert ((lhsProperty.getKind () == Symbol::Kind::Layout &&
87+ rhsProperty.getKind () == Symbol::Kind::Layout) ||
8988 (lhsProperty.getKind () == Symbol::Kind::Superclass &&
90- rhsProperty.getKind () == Symbol::Kind::Layout));
89+ rhsProperty.getKind () == Symbol::Kind::Layout) ||
90+ (lhsProperty.getKind () == Symbol::Kind::ConcreteType &&
91+ rhsProperty.getKind () == Symbol::Kind::Superclass));
9192
9293 if (debug) {
9394 llvm::dbgs () << " %% Recording relation: " ;
@@ -132,16 +133,20 @@ static void recordConflict(Term key,
132133 unsigned existingRuleID,
133134 unsigned newRuleID,
134135 RewriteSystem &system) {
136+ auto &existingRule = system.getRule (existingRuleID);
137+ auto &newRule = system.getRule (newRuleID);
138+
139+ auto existingKind = existingRule.isPropertyRule ()->getKind ();
140+ auto newKind = newRule.isPropertyRule ()->getKind ();
141+
135142 // The GSB only dropped the new rule in the case of a conflicting
136143 // superclass requirement, so maintain that behavior here.
137- auto &existingRule = system.getRule (existingRuleID);
138- if (existingRule.isPropertyRule ()->getKind () !=
139- Symbol::Kind::Superclass) {
144+ if (existingKind != Symbol::Kind::Superclass &&
145+ existingKind == newKind) {
140146 if (existingRule.getRHS ().size () == key.size ())
141147 existingRule.markConflicting ();
142148 }
143149
144- auto &newRule = system.getRule (newRuleID);
145150 assert (newRule.getRHS ().size () == key.size ());
146151 newRule.markConflicting ();
147152}
@@ -546,10 +551,39 @@ void PropertyMap::addProperty(
546551 llvm_unreachable (" Bad symbol kind" );
547552}
548553
554+ void PropertyMap::checkConcreteTypeRequirements (
555+ SmallVectorImpl<InducedRule> &inducedRules) {
556+ bool debug = Debug.contains (DebugFlags::ConcreteUnification);
557+
558+ for (auto *props : Entries) {
559+ if (props->ConcreteTypeRule && props->SuperclassRule ) {
560+ auto concreteType = props->ConcreteType ->getConcreteType ();
561+
562+ // A rule (T.[concrete: C] => T) where C is a class type induces a rule
563+ // (T.[superclass: C] => T).
564+ if (concreteType->getClassOrBoundGenericClass ()) {
565+ auto superclassSymbol = Symbol::forSuperclass (
566+ concreteType, props->ConcreteType ->getSubstitutions (),
567+ Context);
568+
569+ recordRelation (props->getKey (), *props->ConcreteTypeRule ,
570+ superclassSymbol, System,
571+ inducedRules, debug);
572+
573+ // Otherwise, we have a concrete vs superclass conflict.
574+ } else {
575+ recordConflict (props->getKey (),
576+ *props->ConcreteTypeRule ,
577+ *props->SuperclassRule , System);
578+ }
579+ }
580+ }
581+ }
582+
549583// / For each fully-concrete type, find the shortest term having that concrete type.
550584// / This is later used by computeConstraintTermForTypeWitness().
551585void PropertyMap::computeConcreteTypeInDomainMap () {
552- for (const auto & props : Entries) {
586+ for (auto * props : Entries) {
553587 if (!props->isConcreteType ())
554588 continue ;
555589
@@ -575,7 +609,7 @@ void PropertyMap::computeConcreteTypeInDomainMap() {
575609
576610void PropertyMap::concretizeNestedTypesFromConcreteParents (
577611 SmallVectorImpl<InducedRule> &inducedRules) {
578- for (const auto & props : Entries) {
612+ for (auto * props : Entries) {
579613 if (props->getConformsTo ().empty ())
580614 continue ;
581615
0 commit comments