@@ -667,58 +667,91 @@ unsigned GenericSignatureImpl::getGenericParamOrdinal(
667
667
return GenericParamKey (param).findIndexIn (getGenericParams ());
668
668
}
669
669
670
- Type GenericSignatureImpl::getUpperBound (Type type) const {
670
+ Type GenericSignatureImpl::getUpperBound (Type type,
671
+ bool forExistentialSelf,
672
+ bool includeParameterizedProtocols) const {
671
673
assert (type->isTypeParameter ());
672
674
673
675
llvm::SmallVector<Type, 2 > types;
674
676
unsigned rootDepth = type->getRootGenericParam ()->getDepth ();
675
677
678
+ auto accept = [forExistentialSelf, rootDepth](Type t) {
679
+ if (!forExistentialSelf)
680
+ return true ;
681
+
682
+ return !t.findIf ([rootDepth](Type t) {
683
+ if (auto *paramTy = t->getAs <GenericTypeParamType>())
684
+ return (paramTy->getDepth () == rootDepth);
685
+ return false ;
686
+ });
687
+ };
688
+
689
+ // We start with the assumption we'll add a '& AnyObject' member to our
690
+ // composition, but we might clear this below.
676
691
bool hasExplicitAnyObject = requiresClass (type);
677
692
678
- if (Type superclass = getSuperclassBound (type)) {
693
+ // Look for the most derived superclass that does not involve the type
694
+ // being erased.
695
+ Type superclass = getSuperclassBound (type);
696
+ if (superclass) {
679
697
do {
680
698
superclass = getReducedType (superclass);
681
-
682
- if (!superclass.findIf ([&](Type t) {
683
- if (auto *paramTy = t->getAs <GenericTypeParamType>())
684
- return (paramTy->getDepth () == rootDepth);
685
- return false ;
686
- })) {
699
+ if (accept (superclass))
687
700
break ;
688
- }
689
701
} while ((superclass = superclass->getSuperclass ()));
690
702
703
+ // If we're going to have a superclass, we can drop the '& AnyObject'.
691
704
if (superclass) {
692
- types.push_back (superclass);
705
+ types.push_back (getSugaredType ( superclass) );
693
706
hasExplicitAnyObject = false ;
694
707
}
695
708
}
696
709
710
+ auto &ctx = getASTContext ();
711
+
712
+ // Record the absence of Copyable and Escapable conformance, but only if
713
+ // we didn't have a superclass or require AnyObject.
714
+ InvertibleProtocolSet inverses;
715
+
716
+ if (SWIFT_ENABLE_EXPERIMENTAL_NONCOPYABLE_GENERICS ||
717
+ ctx.LangOpts .hasFeature (Feature::NoncopyableGenerics)) {
718
+ if (!superclass && !hasExplicitAnyObject) {
719
+ for (auto ip : InvertibleProtocolSet::full ()) {
720
+ auto *kp = ctx.getProtocol (::getKnownProtocolKind (ip));
721
+ if (!requiresProtocol (type, kp))
722
+ inverses.insert (ip);
723
+ }
724
+ }
725
+ }
726
+
697
727
for (auto *proto : getRequiredProtocols (type)) {
728
+ if (SWIFT_ENABLE_EXPERIMENTAL_NONCOPYABLE_GENERICS ||
729
+ ctx.LangOpts .hasFeature (Feature::NoncopyableGenerics)) {
730
+ // Don't add invertible protocols to the composition, because we recorded
731
+ // their absence above.
732
+ if (proto->getInvertibleProtocolKind ())
733
+ continue ;
734
+ }
735
+
698
736
if (proto->requiresClass ())
699
737
hasExplicitAnyObject = false ;
700
738
701
739
auto *baseType = proto->getDeclaredInterfaceType ()->castTo <ProtocolType>();
702
740
703
741
auto primaryAssocTypes = proto->getPrimaryAssociatedTypes ();
704
- if (!primaryAssocTypes.empty ()) {
742
+ if (includeParameterizedProtocols && !primaryAssocTypes.empty ()) {
705
743
SmallVector<Type, 2 > argTypes;
706
744
707
745
// Attempt to recover same-type requirements on primary associated types.
708
746
for (auto *assocType : primaryAssocTypes) {
709
747
// For each primary associated type A of P, compute the reduced type
710
748
// of T.[P]A.
711
- auto *memberType = DependentMemberType::get (type, assocType);
712
- auto reducedType = getReducedType (memberType);
749
+ auto memberType = getReducedType (DependentMemberType::get (type, assocType));
713
750
714
751
// If the reduced type is at a lower depth than the root generic
715
752
// parameter of T, then it's constrained.
716
- if (!reducedType.findIf ([&](Type t) {
717
- if (auto *paramTy = t->getAs <GenericTypeParamType>())
718
- return (paramTy->getDepth () == rootDepth);
719
- return false ;
720
- })) {
721
- argTypes.push_back (reducedType);
753
+ if (accept (memberType)) {
754
+ argTypes.push_back (getSugaredType (memberType));
722
755
}
723
756
}
724
757
@@ -740,15 +773,18 @@ Type GenericSignatureImpl::getUpperBound(Type type) const {
740
773
types.push_back (baseType);
741
774
}
742
775
743
- auto constraint = ProtocolCompositionType::get (getASTContext (), types,
744
- hasExplicitAnyObject);
745
-
746
- if (!constraint->isConstraintType ()) {
747
- assert (constraint->getClassOrBoundGenericClass ());
748
- return constraint;
749
- }
776
+ return ProtocolCompositionType::get (ctx, types, inverses,
777
+ hasExplicitAnyObject);
778
+ }
750
779
751
- return ExistentialType::get (constraint);
780
+ Type GenericSignatureImpl::getExistentialType (Type paramTy) const {
781
+ auto upperBound = getUpperBound (paramTy,
782
+ /* forExistentialSelf=*/ true ,
783
+ /* includeParameterizedProtocols=*/ true );
784
+ if (upperBound->isConstraintType ())
785
+ return ExistentialType::get (upperBound);
786
+ assert (upperBound->getClassOrBoundGenericClass ());
787
+ return upperBound;
752
788
}
753
789
754
790
void GenericSignature::Profile (llvm::FoldingSetNodeID &id) const {
0 commit comments