@@ -767,65 +767,88 @@ Type ASTBuilder::createExistentialMetatypeType(
767767Type ASTBuilder::createConstrainedExistentialType (
768768 Type base, ArrayRef<BuiltRequirement> constraints,
769769 ArrayRef<BuiltInverseRequirement> inverseRequirements) {
770- Type constrainedBase;
771-
772- if (auto baseTy = base->getAs <ProtocolType>()) {
773- auto baseDecl = baseTy->getDecl ();
774- llvm::SmallDenseMap<Identifier, Type> cmap;
775- for (const auto &req : constraints) {
776- switch (req.getKind ()) {
777- case RequirementKind::SameShape:
778- llvm_unreachable (" Same-shape requirement not supported here" );
779- case RequirementKind::Conformance:
780- case RequirementKind::Superclass:
781- case RequirementKind::Layout:
782- continue ;
770+ llvm::SmallDenseMap<Identifier, Type> primaryAssociatedTypes;
771+ llvm::SmallDenseSet<Identifier> claimed;
772+
773+ for (const auto &req : constraints) {
774+ switch (req.getKind ()) {
775+ case RequirementKind::SameShape:
776+ case RequirementKind::Conformance:
777+ case RequirementKind::Superclass:
778+ case RequirementKind::Layout:
779+ break ;
783780
784- case RequirementKind::SameType:
785- if (auto *DMT = req.getFirstType ()->getAs <DependentMemberType>())
786- cmap[DMT->getName ()] = req.getSecondType ();
781+ case RequirementKind::SameType: {
782+ if (auto *memberTy = req.getFirstType ()->getAs <DependentMemberType>()) {
783+ if (memberTy->getBase ()->is <GenericTypeParamType>()) {
784+ // This is the only case we understand so far.
785+ primaryAssociatedTypes[memberTy->getName ()] = req.getSecondType ();
786+ continue ;
787+ }
787788 }
789+ break ;
790+ }
788791 }
792+
793+ // If we end here, we didn't recognize this requirement.
794+ return Type ();
795+ }
796+
797+ auto maybeFormParameterizedProtocolType = [&](ProtocolType *protoTy) -> Type {
798+ auto *proto = protoTy->getDecl ();
799+
789800 llvm::SmallVector<Type, 4 > args;
790- for (auto *assocTy : baseDecl ->getPrimaryAssociatedTypes ()) {
791- auto argTy = cmap .find (assocTy->getName ());
792- if (argTy == cmap .end ()) {
793- return Type () ;
794- }
795- args. push_back (argTy-> getSecond () );
801+ for (auto *assocTy : proto ->getPrimaryAssociatedTypes ()) {
802+ auto found = primaryAssociatedTypes .find (assocTy->getName ());
803+ if (found == primaryAssociatedTypes .end ())
804+ return protoTy ;
805+ args. push_back (found-> second );
806+ claimed. insert (found-> first );
796807 }
797808
798809 // We may not have any arguments because the constrained existential is a
799810 // plain protocol with an inverse requirement.
800- if (args.empty ()) {
801- constrainedBase =
802- ProtocolType::get (baseDecl, baseTy, base->getASTContext ());
803- } else {
804- constrainedBase =
805- ParameterizedProtocolType::get (base->getASTContext (), baseTy, args);
806- }
807- } else if (base->isAny ()) {
808- // The only other case should be that we got an empty PCT, which is equal to
809- // the Any type. The other constraints should have been encoded in the
810- // existential's generic signature (and arrive as BuiltInverseRequirement).
811- constrainedBase = base;
811+ if (args.empty ())
812+ return protoTy;
813+
814+ return ParameterizedProtocolType::get (Ctx, protoTy, args);
815+ };
816+
817+ SmallVector<Type, 2 > members;
818+ bool hasExplicitAnyObject = false ;
819+ InvertibleProtocolSet inverses;
820+
821+ // We're given either a single protocol type, or a composition of protocol
822+ // types. Transform each protocol type to add arguments, if necessary.
823+ if (auto protoTy = base->getAs <ProtocolType>()) {
824+ members.push_back (maybeFormParameterizedProtocolType (protoTy));
812825 } else {
813- return Type ();
826+ auto compositionTy = base->castTo <ProtocolCompositionType>();
827+ hasExplicitAnyObject = compositionTy->hasExplicitAnyObject ();
828+ ASSERT (compositionTy->getInverses ().empty ());
829+
830+ for (auto member : compositionTy->getMembers ()) {
831+ if (auto *protoTy = member->getAs <ProtocolType>()) {
832+ members.push_back (maybeFormParameterizedProtocolType (protoTy));
833+ continue ;
834+ }
835+ ASSERT (member->getClassOrBoundGenericClass ());
836+ members.push_back (member);
837+ }
814838 }
815839
816- assert (constrainedBase);
840+ // Make sure that all arguments were actually used.
841+ ASSERT (claimed.size () == primaryAssociatedTypes.size ());
817842
818843 // Handle inverse requirements.
819844 if (!inverseRequirements.empty ()) {
820- InvertibleProtocolSet inverseSet;
821845 for (const auto &inverseReq : inverseRequirements) {
822- inverseSet .insert (inverseReq.getKind ());
846+ inverses .insert (inverseReq.getKind ());
823847 }
824- constrainedBase = ProtocolCompositionType::get (
825- Ctx, { constrainedBase }, inverseSet, /* hasExplicitAnyObject=*/ false );
826848 }
827849
828- return ExistentialType::get (constrainedBase);
850+ return ExistentialType::get (ProtocolCompositionType::get (
851+ Ctx, members, inverses, hasExplicitAnyObject));
829852}
830853
831854Type ASTBuilder::createSymbolicExtendedExistentialType (NodePointer shapeNode,
0 commit comments