@@ -630,3 +630,81 @@ SILType SILType::wrapAnyOptionalType(SILFunction &F) const {
630
630
BoundEnumDecl->getCanonicalType ());
631
631
return M.Types .getLoweredType (Pattern, BoundEnumDecl);
632
632
}
633
+
634
+ #ifndef NDEBUG
635
+ static bool areOnlyAbstractionDifferent (CanType type1, CanType type2) {
636
+ assert (type1->isLegalSILType ());
637
+ assert (type2->isLegalSILType ());
638
+
639
+ // Exact equality is fine.
640
+ if (type1 == type2)
641
+ return true ;
642
+
643
+ // Either both types should be optional or neither should be.
644
+ if (auto object1 = type1.getAnyOptionalObjectType ()) {
645
+ auto object2 = type2.getAnyOptionalObjectType ();
646
+ if (!object2)
647
+ return false ;
648
+ return areOnlyAbstractionDifferent (object1, object2);
649
+ }
650
+ if (type2.getAnyOptionalObjectType ())
651
+ return false ;
652
+
653
+ // Either both types should be tuples or neither should be.
654
+ if (auto tuple1 = dyn_cast<TupleType>(type1)) {
655
+ auto tuple2 = dyn_cast<TupleType>(type2);
656
+ if (!tuple2)
657
+ return false ;
658
+ if (tuple1->getNumElements () != tuple2->getNumElements ())
659
+ return false ;
660
+ for (auto i : indices (tuple2->getElementTypes ()))
661
+ if (!areOnlyAbstractionDifferent (tuple1.getElementType (i),
662
+ tuple2.getElementType (i)))
663
+ return false ;
664
+ return true ;
665
+ }
666
+ if (isa<TupleType>(type2))
667
+ return false ;
668
+
669
+ // Either both types should be metatypes or neither should be.
670
+ if (auto meta1 = dyn_cast<AnyMetatypeType>(type1)) {
671
+ auto meta2 = dyn_cast<AnyMetatypeType>(type2);
672
+ if (!meta2)
673
+ return false ;
674
+ if (meta1.getInstanceType () != meta2.getInstanceType ())
675
+ return false ;
676
+ return true ;
677
+ }
678
+
679
+ // Either both types should be functions or neither should be.
680
+ if (auto fn1 = dyn_cast<SILFunctionType>(type1)) {
681
+ auto fn2 = dyn_cast<SILFunctionType>(type2);
682
+ if (!fn2)
683
+ return false ;
684
+ // TODO: maybe there are checks we can do here?
685
+ (void )fn1;
686
+ (void )fn2;
687
+ return true ;
688
+ }
689
+ if (isa<SILFunctionType>(type2))
690
+ return false ;
691
+
692
+ llvm_unreachable (" no other types should differ by abstraction" );
693
+ }
694
+ #endif
695
+
696
+ // / Given two SIL types which are representations of the same type,
697
+ // / check whether they have an abstraction difference.
698
+ bool SILType::hasAbstractionDifference (SILFunctionTypeRepresentation rep,
699
+ SILType type2) {
700
+ CanType ct1 = getSwiftRValueType ();
701
+ CanType ct2 = type2.getSwiftRValueType ();
702
+ assert (getSILFunctionLanguage (rep) == SILFunctionLanguage::C ||
703
+ areOnlyAbstractionDifferent (ct1, ct2));
704
+ (void )ct1;
705
+ (void )ct2;
706
+
707
+ // Assuming that we've applied the same substitutions to both types,
708
+ // abstraction equality should equal type equality.
709
+ return (*this != type2);
710
+ }
0 commit comments