@@ -4825,8 +4825,8 @@ GenericParameterReferenceInfo::operator|=(const GenericParameterReferenceInfo &o
48254825
48264826// / Forward declaration.
48274827static GenericParameterReferenceInfo
4828- findGenericParameterReferences (CanGenericSignature, GenericTypeParamType *,
4829- Type, TypePosition, bool , bool );
4828+ findGenericParameterReferencesRec (CanGenericSignature, GenericTypeParamType *,
4829+ Type, TypePosition, bool );
48304830
48314831// / Determine whether a function type with the given result type may have
48324832// / a covariant generic parameter type result. This is true if the result type
@@ -4848,8 +4848,7 @@ static bool canResultTypeHaveCovariantGenericParameterResult(Type resultTy) {
48484848static GenericParameterReferenceInfo findGenericParameterReferencesInFunction (
48494849 CanGenericSignature genericSig, GenericTypeParamType *genericParam,
48504850 const AnyFunctionType *fnType, TypePosition position,
4851- bool treatNonResultCovarianceAsInvariant, bool canBeCovariantResult,
4852- std::optional<unsigned > skipParamIndex) {
4851+ bool canBeCovariantResult, std::optional<unsigned > skipParamIndex) {
48534852 // If there are no type parameters, we're done.
48544853 if (!isa<GenericFunctionType>(fnType) && !fnType->hasTypeParameter ())
48554854 return GenericParameterReferenceInfo ();
@@ -4864,10 +4863,9 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
48644863 const auto ¶m = params[paramIdx];
48654864 // inout types are invariant.
48664865 if (param.isInOut ()) {
4867- inputInfo |= ::findGenericParameterReferences (
4866+ inputInfo |= ::findGenericParameterReferencesRec (
48684867 genericSig, genericParam, param.getPlainType (),
4869- TypePosition::Invariant, treatNonResultCovarianceAsInvariant,
4870- /* canBeCovariantResult=*/ false );
4868+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
48714869 continue ;
48724870 }
48734871
@@ -4878,19 +4876,19 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
48784876 if (skipParamIndex && paramIdx < *skipParamIndex)
48794877 paramPos = TypePosition::Invariant;
48804878
4881- inputInfo |= ::findGenericParameterReferences (
4879+ inputInfo |= ::findGenericParameterReferencesRec (
48824880 genericSig, genericParam, param.getParameterType (), paramPos,
4883- treatNonResultCovarianceAsInvariant, /* canBeCovariantResult=*/ false );
4881+ /* canBeCovariantResult=*/ false );
48844882 }
48854883
48864884 canBeCovariantResult =
48874885 // &= does not short-circuit.
48884886 canBeCovariantResult &&
48894887 canResultTypeHaveCovariantGenericParameterResult (fnType->getResult ());
48904888
4891- const auto resultInfo = ::findGenericParameterReferences (
4892- genericSig, genericParam, fnType->getResult (), position,
4893- treatNonResultCovarianceAsInvariant , canBeCovariantResult);
4889+ const auto resultInfo = ::findGenericParameterReferencesRec (
4890+ genericSig, genericParam, fnType->getResult (),
4891+ position , canBeCovariantResult);
48944892
48954893 return inputInfo |= resultInfo;
48964894}
@@ -4900,12 +4898,11 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
49004898// /
49014899// / \param position The current position in terms of variance.
49024900static GenericParameterReferenceInfo
4903- findGenericParameterReferences (CanGenericSignature genericSig,
4904- GenericTypeParamType *genericParam,
4905- Type type,
4906- TypePosition position,
4907- bool treatNonResultCovarianceAsInvariant,
4908- bool canBeCovariantResult) {
4901+ findGenericParameterReferencesRec (CanGenericSignature genericSig,
4902+ GenericTypeParamType *genericParam,
4903+ Type type,
4904+ TypePosition position,
4905+ bool canBeCovariantResult) {
49094906 // If there are no type parameters, we're done.
49104907 if (!type->hasTypeParameter ())
49114908 return GenericParameterReferenceInfo ();
@@ -4914,9 +4911,8 @@ findGenericParameterReferences(CanGenericSignature genericSig,
49144911 if (auto tuple = type->getAs <TupleType>()) {
49154912 auto info = GenericParameterReferenceInfo ();
49164913 for (auto &elt : tuple->getElements ()) {
4917- info |= findGenericParameterReferences (
4914+ info |= findGenericParameterReferencesRec (
49184915 genericSig, genericParam, elt.getType (), position,
4919- treatNonResultCovarianceAsInvariant,
49204916 /* canBeCovariantResult=*/ false );
49214917 }
49224918
@@ -4927,69 +4923,61 @@ findGenericParameterReferences(CanGenericSignature genericSig,
49274923 // the parameter type.
49284924 if (auto funcTy = type->getAs <AnyFunctionType>()) {
49294925 return findGenericParameterReferencesInFunction (
4930- genericSig, genericParam, funcTy, position,
4931- treatNonResultCovarianceAsInvariant , canBeCovariantResult,
4926+ genericSig, genericParam, funcTy,
4927+ position , canBeCovariantResult,
49324928 /* skipParamIndex=*/ std::nullopt );
49334929 }
49344930
49354931 // Metatypes preserve variance.
49364932 if (auto metaTy = type->getAs <MetatypeType>()) {
4937- return findGenericParameterReferences (genericSig, genericParam,
4938- metaTy->getInstanceType (), position,
4939- treatNonResultCovarianceAsInvariant,
4940- canBeCovariantResult);
4933+ return findGenericParameterReferencesRec (genericSig, genericParam,
4934+ metaTy->getInstanceType (),
4935+ position, canBeCovariantResult);
49414936 }
49424937
49434938 // Optionals preserve variance.
49444939 if (auto optType = type->getOptionalObjectType ()) {
4945- return findGenericParameterReferences (
4946- genericSig, genericParam, optType, position,
4947- treatNonResultCovarianceAsInvariant, canBeCovariantResult);
4940+ return findGenericParameterReferencesRec (
4941+ genericSig, genericParam, optType, position, canBeCovariantResult);
49484942 }
49494943
49504944 // DynamicSelfType preserves variance.
49514945 if (auto selfType = type->getAs <DynamicSelfType>()) {
4952- return findGenericParameterReferences (genericSig, genericParam,
4953- selfType->getSelfType (), position,
4954- treatNonResultCovarianceAsInvariant,
4955- /* canBeCovariantResult=*/ false );
4946+ return findGenericParameterReferencesRec (genericSig, genericParam,
4947+ selfType->getSelfType (), position,
4948+ /* canBeCovariantResult=*/ false );
49564949 }
49574950
49584951 if (auto *const nominal = type->getAs <NominalOrBoundGenericNominalType>()) {
49594952 auto info = GenericParameterReferenceInfo ();
49604953
49614954 // Don't forget to look in the parent.
49624955 if (const auto parent = nominal->getParent ()) {
4963- info |= findGenericParameterReferences (
4956+ info |= findGenericParameterReferencesRec (
49644957 genericSig, genericParam, parent, position,
4965- treatNonResultCovarianceAsInvariant,
49664958 /* canBeCovariantResult=*/ false );
49674959 }
49684960
49694961 // Most bound generic types are invariant.
49704962 if (auto *const bgt = type->getAs <BoundGenericType>()) {
49714963 if (bgt->isArray ()) {
49724964 // Swift.Array preserves variance in its 'Value' type.
4973- info |= findGenericParameterReferences (
4965+ info |= findGenericParameterReferencesRec (
49744966 genericSig, genericParam, bgt->getGenericArgs ().front (),
4975- position, treatNonResultCovarianceAsInvariant,
4976- /* canBeCovariantResult=*/ false );
4967+ position, /* canBeCovariantResult=*/ false );
49774968 } else if (bgt->isDictionary ()) {
49784969 // Swift.Dictionary preserves variance in its 'Element' type.
4979- info |= findGenericParameterReferences (
4970+ info |= findGenericParameterReferencesRec (
49804971 genericSig, genericParam, bgt->getGenericArgs ().front (),
4981- TypePosition::Invariant, treatNonResultCovarianceAsInvariant,
4982- /* canBeCovariantResult=*/ false );
4983- info |= findGenericParameterReferences (
4972+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
4973+ info |= findGenericParameterReferencesRec (
49844974 genericSig, genericParam, bgt->getGenericArgs ().back (),
4985- position, treatNonResultCovarianceAsInvariant,
4986- /* canBeCovariantResult=*/ false );
4975+ position, /* canBeCovariantResult=*/ false );
49874976 } else {
49884977 for (const auto ¶mType : bgt->getGenericArgs ()) {
4989- info |= findGenericParameterReferences (
4990- genericSig, genericParam, paramType, TypePosition::Invariant,
4991- treatNonResultCovarianceAsInvariant,
4992- /* canBeCovariantResult=*/ false );
4978+ info |= findGenericParameterReferencesRec (
4979+ genericSig, genericParam, paramType,
4980+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
49934981 }
49944982 }
49954983 }
@@ -5012,40 +5000,37 @@ findGenericParameterReferences(CanGenericSignature genericSig,
50125000 continue ;
50135001
50145002 case RequirementKind::SameType:
5015- info |= findGenericParameterReferences (
5003+ info |= findGenericParameterReferencesRec (
50165004 genericSig, genericParam, req.getFirstType (),
5017- TypePosition::Invariant, treatNonResultCovarianceAsInvariant,
5018- /* canBeCovariantResult=*/ false );
5005+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
50195006
50205007 LLVM_FALLTHROUGH;
50215008
50225009 case RequirementKind::Superclass:
5023- info |= findGenericParameterReferences (
5010+ info |= findGenericParameterReferencesRec (
50245011 genericSig, genericParam, req.getSecondType (),
5025- TypePosition::Invariant, treatNonResultCovarianceAsInvariant,
5026- /* canBeCovariantResult=*/ false );
5012+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
50275013 break ;
50285014 }
50295015 }
50305016
50315017 return info;
50325018 }
50335019
5034- // Protocol compositions preserve variance.
50355020 if (auto *existential = type->getAs <ExistentialType>())
50365021 type = existential->getConstraintType ();
5022+
5023+ // Protocol compositions are invariant.
50375024 if (auto *comp = type->getAs <ProtocolCompositionType>()) {
5038- // 'Self' may be referenced only in an explicit superclass component.
5039- for (const auto member : comp->getMembers ()) {
5040- if (member->getClassOrBoundGenericClass ()) {
5041- return findGenericParameterReferences (
5042- genericSig, genericParam, member, position,
5043- treatNonResultCovarianceAsInvariant,
5044- /* canBeCovariantResult=*/ false );
5045- }
5025+ auto info = GenericParameterReferenceInfo ();
5026+
5027+ for (auto member : comp->getMembers ()) {
5028+ info |= findGenericParameterReferencesRec (
5029+ genericSig, genericParam, member,
5030+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
50465031 }
50475032
5048- return GenericParameterReferenceInfo () ;
5033+ return info ;
50495034 }
50505035
50515036 if (!type->isTypeParameter ()) {
@@ -5059,13 +5044,8 @@ findGenericParameterReferences(CanGenericSignature genericSig,
50595044
50605045 // A direct reference to 'Self'.
50615046 if (selfTy->isEqual (type)) {
5062- if (position == TypePosition::Covariant) {
5063- if (canBeCovariantResult) {
5064- return GenericParameterReferenceInfo::forCovariantResult ();
5065- } else if (treatNonResultCovarianceAsInvariant) {
5066- position = TypePosition::Invariant;
5067- }
5068- }
5047+ if (position == TypePosition::Covariant && canBeCovariantResult)
5048+ return GenericParameterReferenceInfo::forCovariantResult ();
50695049
50705050 return GenericParameterReferenceInfo::forSelfRef (position);
50715051 }
@@ -5077,9 +5057,9 @@ findGenericParameterReferences(CanGenericSignature genericSig,
50775057 }
50785058
50795059 if (const auto concreteTy = genericSig->getConcreteType (type)) {
5080- return findGenericParameterReferences (
5081- genericSig, genericParam, concreteTy, position,
5082- treatNonResultCovarianceAsInvariant , canBeCovariantResult);
5060+ return findGenericParameterReferencesRec (
5061+ genericSig, genericParam, concreteTy,
5062+ position , canBeCovariantResult);
50835063 }
50845064
50855065 // A reference to an associated type rooted on 'Self'.
@@ -5090,9 +5070,8 @@ GenericParameterReferenceInfo
50905070swift::findGenericParameterReferences (const ValueDecl *value,
50915071 CanGenericSignature sig,
50925072 GenericTypeParamType *genericParam,
5093- bool treatNonResultCovarianceAsInvariant,
50945073 std::optional<unsigned > skipParamIndex) {
5095- assert (isa<TypeDecl>(value) == false );
5074+ assert (! isa<TypeDecl>(value));
50965075 assert (sig->getGenericParamOrdinal (genericParam) <
50975076 sig.getGenericParams ().size ());
50985077
@@ -5102,25 +5081,25 @@ swift::findGenericParameterReferences(const ValueDecl *value,
51025081 if (type->hasError ())
51035082 return GenericParameterReferenceInfo ();
51045083
5084+ // For functions and subscripts, take skipParamIndex into account.
51055085 if (isa<AbstractFunctionDecl>(value) || isa<SubscriptDecl>(value)) {
5106- // For a method, skip the 'self' parameter.
5086+ // And for a method, skip the 'self' parameter.
51075087 if (value->hasCurriedSelf ())
51085088 type = type->castTo <AnyFunctionType>()->getResult ();
51095089
51105090 return ::findGenericParameterReferencesInFunction (
51115091 sig, genericParam, type->castTo <AnyFunctionType>(),
5112- TypePosition::Covariant, treatNonResultCovarianceAsInvariant ,
5113- /* canBeCovariantResult= */ true , skipParamIndex);
5092+ TypePosition::Covariant, /* canBeCovariantResult= */ true ,
5093+ skipParamIndex);
51145094 }
51155095
5116- return ::findGenericParameterReferences (sig, genericParam, type,
5117- TypePosition::Covariant,
5118- treatNonResultCovarianceAsInvariant,
5119- /* canBeCovariantResult=*/ true );
5096+ return ::findGenericParameterReferencesRec (sig, genericParam, type,
5097+ TypePosition::Covariant,
5098+ /* canBeCovariantResult=*/ true );
51205099}
51215100
51225101GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences (
5123- Type baseTy, bool treatNonResultCovariantSelfAsInvariant ) const {
5102+ Type baseTy) const {
51245103 assert (baseTy->isExistentialType ());
51255104 assert (!baseTy->hasTypeParameter ());
51265105
@@ -5139,9 +5118,7 @@ GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences(
51395118 GenericSignature ());
51405119
51415120 auto genericParam = sig.getGenericParams ().front ();
5142- return findGenericParameterReferences (this , sig, genericParam,
5143- treatNonResultCovariantSelfAsInvariant,
5144- std::nullopt );
5121+ return findGenericParameterReferences (this , sig, genericParam, std::nullopt );
51455122}
51465123
51475124TypeDecl::CanBeInvertible::Result
0 commit comments