@@ -83,11 +83,12 @@ static void recordRelation(Term key,
83
83
84
84
assert (key.size () >= lhsRule.getRHS ().size ());
85
85
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) ||
89
88
(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));
91
92
92
93
if (debug) {
93
94
llvm::dbgs () << " %% Recording relation: " ;
@@ -132,16 +133,20 @@ static void recordConflict(Term key,
132
133
unsigned existingRuleID,
133
134
unsigned newRuleID,
134
135
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
+
135
142
// The GSB only dropped the new rule in the case of a conflicting
136
143
// 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) {
140
146
if (existingRule.getRHS ().size () == key.size ())
141
147
existingRule.markConflicting ();
142
148
}
143
149
144
- auto &newRule = system.getRule (newRuleID);
145
150
assert (newRule.getRHS ().size () == key.size ());
146
151
newRule.markConflicting ();
147
152
}
@@ -546,10 +551,39 @@ void PropertyMap::addProperty(
546
551
llvm_unreachable (" Bad symbol kind" );
547
552
}
548
553
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
+
549
583
// / For each fully-concrete type, find the shortest term having that concrete type.
550
584
// / This is later used by computeConstraintTermForTypeWitness().
551
585
void PropertyMap::computeConcreteTypeInDomainMap () {
552
- for (const auto & props : Entries) {
586
+ for (auto * props : Entries) {
553
587
if (!props->isConcreteType ())
554
588
continue ;
555
589
@@ -575,7 +609,7 @@ void PropertyMap::computeConcreteTypeInDomainMap() {
575
609
576
610
void PropertyMap::concretizeNestedTypesFromConcreteParents (
577
611
SmallVectorImpl<InducedRule> &inducedRules) {
578
- for (const auto & props : Entries) {
612
+ for (auto * props : Entries) {
579
613
if (props->getConformsTo ().empty ())
580
614
continue ;
581
615
0 commit comments