@@ -755,36 +755,53 @@ Type ASTBuilder::createExistentialMetatypeType(
755755Type ASTBuilder::createConstrainedExistentialType (
756756 Type base, ArrayRef<BuiltRequirement> constraints,
757757 ArrayRef<BuiltInverseRequirement> inverseRequirements) {
758- // FIXME: Generalize to other kinds of bases.
759- if (!base->getAs <ProtocolType>())
760- return Type ();
761- auto baseTy = base->castTo <ProtocolType>();
762- auto baseDecl = baseTy->getDecl ();
763- llvm::SmallDenseMap<Identifier, Type> cmap;
764- for (const auto &req : constraints) {
765- switch (req.getKind ()) {
766- case RequirementKind::SameShape:
767- llvm_unreachable (" Same-shape requirement not supported here" );
768- case RequirementKind::Conformance:
769- case RequirementKind::Superclass:
770- case RequirementKind::Layout:
771- continue ;
758+ Type constrainedBase;
759+
760+ if (auto baseTy = base->getAs <ProtocolType>()) {
761+ auto baseDecl = baseTy->getDecl ();
762+ llvm::SmallDenseMap<Identifier, Type> cmap;
763+ for (const auto &req : constraints) {
764+ switch (req.getKind ()) {
765+ case RequirementKind::SameShape:
766+ llvm_unreachable (" Same-shape requirement not supported here" );
767+ case RequirementKind::Conformance:
768+ case RequirementKind::Superclass:
769+ case RequirementKind::Layout:
770+ continue ;
772771
773- case RequirementKind::SameType:
774- if (auto *DMT = req.getFirstType ()->getAs <DependentMemberType>())
775- cmap[DMT->getName ()] = req.getSecondType ();
772+ case RequirementKind::SameType:
773+ if (auto *DMT = req.getFirstType ()->getAs <DependentMemberType>())
774+ cmap[DMT->getName ()] = req.getSecondType ();
775+ }
776776 }
777- }
778- llvm::SmallVector<Type, 4 > args;
779- for (auto *assocTy : baseDecl->getPrimaryAssociatedTypes ()) {
780- auto argTy = cmap.find (assocTy->getName ());
781- if (argTy == cmap.end ()) {
782- return Type ();
777+ llvm::SmallVector<Type, 4 > args;
778+ for (auto *assocTy : baseDecl->getPrimaryAssociatedTypes ()) {
779+ auto argTy = cmap.find (assocTy->getName ());
780+ if (argTy == cmap.end ()) {
781+ return Type ();
782+ }
783+ args.push_back (argTy->getSecond ());
784+ }
785+
786+ // We may not have any arguments because the constrained existential is a
787+ // plain protocol with an inverse requirement.
788+ if (args.empty ()) {
789+ constrainedBase =
790+ ProtocolType::get (baseDecl, baseTy, base->getASTContext ());
791+ } else {
792+ constrainedBase =
793+ ParameterizedProtocolType::get (base->getASTContext (), baseTy, args);
783794 }
784- args.push_back (argTy->getSecond ());
795+ } else if (base->isAny ()) {
796+ // The only other case should be that we got an empty PCT, which is equal to
797+ // the Any type. The other constraints should have been encoded in the
798+ // existential's generic signature (and arrive as BuiltInverseRequirement).
799+ constrainedBase = base;
800+ } else {
801+ return Type ();
785802 }
786- Type constrainedBase =
787- ParameterizedProtocolType::get (base-> getASTContext (), baseTy, args );
803+
804+ assert (constrainedBase );
788805
789806 // Handle inverse requirements.
790807 if (!inverseRequirements.empty ()) {
0 commit comments