@@ -404,7 +404,7 @@ void PropertyMap::computeConcreteTypeInDomainMap() {
404404}
405405
406406void PropertyMap::concretizeNestedTypesFromConcreteParents (
407- SmallVectorImpl<InducedRule> &inducedRules) const {
407+ SmallVectorImpl<InducedRule> &inducedRules) {
408408 for (const auto &props : Entries) {
409409 if (props->getConformsTo ().empty ())
410410 continue ;
@@ -426,8 +426,10 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
426426 concretizeNestedTypesFromConcreteParent (
427427 props->getKey (),
428428 RequirementKind::SameType,
429+ *props->ConcreteTypeRule ,
429430 props->ConcreteType ->getConcreteType (),
430431 props->ConcreteType ->getSubstitutions (),
432+ props->ConformsToRules ,
431433 props->ConformsTo ,
432434 props->ConcreteConformances ,
433435 inducedRules);
@@ -441,9 +443,11 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
441443 concretizeNestedTypesFromConcreteParent (
442444 props->getKey (),
443445 RequirementKind::Superclass,
446+ *props->SuperclassRule ,
444447 props->Superclass ->getSuperclass (),
445448 props->Superclass ->getSubstitutions (),
446- props->getConformsTo (),
449+ props->ConformsToRules ,
450+ props->ConformsTo ,
447451 props->SuperclassConformances ,
448452 inducedRules);
449453 }
@@ -484,22 +488,45 @@ void PropertyMap::concretizeNestedTypesFromConcreteParents(
484488// /
485489void PropertyMap::concretizeNestedTypesFromConcreteParent (
486490 Term key, RequirementKind requirementKind,
487- CanType concreteType, ArrayRef<Term> substitutions,
491+ unsigned concreteRuleID,
492+ CanType concreteType,
493+ ArrayRef<Term> substitutions,
494+ ArrayRef<unsigned > conformsToRules,
488495 ArrayRef<const ProtocolDecl *> conformsTo,
489496 llvm::TinyPtrVector<ProtocolConformance *> &conformances,
490- SmallVectorImpl<InducedRule> &inducedRules) const {
497+ SmallVectorImpl<InducedRule> &inducedRules) {
491498 assert (requirementKind == RequirementKind::SameType ||
492499 requirementKind == RequirementKind::Superclass);
500+ assert (conformsTo.size () == conformsToRules.size ());
501+
502+ for (unsigned i : indices (conformsTo)) {
503+ auto *proto = conformsTo[i];
504+ unsigned conformanceRuleID = conformsToRules[i];
493505
494- for (auto *proto : conformsTo) {
495506 // FIXME: Either remove the ModuleDecl entirely from conformance lookup,
496507 // or pass the correct one down in here.
497508 auto *module = proto->getParentModule ();
498509
499510 auto conformance = module ->lookupConformance (concreteType,
500511 const_cast <ProtocolDecl *>(proto));
501512 if (conformance.isInvalid ()) {
502- // FIXME: Diagnose conflict
513+ // For superclass rules, it is totally fine to have a signature like:
514+ //
515+ // protocol P {}
516+ // class C {}
517+ // <T where T : P, T : C>
518+ //
519+ // There is no relation between P and C here.
520+ //
521+ // With concrete types, a missing conformance is a conflict.
522+ if (requirementKind == RequirementKind::SameType) {
523+ // FIXME: Diagnose conflict
524+ //
525+ // FIXME: We should mark the more specific rule of the two
526+ // as conflicting.
527+ System.getRule (conformanceRuleID).markConflicting ();
528+ }
529+
503530 if (Debug.contains (DebugFlags::ConcretizeNestedTypes)) {
504531 llvm::dbgs () << " ^^ " << concreteType << " does not conform to "
505532 << proto->getName () << " \n " ;
@@ -514,6 +541,9 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
514541
515542 auto *concrete = conformance.getConcrete ();
516543
544+ recordConcreteConformanceRule (concreteRuleID, conformanceRuleID, proto,
545+ inducedRules);
546+
517547 // Record the conformance for use by
518548 // PropertyBag::getConformsToExcludingSuperclassConformances().
519549 conformances.push_back (concrete);
@@ -672,92 +702,6 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
672702 return constraintType;
673703}
674704
675- void PropertyMap::recordConcreteConformanceRules (
676- SmallVectorImpl<InducedRule> &inducedRules) {
677- for (const auto &props : Entries) {
678- if (props->getConformsTo ().empty ())
679- continue ;
680-
681- if (props->ConcreteType ) {
682- unsigned concreteRuleID = *props->ConcreteTypeRule ;
683-
684- // The GSB drops all conformance requirements on a type parameter equated
685- // to a concrete type, even if the concrete type doesn't conform. That is,
686- //
687- // protocol P {}
688- // <T where T : P, T == Int>
689- //
690- // minimizes as
691- //
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-
700- for (unsigned i : indices (props->ConformsTo )) {
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-
717- recordConcreteConformanceRule (concreteRuleID, conformanceRuleID, proto,
718- inducedRules);
719- ++conformanceIter;
720- }
721-
722- assert (conformanceIter == props->ConcreteConformances .end ());
723- }
724-
725- if (props->Superclass ) {
726- unsigned superclassRuleID = *props->SuperclassRule ;
727-
728- // For superclass rules, we only introduce a concrete conformance if the
729- // superclass actually conforms. Otherwise, it is totally fine to have a
730- // signature like
731- //
732- // protocol P {}
733- // class C {}
734- // <T where T : P, T : C>
735- //
736- // There is no relation between P and C here.
737-
738- // The conformances in SuperclassConformances should appear in the same
739- // order as the protocols in ConformsTo.
740- auto conformanceIter = props->SuperclassConformances .begin ();
741-
742- for (unsigned i : indices (props->ConformsTo )) {
743- if (conformanceIter == props->SuperclassConformances .end ())
744- break ;
745-
746- auto *proto = props->ConformsTo [i];
747- if (proto != (*conformanceIter)->getProtocol ())
748- continue ;
749-
750- unsigned conformanceRuleID = props->ConformsToRules [i];
751- recordConcreteConformanceRule (superclassRuleID, conformanceRuleID, proto,
752- inducedRules);
753- ++conformanceIter;
754- }
755-
756- assert (conformanceIter == props->SuperclassConformances .end ());
757- }
758- }
759- }
760-
761705void PropertyMap::recordConcreteConformanceRule (
762706 unsigned concreteRuleID,
763707 unsigned conformanceRuleID,
0 commit comments