@@ -943,6 +943,55 @@ AbstractionPattern AbstractionPattern::getReferenceStorageReferentType() const {
943
943
llvm_unreachable (" bad kind" );
944
944
}
945
945
946
+ static CanType getExistentialConstraintType (CanType type) {
947
+ assert (type.isExistentialType ());
948
+ if (auto *ET = type->getAs <ExistentialType>()) {
949
+ return CanType (ET->getConstraintType ());
950
+ }
951
+ return type;
952
+ }
953
+
954
+ AbstractionPattern AbstractionPattern::getExistentialConstraintType () const {
955
+ switch (getKind ()) {
956
+ case Kind::Invalid:
957
+ llvm_unreachable (" querying invalid abstraction pattern!" );
958
+ case Kind::ObjCMethodType:
959
+ case Kind::CurriedObjCMethodType:
960
+ case Kind::PartialCurriedObjCMethodType:
961
+ case Kind::CFunctionAsMethodType:
962
+ case Kind::CurriedCFunctionAsMethodType:
963
+ case Kind::PartialCurriedCFunctionAsMethodType:
964
+ case Kind::CXXMethodType:
965
+ case Kind::CurriedCXXMethodType:
966
+ case Kind::PartialCurriedCXXMethodType:
967
+ case Kind::Tuple:
968
+ case Kind::OpaqueFunction:
969
+ case Kind::OpaqueDerivativeFunction:
970
+ case Kind::ObjCCompletionHandlerArgumentsType:
971
+ llvm_unreachable (" pattern for function or tuple cannot be for optional" );
972
+
973
+ case Kind::Opaque:
974
+ return *this ;
975
+
976
+ case Kind::Type:
977
+ if (isTypeParameterOrOpaqueArchetype ())
978
+ return AbstractionPattern::getOpaque ();
979
+ return AbstractionPattern (getGenericSignature (),
980
+ ::getExistentialConstraintType (getType()));
981
+
982
+ case Kind::Discard:
983
+ return AbstractionPattern::getDiscard (
984
+ getGenericSignature (), ::getExistentialConstraintType (getType ()));
985
+
986
+ case Kind::ClangType:
987
+ // This is not reflected in clang types.
988
+ return AbstractionPattern (getGenericSignature (),
989
+ ::getExistentialConstraintType (getType()),
990
+ getClangType());
991
+ }
992
+ llvm_unreachable (" bad kind" );
993
+ }
994
+
946
995
void AbstractionPattern::dump () const {
947
996
print (llvm::errs ());
948
997
llvm::errs () << " \n " ;
@@ -1683,6 +1732,44 @@ class SubstFunctionTypePatternVisitor
1683
1732
llvm_unreachable (" Unimplemented!" );
1684
1733
}
1685
1734
1735
+ CanType visitExistentialType (ExistentialType *exist,
1736
+ AbstractionPattern pattern) {
1737
+ if (auto gp = handleTypeParameterInAbstractionPattern (pattern, exist))
1738
+ return gp;
1739
+
1740
+ // Avoid walking into the constraint type if we can help it.
1741
+ if (!exist->hasTypeParameter () && !exist->hasArchetype () &&
1742
+ !exist->hasOpaqueArchetype ()) {
1743
+ return CanType (exist);
1744
+ }
1745
+
1746
+ return CanExistentialType::get (visit (
1747
+ exist->getConstraintType (), pattern.getExistentialConstraintType ()));
1748
+ }
1749
+
1750
+ CanType visitParameterizedProtocolType (ParameterizedProtocolType *ppt,
1751
+ AbstractionPattern pattern) {
1752
+ if (auto gp = handleTypeParameterInAbstractionPattern (pattern, ppt))
1753
+ return gp;
1754
+
1755
+ // Recurse into the arguments of the parameterized protocol.
1756
+ SmallVector<Type, 4 > substArgs;
1757
+ auto origPPT = pattern.getAs <ParameterizedProtocolType>();
1758
+ if (!origPPT)
1759
+ return CanType (ppt);
1760
+
1761
+ for (unsigned i = 0 ; i < ppt->getArgs ().size (); ++i) {
1762
+ auto argTy = ppt->getArgs ()[i];
1763
+ auto origArgTy = AbstractionPattern (pattern.getGenericSignatureOrNull (),
1764
+ origPPT.getArgs ()[i]);
1765
+ auto substEltTy = visit (argTy, origArgTy);
1766
+ substArgs.push_back (substEltTy);
1767
+ }
1768
+
1769
+ return CanType (ParameterizedProtocolType::get (
1770
+ TC.Context , ppt->getBaseType (), substArgs));
1771
+ }
1772
+
1686
1773
CanType visitTupleType (TupleType *tuple, AbstractionPattern pattern) {
1687
1774
if (auto gp = handleTypeParameterInAbstractionPattern (pattern, tuple))
1688
1775
return gp;
0 commit comments