@@ -428,7 +428,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
428
428
RequirementKind::SameType,
429
429
props->ConcreteType ->getConcreteType (),
430
430
props->ConcreteType ->getSubstitutions (),
431
- props->getConformsTo () ,
431
+ props->ConformsTo ,
432
432
props->ConcreteConformances ,
433
433
inducedRules);
434
434
}
@@ -523,70 +523,83 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
523
523
continue ;
524
524
525
525
for (auto *assocType : assocTypes) {
526
- if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
527
- llvm::dbgs () << " ^^ " << " Looking up type witness for "
528
- << proto->getName () << " :" << assocType->getName ()
529
- << " on " << concreteType << " \n " ;
530
- }
526
+ concretizeTypeWitnessInConformance (key, requirementKind,
527
+ concreteType, substitutions,
528
+ proto, concrete, assocType,
529
+ inducedRules);
530
+ }
531
+ }
532
+ }
531
533
532
- auto t = concrete-> getTypeWitness (assocType);
533
- if (!t) {
534
- if (Debug. contains (DebugFlags::ConcretizeNestedTypes)) {
535
- llvm::dbgs () << " ^^ " << " Type witness for " << assocType-> getName ()
536
- << " of " << concreteType << " could not be inferred \n " ;
537
- }
534
+ void PropertyMap::concretizeTypeWitnessInConformance (
535
+ Term key, RequirementKind requirementKind,
536
+ CanType concreteType, ArrayRef<Term> substitutions,
537
+ const ProtocolDecl *proto, ProtocolConformance *concrete,
538
+ AssociatedTypeDecl *assocType,
539
+ SmallVectorImpl<InducedRule> &inducedRules) const {
538
540
539
- t = ErrorType::get (concreteType);
540
- }
541
+ if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
542
+ llvm::dbgs () << " ^^ " << " Looking up type witness for "
543
+ << proto->getName () << " :" << assocType->getName ()
544
+ << " on " << concreteType << " \n " ;
545
+ }
541
546
542
- auto typeWitness = t->getCanonicalType ();
547
+ auto t = concrete->getTypeWitness (assocType);
548
+ if (!t) {
549
+ if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
550
+ llvm::dbgs () << " ^^ " << " Type witness for " << assocType->getName ()
551
+ << " of " << concreteType << " could not be inferred\n " ;
552
+ }
543
553
544
- if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
545
- llvm::dbgs () << " ^^ " << " Type witness for " << assocType->getName ()
546
- << " of " << concreteType << " is " << typeWitness << " \n " ;
547
- }
554
+ t = ErrorType::get (concreteType);
555
+ }
548
556
549
- MutableTerm subjectType (key);
550
- subjectType.add (Symbol::forAssociatedType (proto, assocType->getName (),
551
- Context));
557
+ auto typeWitness = t->getCanonicalType ();
552
558
553
- MutableTerm constraintType;
559
+ if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
560
+ llvm::dbgs () << " ^^ " << " Type witness for " << assocType->getName ()
561
+ << " of " << concreteType << " is " << typeWitness << " \n " ;
562
+ }
554
563
555
- auto simplify = [&](CanType t) -> CanType {
556
- return CanType (t.transformRec ([&](Type t) -> Optional<Type> {
557
- if (!t->isTypeParameter ())
558
- return None;
564
+ MutableTerm subjectType (key);
565
+ subjectType.add (Symbol::forAssociatedType (proto, assocType->getName (),
566
+ Context));
559
567
560
- auto term = Context.getRelativeTermForType (t->getCanonicalType (),
561
- substitutions);
562
- System.simplify (term);
563
- return Context.getTypeForTerm (term, { });
564
- }));
565
- };
568
+ MutableTerm constraintType;
566
569
567
- if ( simplify (concreteType) == simplify (typeWitness) &&
568
- requirementKind == RequirementKind::SameType) {
569
- // FIXME: ConcreteTypeInDomainMap should support substitutions so
570
- // that we can remove this.
570
+ auto simplify = [&](CanType t) -> CanType {
571
+ return CanType (t. transformRec ([&](Type t) -> Optional<Type> {
572
+ if (!t-> isTypeParameter ())
573
+ return None;
571
574
572
- if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
573
- llvm::dbgs () << " ^^ Type witness is the same as the concrete type\n " ;
574
- }
575
+ auto term = Context.getRelativeTermForType (t->getCanonicalType (),
576
+ substitutions);
577
+ System.simplify (term);
578
+ return Context.getTypeForTerm (term, { });
579
+ }));
580
+ };
575
581
576
- // Add a rule T.[P:A] => T.
577
- constraintType = MutableTerm (key);
578
- } else {
579
- constraintType = computeConstraintTermForTypeWitness (
580
- key, concreteType, typeWitness, subjectType,
581
- substitutions);
582
- }
582
+ if (simplify (concreteType) == simplify (typeWitness) &&
583
+ requirementKind == RequirementKind::SameType) {
584
+ // FIXME: ConcreteTypeInDomainMap should support substitutions so
585
+ // that we can remove this.
583
586
584
- inducedRules.emplace_back (subjectType, constraintType);
585
- if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
586
- llvm::dbgs () << " ^^ Induced rule " << constraintType
587
- << " => " << subjectType << " \n " ;
588
- }
587
+ if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
588
+ llvm::dbgs () << " ^^ Type witness is the same as the concrete type\n " ;
589
589
}
590
+
591
+ // Add a rule T.[P:A] => T.
592
+ constraintType = MutableTerm (key);
593
+ } else {
594
+ constraintType = computeConstraintTermForTypeWitness (
595
+ key, concreteType, typeWitness, subjectType,
596
+ substitutions);
597
+ }
598
+
599
+ inducedRules.emplace_back (subjectType, constraintType);
600
+ if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
601
+ llvm::dbgs () << " ^^ Induced rule " << constraintType
602
+ << " => " << subjectType << " \n " ;
590
603
}
591
604
}
592
605
@@ -677,12 +690,36 @@ void PropertyMap::recordConcreteConformanceRules(
677
690
// minimizes as
678
691
//
679
692
// <T where T == Int>.
693
+ //
694
+ // We model this by marking unsatisfied conformance rules as conflicts.
695
+
696
+ // The conformances in ConcreteConformances should appear in the same
697
+ // order as the protocols in ConformsTo.
698
+ auto conformanceIter = props->ConcreteConformances .begin ();
699
+
680
700
for (unsigned i : indices (props->ConformsTo )) {
681
- auto *proto = props->ConformsTo [i];
682
701
auto conformanceRuleID = props->ConformsToRules [i];
702
+ if (conformanceIter == props->ConcreteConformances .end ()) {
703
+ // FIXME: We should mark the more specific rule of the conformance and
704
+ // concrete type rules as conflicting.
705
+ System.getRule (conformanceRuleID).markConflicting ();
706
+ continue ;
707
+ }
708
+
709
+ auto *proto = props->ConformsTo [i];
710
+ if (proto != (*conformanceIter)->getProtocol ()) {
711
+ // FIXME: We should mark the more specific rule of the conformance and
712
+ // concrete type rules as conflicting.
713
+ System.getRule (conformanceRuleID).markConflicting ();
714
+ continue ;
715
+ }
716
+
683
717
recordConcreteConformanceRule (concreteRuleID, conformanceRuleID, proto,
684
718
inducedRules);
719
+ ++conformanceIter;
685
720
}
721
+
722
+ assert (conformanceIter == props->ConcreteConformances .end ());
686
723
}
687
724
688
725
if (props->Superclass ) {
0 commit comments