@@ -943,6 +943,55 @@ AbstractionPattern AbstractionPattern::getReferenceStorageReferentType() const {
943943 llvm_unreachable (" bad kind" );
944944}
945945
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+
946995void AbstractionPattern::dump () const {
947996 print (llvm::errs ());
948997 llvm::errs () << " \n " ;
@@ -1683,6 +1732,44 @@ class SubstFunctionTypePatternVisitor
16831732 llvm_unreachable (" Unimplemented!" );
16841733 }
16851734
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+
16861773 CanType visitTupleType (TupleType *tuple, AbstractionPattern pattern) {
16871774 if (auto gp = handleTypeParameterInAbstractionPattern (pattern, tuple))
16881775 return gp;
0 commit comments