@@ -732,36 +732,53 @@ Type ASTBuilder::createExistentialMetatypeType(
732
732
Type ASTBuilder::createConstrainedExistentialType (
733
733
Type base, ArrayRef<BuiltRequirement> constraints,
734
734
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 ;
749
748
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
+ }
753
753
}
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 ());
761
+ }
762
+
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);
760
771
}
761
- args.push_back (argTy->getSecond ());
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;
777
+ } else {
778
+ return Type ();
762
779
}
763
- Type constrainedBase =
764
- ParameterizedProtocolType::get (base-> getASTContext (), baseTy, args );
780
+
781
+ assert (constrainedBase );
765
782
766
783
// Handle inverse requirements.
767
784
if (!inverseRequirements.empty ()) {
0 commit comments