@@ -827,6 +827,9 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
827827 // We collect conformance requirements to check that they're minimal.
828828 llvm::SmallDenseMap<CanType, SmallVector<ProtocolDecl *, 2 >, 2 > conformances;
829829
830+ // We collect same-type requirements to check that they're minimal.
831+ llvm::SmallDenseMap<CanType, SmallVector<Type, 2 >, 2 > sameTypeComponents;
832+
830833 // Check that the requirements satisfy certain invariants.
831834 for (unsigned idx : indices (reqts)) {
832835 const auto &reqt = reqts[idx].getCanonical ();
@@ -873,6 +876,10 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
873876
874877 auto firstType = reqt.getFirstType ();
875878 auto secondType = reqt.getSecondType ();
879+
880+ auto canType = canSig->getCanonicalTypeInContext (firstType);
881+ auto &component = sameTypeComponents[canType];
882+
876883 if (!hasCanonicalOrConcreteParent (firstType)) {
877884 llvm::errs () << " Left hand side does not have a canonical parent: " ;
878885 reqt.dump (llvm::errs ());
@@ -893,13 +900,34 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
893900 llvm::errs () << " \n " ;
894901 abort ();
895902 }
903+
904+ if (component.empty ()) {
905+ component.push_back (firstType);
906+ } else if (!component.back ()->isEqual (firstType)) {
907+ llvm::errs () << " Same-type requirement within an equiv. class "
908+ << " is out-of-order: " ;
909+ reqt.dump (llvm::errs ());
910+ llvm::errs () << " \n " ;
911+ abort ();
912+ }
913+
914+ component.push_back (secondType);
896915 } else {
897916 if (!canSig->isCanonicalTypeInContext (secondType)) {
898917 llvm::errs () << " Right hand side is not canonical: " ;
899918 reqt.dump (llvm::errs ());
900919 llvm::errs () << " \n " ;
901920 abort ();
902921 }
922+
923+ if (component.empty ()) {
924+ component.push_back (secondType);
925+ } else if (!component.back ()->isEqual (secondType)) {
926+ llvm::errs () << " Inconsistent concrete requirement in equiv. class: " ;
927+ reqt.dump (llvm::errs ());
928+ llvm::errs () << " \n " ;
929+ abort ();
930+ }
903931 }
904932 break ;
905933 }
@@ -925,33 +953,6 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
925953 abort ();
926954 }
927955
928- // If we have two same-type requirements where the left-hand sides differ
929- // but fall into the same equivalence class, we can check the form.
930- if (compareLHS < 0 && reqt.getKind () == RequirementKind::SameType &&
931- prevReqt.getKind () == RequirementKind::SameType &&
932- canSig->areSameTypeParameterInContext (prevReqt.getFirstType (),
933- reqt.getFirstType ())) {
934- // If it's a it's a type parameter, make sure the equivalence class is
935- // wired together sanely.
936- if (prevReqt.getSecondType ()->isTypeParameter ()) {
937- if (!prevReqt.getSecondType ()->isEqual (reqt.getFirstType ())) {
938- llvm::errs () << " Same-type requirement within an equiv. class "
939- << " is out-of-order: " ;
940- reqt.dump (llvm::errs ());
941- llvm::errs () << " \n " ;
942- abort ();
943- }
944- } else {
945- // Otherwise, the concrete types must match up.
946- if (!prevReqt.getSecondType ()->isEqual (reqt.getSecondType ())) {
947- llvm::errs () << " Inconsistent concrete requirement in equiv. class: " ;
948- reqt.dump (llvm::errs ());
949- llvm::errs () << " \n " ;
950- abort ();
951- }
952- }
953- }
954-
955956 // If we have a concrete same-type requirement, we shouldn't have any
956957 // other requirements on the same type.
957958 if (reqt.getKind () == RequirementKind::SameType &&
@@ -974,7 +975,7 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
974975 }
975976
976977 // Make sure we don't have redundant protocol conformance requirements.
977- for (auto pair : conformances) {
978+ for (const auto & pair : conformances) {
978979 const auto &protos = pair.second ;
979980 auto canonicalProtos = protos;
980981
@@ -992,6 +993,18 @@ void GenericSignature::verify(ArrayRef<Requirement> reqts) const {
992993 abort ();
993994 }
994995 }
996+
997+ // Check same-type components for consistency.
998+ for (const auto &pair : sameTypeComponents) {
999+ if (pair.second .front ()->isTypeParameter () &&
1000+ !canSig->isCanonicalTypeInContext (pair.second .front ())) {
1001+ llvm::errs () << " Abstract same-type requirement involving concrete types\n " ;
1002+ llvm::errs () << " Canonical type: " << pair.first << " \n " ;
1003+ llvm::errs () << " Left hand side of first requirement: "
1004+ << pair.second .front () << " \n " ;
1005+ abort ();
1006+ }
1007+ }
9951008}
9961009
9971010static Type stripBoundDependentMemberTypes (Type t) {
0 commit comments