@@ -732,47 +732,54 @@ Type ASTBuilder::createExistentialMetatypeType(
732732Type ASTBuilder::createConstrainedExistentialType (
733733 Type base, ArrayRef<BuiltRequirement> constraints,
734734 ArrayRef<BuiltInverseRequirement> inverseRequirements) {
735- // FIXME: Generalize to other kinds of bases.
736- if (!base->getAs <ProtocolType>())
737- return Type ();
738- auto baseTy = base->castTo <ProtocolType>();
739- auto baseDecl = baseTy->getDecl ();
740- llvm::SmallDenseMap<Identifier, Type> cmap;
741- for (const auto &req : constraints) {
742- switch (req.getKind ()) {
743- case RequirementKind::SameShape:
744- llvm_unreachable (" Same-shape requirement not supported here" );
745- case RequirementKind::Conformance:
746- case RequirementKind::Superclass:
747- case RequirementKind::Layout:
748- continue ;
735+ Type constrainedBase;
736+
737+ if (auto baseTy = base->getAs <ProtocolType>()) {
738+ auto baseDecl = baseTy->getDecl ();
739+ llvm::SmallDenseMap<Identifier, Type> cmap;
740+ for (const auto &req : constraints) {
741+ switch (req.getKind ()) {
742+ case RequirementKind::SameShape:
743+ llvm_unreachable (" Same-shape requirement not supported here" );
744+ case RequirementKind::Conformance:
745+ case RequirementKind::Superclass:
746+ case RequirementKind::Layout:
747+ continue ;
749748
750- case RequirementKind::SameType:
751- if (auto *DMT = req.getFirstType ()->getAs <DependentMemberType>())
752- cmap[DMT->getName ()] = req.getSecondType ();
749+ case RequirementKind::SameType:
750+ if (auto *DMT = req.getFirstType ()->getAs <DependentMemberType>())
751+ cmap[DMT->getName ()] = req.getSecondType ();
752+ }
753753 }
754- }
755- llvm::SmallVector<Type, 4 > args;
756- for (auto *assocTy : baseDecl->getPrimaryAssociatedTypes ()) {
757- auto argTy = cmap.find (assocTy->getName ());
758- if (argTy == cmap.end ()) {
759- return Type ();
754+ llvm::SmallVector<Type, 4 > args;
755+ for (auto *assocTy : baseDecl->getPrimaryAssociatedTypes ()) {
756+ auto argTy = cmap.find (assocTy->getName ());
757+ if (argTy == cmap.end ()) {
758+ return Type ();
759+ }
760+ args.push_back (argTy->getSecond ());
760761 }
761- args.push_back (argTy->getSecond ());
762- }
763-
764- Type constrainedBase;
765762
766- // We may not have any arguments because the constrained existential is a
767- // plain protocol with an inverse requirement.
768- if (args.empty ()) {
769- constrainedBase =
770- ProtocolType::get (baseDecl, baseTy, base->getASTContext ());
763+ // We may not have any arguments because the constrained existential is a
764+ // plain protocol with an inverse requirement.
765+ if (args.empty ()) {
766+ constrainedBase =
767+ ProtocolType::get (baseDecl, baseTy, base->getASTContext ());
768+ } else {
769+ constrainedBase =
770+ ParameterizedProtocolType::get (base->getASTContext (), baseTy, args);
771+ }
772+ } else if (base->isAny ()) {
773+ // The only other case should be that we got an empty PCT, which is equal to
774+ // the Any type. The other constraints should have been encoded in the
775+ // existential's generic signature (and arrive as BuiltInverseRequirement).
776+ constrainedBase = base;
771777 } else {
772- constrainedBase =
773- ParameterizedProtocolType::get (base->getASTContext (), baseTy, args);
778+ return Type ();
774779 }
775780
781+ assert (constrainedBase);
782+
776783 // Handle inverse requirements.
777784 if (!inverseRequirements.empty ()) {
778785 InvertibleProtocolSet inverseSet;
0 commit comments