@@ -503,6 +503,18 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
503503 auto *proto = conformsTo[i];
504504 unsigned conformanceRuleID = conformsToRules[i];
505505
506+ // If we've already processed this pair of rules, record the conformance
507+ // and move on.
508+ //
509+ // This occurs when a pair of rules are inherited from the property map
510+ // entry for this key's suffix.
511+ auto pair = std::make_pair (concreteRuleID, conformanceRuleID);
512+ auto found = ConcreteConformances.find (pair);
513+ if (found != ConcreteConformances.end ()) {
514+ conformances.push_back (found->second );
515+ continue ;
516+ }
517+
506518 // FIXME: Either remove the ModuleDecl entirely from conformance lookup,
507519 // or pass the correct one down in here.
508520 auto *module = proto->getParentModule ();
@@ -539,20 +551,17 @@ void PropertyMap::concretizeNestedTypesFromConcreteParent(
539551 // opaque result type?
540552 assert (!conformance.isAbstract ());
541553
554+ // Save this conformance for later.
542555 auto *concrete = conformance.getConcrete ();
556+ auto inserted = ConcreteConformances.insert (
557+ std::make_pair (pair, concrete));
558+ assert (inserted.second );
559+ (void ) inserted;
543560
544561 // Record the conformance for use by
545562 // PropertyBag::getConformsToExcludingSuperclassConformances().
546563 conformances.push_back (concrete);
547564
548- // All subsequent logic just records new rewrite rules, and can be
549- // skipped if we've already processed this pair of rules.
550- if (!ConcreteConformanceRules.insert (
551- std::make_pair (concreteRuleID, conformanceRuleID)).second ) {
552- // We've already processed this pair of rules.
553- continue ;
554- }
555-
556565 auto concreteConformanceSymbol = Symbol::forConcreteConformance (
557566 concreteType, substitutions, proto, Context);
558567
0 commit comments