@@ -755,36 +755,53 @@ Type ASTBuilder::createExistentialMetatypeType(
755
755
Type ASTBuilder::createConstrainedExistentialType (
756
756
Type base, ArrayRef<BuiltRequirement> constraints,
757
757
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 ;
772
771
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
+ }
776
776
}
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);
783
794
}
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 ();
785
802
}
786
- Type constrainedBase =
787
- ParameterizedProtocolType::get (base-> getASTContext (), baseTy, args );
803
+
804
+ assert (constrainedBase );
788
805
789
806
// Handle inverse requirements.
790
807
if (!inverseRequirements.empty ()) {
0 commit comments