@@ -60,10 +60,8 @@ SubstitutionMap::SubstitutionMap(
60
60
ArrayRef<Type> replacementTypes,
61
61
ArrayRef<ProtocolConformanceRef> conformances)
62
62
: storage(Storage::get(genericSig, replacementTypes, conformances)) {
63
- #ifndef NDEBUG
64
63
if (genericSig->getASTContext ().LangOpts .VerifyAllSubstitutionMaps )
65
64
verify ();
66
- #endif
67
65
}
68
66
69
67
ArrayRef<ProtocolConformanceRef> SubstitutionMap::getConformances () const {
@@ -534,78 +532,109 @@ SubstitutionMap::getOverrideSubstitutions(const NominalTypeDecl *baseNominal,
534
532
LookUpConformanceInOverrideSubs (info));
535
533
}
536
534
537
- void SubstitutionMap::verify () const {
538
- #ifndef NDEBUG
535
+ void SubstitutionMap::verify (bool allowInvalid) const {
539
536
if (empty ())
540
537
return ;
541
538
539
+ auto genericSig = getGenericSignature ();
540
+ auto &ctx = genericSig->getASTContext ();
541
+
542
+ if (ctx.isRecursivelyConstructingRequirementMachine (
543
+ genericSig.getCanonicalSignature ()))
544
+ return ;
545
+
542
546
unsigned conformanceIndex = 0 ;
543
547
544
- for (const auto &req : getGenericSignature () .getRequirements ()) {
548
+ for (const auto &req : genericSig .getRequirements ()) {
545
549
if (req.getKind () != RequirementKind::Conformance)
546
550
continue ;
547
551
548
552
SWIFT_DEFER { ++conformanceIndex; };
553
+ auto conformance = getConformances ()[conformanceIndex];
554
+
549
555
auto substType = req.getFirstType ().subst (*this );
550
- if (substType->isTypeParameter () ||
551
- substType->is <ArchetypeType>() ||
552
- substType->isTypeVariableOrMember () ||
553
- substType->is <UnresolvedType>() ||
554
- substType->hasError ())
555
- continue ;
556
556
557
- auto conformance = getConformances ()[conformanceIndex];
557
+ // Unwrap various strange things.
558
+ substType = substType->getReferenceStorageReferent ();
559
+ if (auto *selfType = substType->getAs <DynamicSelfType>())
560
+ substType = selfType->getSelfType ();
558
561
559
- if (conformance.isInvalid ())
560
- continue ;
562
+ // Don't bother validating these cases.
563
+ if (allowInvalid && substType->hasUnboundGenericType ())
564
+ return ;
565
+
566
+ if (conformance.isInvalid ()) {
567
+ if (!allowInvalid) {
568
+ llvm::errs () << " Unexpected invalid conformance in substitution map:\n " ;
569
+ dump (llvm::dbgs ());
570
+ llvm::errs () << " \n " ;
571
+ abort ();
572
+ }
561
573
562
- // All of the conformances should be concrete.
563
- if (!conformance.isConcrete ()) {
564
- llvm::dbgs () << " Concrete type cannot have abstract conformance:\n " ;
565
- substType->dump (llvm::dbgs ());
566
- llvm::dbgs () << " SubstitutionMap:\n " ;
567
- dump (llvm::dbgs ());
568
- llvm::dbgs () << " \n " ;
569
- llvm::dbgs () << " Requirement:\n " ;
570
- req.dump (llvm::dbgs ());
571
- llvm::dbgs () << " \n " ;
574
+ continue ;
572
575
}
573
- assert (conformance.isConcrete () && " Conformance should be concrete" );
574
-
575
- if (substType->is <UnboundGenericType>())
576
+
577
+ if (conformance.isAbstract ()) {
578
+ if (!substType->isTypeParameter () &&
579
+ !substType->is <PackElementType>() &&
580
+ !substType->is <ArchetypeType>() &&
581
+ !substType->isTypeVariableOrMember () &&
582
+ !substType->is <UnresolvedType>() &&
583
+ !substType->is <PlaceholderType>() &&
584
+ !substType->is <ErrorType>()) {
585
+ llvm::errs () << " Unexpected abstract conformance in substitution map:\n " ;
586
+ dump (llvm::errs ());
587
+ llvm::errs () << " \n " ;
588
+ abort ();
589
+ }
590
+
576
591
continue ;
577
-
578
- auto conformanceTy = conformance.getConcrete ()->getType ();
579
- if (conformanceTy->hasTypeParameter ()
580
- && !substType->hasTypeParameter ()) {
581
- conformanceTy = conformance.getConcrete ()->getDeclContext ()
582
- ->mapTypeIntoContext (conformanceTy);
583
592
}
584
-
585
- if (!substType->isEqual (conformanceTy)) {
586
- llvm::dbgs () << " Conformance must match concrete replacement type:\n " ;
587
- substType->dump (llvm::dbgs ());
588
- llvm::dbgs () << " Conformance type:\n " ;
589
- conformance.getConcrete ()->getType ()->dump (llvm::dbgs ());
590
- llvm::dbgs () << " Conformance:\n " ;
591
- conformance.dump (llvm::dbgs ());
592
- llvm::dbgs () << " \n " ;
593
- llvm::dbgs () << " SubstitutionMap:\n " ;
594
- dump (llvm::dbgs ());
595
- llvm::dbgs () << " \n " ;
596
- llvm::dbgs () << " Requirement:\n " ;
597
- req.dump (llvm::dbgs ());
598
- llvm::dbgs () << " \n " ;
593
+
594
+ if (conformance.isPack ()) {
595
+ // FIXME: Implement some kind of check here.
596
+ continue ;
599
597
}
600
- assert (substType-> isEqual (conformanceTy)
601
- && " conformance should match corresponding type " );
598
+
599
+ auto *concrete = conformance. getConcrete ( );
602
600
603
601
if (substType->isExistentialType ()) {
604
- assert (isa<SelfProtocolConformance>(conformance.getConcrete ()) &&
605
- " Existential type cannot have normal conformance" );
602
+ if (req.getProtocolDecl ()->isSpecificProtocol (KnownProtocolKind::Sendable) &&
603
+ isa<BuiltinProtocolConformance>(concrete)) {
604
+ continue ;
605
+ }
606
+
607
+ if (!isa<SelfProtocolConformance>(concrete)) {
608
+ // A superclass-constrained self-conforming existential might conform
609
+ // concretely.
610
+ if (substType->getSuperclass ())
611
+ continue ;
612
+
613
+ llvm::errs () << " Expected to find a self conformance:\n " ;
614
+ substType->dump (llvm::errs ());
615
+ llvm::errs () << " Substitution map:\n " ;
616
+ dump (llvm::errs ());
617
+ llvm::errs () << " \n " ;
618
+ abort ();
619
+ }
620
+
621
+ continue ;
622
+ }
623
+
624
+ if (substType->isTypeParameter ())
625
+ continue ;
626
+
627
+ if (!concrete->getType ()->isEqual (substType)) {
628
+ llvm::errs () << " Conformance with wrong conforming type:\n " ;
629
+ concrete->getType ()->dump (llvm::errs ());
630
+ llvm::errs () << " Should be:\n " ;
631
+ substType->dump (llvm::errs ());
632
+ llvm::errs () << " Substitution map:\n " ;
633
+ dump (llvm::errs ());
634
+ llvm::errs () << " \n " ;
635
+ abort ();
606
636
}
607
637
}
608
- #endif
609
638
}
610
639
611
640
void SubstitutionMap::profile (llvm::FoldingSetNodeID &id) const {
0 commit comments