@@ -428,7 +428,7 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
428428 RequirementKind::SameType,
429429 props->ConcreteType ->getConcreteType (),
430430 props->ConcreteType ->getSubstitutions (),
431- props->getConformsTo () ,
431+ props->ConformsTo ,
432432 props->ConcreteConformances ,
433433 inducedRules);
434434 }
@@ -523,70 +523,83 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
523523 continue ;
524524
525525 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+ }
531533
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 {
538540
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+ }
541546
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+ }
543553
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+ }
548556
549- MutableTerm subjectType (key);
550- subjectType.add (Symbol::forAssociatedType (proto, assocType->getName (),
551- Context));
557+ auto typeWitness = t->getCanonicalType ();
552558
553- MutableTerm constraintType;
559+ if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
560+ llvm::dbgs () << " ^^ " << " Type witness for " << assocType->getName ()
561+ << " of " << concreteType << " is " << typeWitness << " \n " ;
562+ }
554563
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));
559567
560- auto term = Context.getRelativeTermForType (t->getCanonicalType (),
561- substitutions);
562- System.simplify (term);
563- return Context.getTypeForTerm (term, { });
564- }));
565- };
568+ MutableTerm constraintType;
566569
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;
571574
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+ };
575581
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.
583586
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 " ;
589589 }
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 " ;
590603 }
591604}
592605
@@ -677,12 +690,36 @@ void PropertyMap::recordConcreteConformanceRules(
677690 // minimizes as
678691 //
679692 // <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+
680700 for (unsigned i : indices (props->ConformsTo )) {
681- auto *proto = props->ConformsTo [i];
682701 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+
683717 recordConcreteConformanceRule (concreteRuleID, conformanceRuleID, proto,
684718 inducedRules);
719+ ++conformanceIter;
685720 }
721+
722+ assert (conformanceIter == props->ConcreteConformances .end ());
686723 }
687724
688725 if (props->Superclass ) {
0 commit comments