@@ -56,7 +56,12 @@ SubstitutionMap::SubstitutionMap(
5656 GenericSignature genericSig,
5757 ArrayRef<Type> replacementTypes,
5858 ArrayRef<ProtocolConformanceRef> conformances)
59- : storage(Storage::get(genericSig, replacementTypes, conformances)) { }
59+ : storage(Storage::get(genericSig, replacementTypes, conformances)) {
60+ #ifndef NDEBUG
61+ if (genericSig->getASTContext ().LangOpts .VerifyAllSubstitutionMaps )
62+ verify ();
63+ #endif
64+ }
6065
6166ArrayRef<Type> SubstitutionMap::getReplacementTypesBuffer () const {
6267 return storage ? storage->getReplacementTypes () : ArrayRef<Type>();
@@ -355,8 +360,10 @@ SubstitutionMap::lookupConformance(CanType type, ProtocolDecl *proto) const {
355360 // Check whether the superclass conforms.
356361 if (auto superclass = genericSig->getSuperclassBound (type)) {
357362 LookUpConformanceInSignature lookup (getGenericSignature ().getPointer ());
358- if (auto conformance = lookup (type->getCanonicalType (), superclass, proto))
363+ auto substType = type.subst (*this );
364+ if (auto conformance = lookup (type->getCanonicalType (), substType, proto)){
359365 return conformance;
366+ }
360367 }
361368
362369 // If the type doesn't conform to this protocol, the result isn't formed
@@ -474,7 +481,7 @@ SubstitutionMap SubstitutionMap::subst(TypeSubstitutionFn subs,
474481 newConformances.push_back (
475482 conformance.subst (substType, subs, conformances, options));
476483 }
477-
484+
478485 oldConformances = oldConformances.slice (1 );
479486 }
480487
@@ -657,6 +664,7 @@ void SubstitutionMap::verify() const {
657664 if (req.getKind () != RequirementKind::Conformance)
658665 continue ;
659666
667+ SWIFT_DEFER { ++conformanceIndex; };
660668 auto substType = req.getFirstType ().subst (*this );
661669 if (substType->isTypeParameter () ||
662670 substType->is <ArchetypeType>() ||
@@ -677,15 +685,44 @@ void SubstitutionMap::verify() const {
677685 llvm::dbgs () << " SubstitutionMap:\n " ;
678686 dump (llvm::dbgs ());
679687 llvm::dbgs () << " \n " ;
688+ llvm::dbgs () << " Requirement:\n " ;
689+ req.dump (llvm::dbgs ());
690+ llvm::dbgs () << " \n " ;
680691 }
681692 assert (conformance.isConcrete () && " Conformance should be concrete" );
693+
694+ if (substType->is <UnboundGenericType>())
695+ continue ;
696+
697+ auto conformanceTy = conformance.getConcrete ()->getType ();
698+ if (conformanceTy->hasTypeParameter ()
699+ && !substType->hasTypeParameter ()) {
700+ conformanceTy = conformance.getConcrete ()->getDeclContext ()
701+ ->mapTypeIntoContext (conformanceTy);
702+ }
703+
704+ if (!substType->isEqual (conformanceTy)) {
705+ llvm::dbgs () << " Conformance must match concrete replacement type:\n " ;
706+ substType->dump (llvm::dbgs ());
707+ llvm::dbgs () << " Conformance type:\n " ;
708+ conformance.getConcrete ()->getType ()->dump (llvm::dbgs ());
709+ llvm::dbgs () << " Conformance:\n " ;
710+ conformance.dump (llvm::dbgs ());
711+ llvm::dbgs () << " \n " ;
712+ llvm::dbgs () << " SubstitutionMap:\n " ;
713+ dump (llvm::dbgs ());
714+ llvm::dbgs () << " \n " ;
715+ llvm::dbgs () << " Requirement:\n " ;
716+ req.dump (llvm::dbgs ());
717+ llvm::dbgs () << " \n " ;
718+ }
719+ assert (substType->isEqual (conformanceTy)
720+ && " conformance should match corresponding type" );
682721
683722 if (substType->isExistentialType ()) {
684723 assert (isa<SelfProtocolConformance>(conformance.getConcrete ()) &&
685724 " Existential type cannot have normal conformance" );
686725 }
687-
688- ++conformanceIndex;
689726 }
690727#endif
691728}
0 commit comments