@@ -3727,12 +3727,24 @@ void ValueDecl::copyFormalAccessFrom(const ValueDecl *source,
37273727 }
37283728}
37293729
3730+ SelfReferenceInfo &
3731+ SelfReferenceInfo::operator |=(const SelfReferenceInfo &other) {
3732+ hasCovariantSelfResult |= other.hasCovariantSelfResult ;
3733+ if (other.selfRef > selfRef) {
3734+ selfRef = other.selfRef ;
3735+ }
3736+ if (other.assocTypeRef > assocTypeRef) {
3737+ assocTypeRef = other.assocTypeRef ;
3738+ }
3739+ return *this ;
3740+ }
3741+
37303742// / Report references to 'Self' within the given type.
37313743// /
37323744// / \param position The current position in terms of variance.
3733- static SelfReferenceInfo
3734- findProtocolSelfReferences ( const ProtocolDecl *proto, Type type,
3735- SelfReferencePosition position) {
3745+ static SelfReferenceInfo findProtocolSelfReferences ( const ProtocolDecl *proto,
3746+ Type type,
3747+ TypePosition position) {
37363748 // If there are no type parameters, we're done.
37373749 if (!type->hasTypeParameter ())
37383750 return SelfReferenceInfo ();
@@ -3757,8 +3769,8 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type,
37573769 for (auto param : funcTy->getParams ()) {
37583770 // inout parameters are invariant.
37593771 if (param.isInOut ()) {
3760- inputInfo |= findProtocolSelfReferences (
3761- proto, param. getPlainType (), SelfReferencePosition ::Invariant);
3772+ inputInfo |= findProtocolSelfReferences (proto, param. getPlainType (),
3773+ TypePosition ::Invariant);
37623774 continue ;
37633775 }
37643776 inputInfo |= findProtocolSelfReferences (proto, param.getParameterType (),
@@ -3770,7 +3782,7 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type,
37703782
37713783 auto resultInfo =
37723784 findProtocolSelfReferences (proto, funcTy->getResult (), position);
3773- if (resultInfo.selfRef == SelfReferencePosition ::Covariant) {
3785+ if (resultInfo.selfRef == TypePosition ::Covariant) {
37743786 resultInfo.hasCovariantSelfResult = true ;
37753787 }
37763788 return inputInfo |= resultInfo;
@@ -3811,13 +3823,13 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type,
38113823 } else if (bgt->isDictionary ()) {
38123824 // Swift.Dictionary preserves variance in its Element type.
38133825 info |= findProtocolSelfReferences (proto, bgt->getGenericArgs ().front (),
3814- SelfReferencePosition ::Invariant);
3826+ TypePosition ::Invariant);
38153827 info |= findProtocolSelfReferences (proto, bgt->getGenericArgs ().back (),
38163828 position);
38173829 } else {
38183830 for (auto paramType : bgt->getGenericArgs ()) {
38193831 info |= findProtocolSelfReferences (proto, paramType,
3820- SelfReferencePosition ::Invariant);
3832+ TypePosition ::Invariant);
38213833 }
38223834 }
38233835 }
@@ -3828,7 +3840,7 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type,
38283840 // Opaque result types of protocol extension members contain an invariant
38293841 // reference to 'Self'.
38303842 if (type->is <OpaqueTypeArchetypeType>())
3831- return SelfReferenceInfo::forSelfRef (SelfReferencePosition ::Invariant);
3843+ return SelfReferenceInfo::forSelfRef (TypePosition ::Invariant);
38323844
38333845 // Protocol compositions preserve variance.
38343846 auto constraint = type;
@@ -3879,13 +3891,12 @@ SelfReferenceInfo ValueDecl::findProtocolSelfReferences(
38793891 for (auto param : type->castTo <AnyFunctionType>()->getParams ()) {
38803892 // inout parameters are invariant.
38813893 if (param.isInOut ()) {
3882- inputInfo |= ::findProtocolSelfReferences (
3883- proto, param. getPlainType (), SelfReferencePosition ::Invariant);
3894+ inputInfo |= ::findProtocolSelfReferences (proto, param. getPlainType (),
3895+ TypePosition ::Invariant);
38843896 continue ;
38853897 }
3886- inputInfo |=
3887- ::findProtocolSelfReferences (proto, param.getParameterType(),
3888- SelfReferencePosition::Contravariant);
3898+ inputInfo |= ::findProtocolSelfReferences (proto, param.getParameterType (),
3899+ TypePosition::Contravariant);
38893900 }
38903901
38913902 // A covariant Self result inside a parameter will not be bona fide.
@@ -3898,24 +3909,24 @@ SelfReferenceInfo ValueDecl::findProtocolSelfReferences(
38983909 // Methods of non-final classes can only contain a covariant 'Self'
38993910 // as their result type.
39003911 if (treatNonResultCovariantSelfAsInvariant &&
3901- inputInfo.selfRef == SelfReferencePosition ::Covariant) {
3902- inputInfo.selfRef = SelfReferencePosition ::Invariant;
3912+ inputInfo.selfRef == TypePosition ::Covariant) {
3913+ inputInfo.selfRef = TypePosition ::Invariant;
39033914 }
39043915
39053916 auto resultInfo = ::findProtocolSelfReferences (
39063917 proto, type->castTo <AnyFunctionType>()->getResult (),
3907- SelfReferencePosition ::Covariant);
3908- if (resultInfo.selfRef == SelfReferencePosition ::Covariant) {
3918+ TypePosition ::Covariant);
3919+ if (resultInfo.selfRef == TypePosition ::Covariant) {
39093920 resultInfo.hasCovariantSelfResult = true ;
39103921 }
39113922
39123923 return inputInfo |= resultInfo;
39133924 } else {
39143925 assert (isa<VarDecl>(this ));
39153926
3916- auto info = :: findProtocolSelfReferences (proto, type,
3917- SelfReferencePosition ::Covariant);
3918- if (info.selfRef == SelfReferencePosition ::Covariant) {
3927+ auto info =
3928+ ::findProtocolSelfReferences (proto, type, TypePosition ::Covariant);
3929+ if (info.selfRef == TypePosition ::Covariant) {
39193930 info.hasCovariantSelfResult = true ;
39203931 }
39213932
0 commit comments