@@ -767,65 +767,88 @@ Type ASTBuilder::createExistentialMetatypeType(
767
767
Type ASTBuilder::createConstrainedExistentialType (
768
768
Type base, ArrayRef<BuiltRequirement> constraints,
769
769
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 ;
783
780
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
+ }
787
788
}
789
+ break ;
790
+ }
788
791
}
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
+
789
800
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 );
796
807
}
797
808
798
809
// We may not have any arguments because the constrained existential is a
799
810
// 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));
812
825
} 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
+ }
814
838
}
815
839
816
- assert (constrainedBase);
840
+ // Make sure that all arguments were actually used.
841
+ ASSERT (claimed.size () == primaryAssociatedTypes.size ());
817
842
818
843
// Handle inverse requirements.
819
844
if (!inverseRequirements.empty ()) {
820
- InvertibleProtocolSet inverseSet;
821
845
for (const auto &inverseReq : inverseRequirements) {
822
- inverseSet .insert (inverseReq.getKind ());
846
+ inverses .insert (inverseReq.getKind ());
823
847
}
824
- constrainedBase = ProtocolCompositionType::get (
825
- Ctx, { constrainedBase }, inverseSet, /* hasExplicitAnyObject=*/ false );
826
848
}
827
849
828
- return ExistentialType::get (constrainedBase);
850
+ return ExistentialType::get (ProtocolCompositionType::get (
851
+ Ctx, members, inverses, hasExplicitAnyObject));
829
852
}
830
853
831
854
Type ASTBuilder::createSymbolicExtendedExistentialType (NodePointer shapeNode,
0 commit comments