@@ -3808,91 +3808,19 @@ Type ProtocolCompositionType::get(const ASTContext &C,
38083808
38093809CanType ProtocolCompositionType::getMinimalCanonicalType (
38103810 const DeclContext *useDC) const {
3811- const CanType CanTy = getCanonicalType ();
3812-
3813- // If the canonical type is not a composition, it's minimal.
3814- const auto Composition = dyn_cast<ProtocolCompositionType>(CanTy);
3815- if (!Composition) {
3816- return CanTy;
3817- }
3818-
3819- // Nothing to minimize.
3820- if (Composition->getMembers ().empty ()) {
3821- return CanTy;
3822- }
3823-
3824- // The only cases we're missing out on proper minimization is when a
3825- // composition has an explicit superclass or AnyObject constraint.
3826- if (!Composition->hasExplicitAnyObject () &&
3827- !Composition->getMembers ().front ()->getClassOrBoundGenericClass ()) {
3828- // Already minimal.
3829- return CanTy;
3830- }
3831-
3832- auto &Ctx = CanTy->getASTContext ();
3811+ auto &Ctx = getASTContext ();
38333812
38343813 // Use generic signature minimization: the requirements of the signature will
38353814 // represent the minimal composition.
3836- auto sig = useDC->getGenericSignatureOfContext ();
3837- const auto Sig = Ctx.getOpenedExistentialSignature (CanTy, sig);
3838- SmallVector<Requirement, 2 > Reqs;
3839- SmallVector<InverseRequirement, 2 > Inverses;
3840- Sig->getRequirementsWithInverses (Reqs, Inverses);
3841-
3842- if (Reqs.size () == 1 ) {
3843- return Reqs.front ().getSecondType ()->getCanonicalType ();
3844- }
3845-
3846- // The set of inverses is already minimal.
3847- auto MinimalInverses = Composition->getInverses ();
3848-
3849- #ifndef NDEBUG
3850- // Check that the generic signature's inverses matches.
3851- InvertibleProtocolSet genSigInverses;
3852- for (InverseRequirement ireq : Inverses)
3853- genSigInverses.insert (ireq.getKind ());
3854- assert (genSigInverses == MinimalInverses);
3855- #endif
3856-
3857- llvm::SmallVector<Type, 2 > MinimalMembers;
3858- bool MinimalHasExplicitAnyObject = false ;
3859- auto ifaceTy = Sig.getGenericParams ().back ();
3860- for (const auto &Req : Reqs) {
3861- if (!Req.getFirstType ()->isEqual (ifaceTy)) {
3862- continue ;
3863- }
3864-
3865- switch (Req.getKind ()) {
3866- case RequirementKind::SameShape:
3867- llvm_unreachable (" Same-shape requirement not supported here" );
3868- case RequirementKind::Superclass:
3869- case RequirementKind::Conformance:
3870- MinimalMembers.push_back (Req.getSecondType ());
3871- break ;
3872- case RequirementKind::Layout:
3873- MinimalHasExplicitAnyObject = true ;
3874- break ;
3875- case RequirementKind::SameType:
3876- llvm_unreachable (" " );
3877- }
3878- }
3879-
3880- // A superclass constraint is always retained and must appear first in the
3881- // members list.
3882- assert (Composition->getMembers ().front ()->getClassOrBoundGenericClass () ==
3883- MinimalMembers.front ()->getClassOrBoundGenericClass ());
3884-
3885- // If we are left with a single member and no layout constraint, the member
3886- // is the minimal type. Also, note that a protocol composition cannot be
3887- // constructed with a single member unless there is a layout constraint.
3888- if (MinimalMembers.size () == 1
3889- && !MinimalHasExplicitAnyObject
3890- && MinimalInverses.empty ())
3891- return CanType (MinimalMembers.front ());
3892-
3893- // The resulting composition is necessarily canonical.
3894- return CanType (build (Ctx, MinimalMembers, MinimalInverses,
3895- MinimalHasExplicitAnyObject));
3815+ auto parentSig = useDC->getGenericSignatureOfContext ();
3816+ auto existentialSig =
3817+ Ctx.getOpenedExistentialSignature (getCanonicalType (), parentSig);
3818+ auto selfTy =
3819+ OpenedArchetypeType::getSelfInterfaceTypeFromContext (parentSig, Ctx);
3820+ return existentialSig->getUpperBound (selfTy,
3821+ /* forExistentialSelf=*/ true ,
3822+ /* includeParameterizedProtocols=*/ true )
3823+ ->getCanonicalType ();
38963824}
38973825
38983826ClangTypeInfo AnyFunctionType::getClangTypeInfo () const {
0 commit comments