@@ -4825,8 +4825,8 @@ GenericParameterReferenceInfo::operator|=(const GenericParameterReferenceInfo &o
4825
4825
4826
4826
// / Forward declaration.
4827
4827
static GenericParameterReferenceInfo
4828
- findGenericParameterReferences (CanGenericSignature, GenericTypeParamType *,
4829
- Type, TypePosition, bool , bool );
4828
+ findGenericParameterReferencesRec (CanGenericSignature, GenericTypeParamType *,
4829
+ Type, TypePosition, bool );
4830
4830
4831
4831
// / Determine whether a function type with the given result type may have
4832
4832
// / a covariant generic parameter type result. This is true if the result type
@@ -4848,8 +4848,7 @@ static bool canResultTypeHaveCovariantGenericParameterResult(Type resultTy) {
4848
4848
static GenericParameterReferenceInfo findGenericParameterReferencesInFunction (
4849
4849
CanGenericSignature genericSig, GenericTypeParamType *genericParam,
4850
4850
const AnyFunctionType *fnType, TypePosition position,
4851
- bool treatNonResultCovarianceAsInvariant, bool canBeCovariantResult,
4852
- std::optional<unsigned > skipParamIndex) {
4851
+ bool canBeCovariantResult, std::optional<unsigned > skipParamIndex) {
4853
4852
// If there are no type parameters, we're done.
4854
4853
if (!isa<GenericFunctionType>(fnType) && !fnType->hasTypeParameter ())
4855
4854
return GenericParameterReferenceInfo ();
@@ -4864,10 +4863,9 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
4864
4863
const auto ¶m = params[paramIdx];
4865
4864
// inout types are invariant.
4866
4865
if (param.isInOut ()) {
4867
- inputInfo |= ::findGenericParameterReferences (
4866
+ inputInfo |= ::findGenericParameterReferencesRec (
4868
4867
genericSig, genericParam, param.getPlainType (),
4869
- TypePosition::Invariant, treatNonResultCovarianceAsInvariant,
4870
- /* canBeCovariantResult=*/ false );
4868
+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
4871
4869
continue ;
4872
4870
}
4873
4871
@@ -4878,19 +4876,19 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
4878
4876
if (skipParamIndex && paramIdx < *skipParamIndex)
4879
4877
paramPos = TypePosition::Invariant;
4880
4878
4881
- inputInfo |= ::findGenericParameterReferences (
4879
+ inputInfo |= ::findGenericParameterReferencesRec (
4882
4880
genericSig, genericParam, param.getParameterType (), paramPos,
4883
- treatNonResultCovarianceAsInvariant, /* canBeCovariantResult=*/ false );
4881
+ /* canBeCovariantResult=*/ false );
4884
4882
}
4885
4883
4886
4884
canBeCovariantResult =
4887
4885
// &= does not short-circuit.
4888
4886
canBeCovariantResult &&
4889
4887
canResultTypeHaveCovariantGenericParameterResult (fnType->getResult ());
4890
4888
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);
4894
4892
4895
4893
return inputInfo |= resultInfo;
4896
4894
}
@@ -4900,12 +4898,11 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
4900
4898
// /
4901
4899
// / \param position The current position in terms of variance.
4902
4900
static 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) {
4909
4906
// If there are no type parameters, we're done.
4910
4907
if (!type->hasTypeParameter ())
4911
4908
return GenericParameterReferenceInfo ();
@@ -4914,9 +4911,8 @@ findGenericParameterReferences(CanGenericSignature genericSig,
4914
4911
if (auto tuple = type->getAs <TupleType>()) {
4915
4912
auto info = GenericParameterReferenceInfo ();
4916
4913
for (auto &elt : tuple->getElements ()) {
4917
- info |= findGenericParameterReferences (
4914
+ info |= findGenericParameterReferencesRec (
4918
4915
genericSig, genericParam, elt.getType (), position,
4919
- treatNonResultCovarianceAsInvariant,
4920
4916
/* canBeCovariantResult=*/ false );
4921
4917
}
4922
4918
@@ -4927,69 +4923,61 @@ findGenericParameterReferences(CanGenericSignature genericSig,
4927
4923
// the parameter type.
4928
4924
if (auto funcTy = type->getAs <AnyFunctionType>()) {
4929
4925
return findGenericParameterReferencesInFunction (
4930
- genericSig, genericParam, funcTy, position,
4931
- treatNonResultCovarianceAsInvariant , canBeCovariantResult,
4926
+ genericSig, genericParam, funcTy,
4927
+ position , canBeCovariantResult,
4932
4928
/* skipParamIndex=*/ std::nullopt);
4933
4929
}
4934
4930
4935
4931
// Metatypes preserve variance.
4936
4932
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);
4941
4936
}
4942
4937
4943
4938
// Optionals preserve variance.
4944
4939
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);
4948
4942
}
4949
4943
4950
4944
// DynamicSelfType preserves variance.
4951
4945
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 );
4956
4949
}
4957
4950
4958
4951
if (auto *const nominal = type->getAs <NominalOrBoundGenericNominalType>()) {
4959
4952
auto info = GenericParameterReferenceInfo ();
4960
4953
4961
4954
// Don't forget to look in the parent.
4962
4955
if (const auto parent = nominal->getParent ()) {
4963
- info |= findGenericParameterReferences (
4956
+ info |= findGenericParameterReferencesRec (
4964
4957
genericSig, genericParam, parent, position,
4965
- treatNonResultCovarianceAsInvariant,
4966
4958
/* canBeCovariantResult=*/ false );
4967
4959
}
4968
4960
4969
4961
// Most bound generic types are invariant.
4970
4962
if (auto *const bgt = type->getAs <BoundGenericType>()) {
4971
4963
if (bgt->isArray ()) {
4972
4964
// Swift.Array preserves variance in its 'Value' type.
4973
- info |= findGenericParameterReferences (
4965
+ info |= findGenericParameterReferencesRec (
4974
4966
genericSig, genericParam, bgt->getGenericArgs ().front (),
4975
- position, treatNonResultCovarianceAsInvariant,
4976
- /* canBeCovariantResult=*/ false );
4967
+ position, /* canBeCovariantResult=*/ false );
4977
4968
} else if (bgt->isDictionary ()) {
4978
4969
// Swift.Dictionary preserves variance in its 'Element' type.
4979
- info |= findGenericParameterReferences (
4970
+ info |= findGenericParameterReferencesRec (
4980
4971
genericSig, genericParam, bgt->getGenericArgs ().front (),
4981
- TypePosition::Invariant, treatNonResultCovarianceAsInvariant,
4982
- /* canBeCovariantResult=*/ false );
4983
- info |= findGenericParameterReferences (
4972
+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
4973
+ info |= findGenericParameterReferencesRec (
4984
4974
genericSig, genericParam, bgt->getGenericArgs ().back (),
4985
- position, treatNonResultCovarianceAsInvariant,
4986
- /* canBeCovariantResult=*/ false );
4975
+ position, /* canBeCovariantResult=*/ false );
4987
4976
} else {
4988
4977
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 );
4993
4981
}
4994
4982
}
4995
4983
}
@@ -5012,40 +5000,37 @@ findGenericParameterReferences(CanGenericSignature genericSig,
5012
5000
continue ;
5013
5001
5014
5002
case RequirementKind::SameType:
5015
- info |= findGenericParameterReferences (
5003
+ info |= findGenericParameterReferencesRec (
5016
5004
genericSig, genericParam, req.getFirstType (),
5017
- TypePosition::Invariant, treatNonResultCovarianceAsInvariant,
5018
- /* canBeCovariantResult=*/ false );
5005
+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
5019
5006
5020
5007
LLVM_FALLTHROUGH;
5021
5008
5022
5009
case RequirementKind::Superclass:
5023
- info |= findGenericParameterReferences (
5010
+ info |= findGenericParameterReferencesRec (
5024
5011
genericSig, genericParam, req.getSecondType (),
5025
- TypePosition::Invariant, treatNonResultCovarianceAsInvariant,
5026
- /* canBeCovariantResult=*/ false );
5012
+ TypePosition::Invariant, /* canBeCovariantResult=*/ false );
5027
5013
break ;
5028
5014
}
5029
5015
}
5030
5016
5031
5017
return info;
5032
5018
}
5033
5019
5034
- // Protocol compositions preserve variance.
5035
5020
if (auto *existential = type->getAs <ExistentialType>())
5036
5021
type = existential->getConstraintType ();
5022
+
5023
+ // Protocol compositions are invariant.
5037
5024
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 );
5046
5031
}
5047
5032
5048
- return GenericParameterReferenceInfo () ;
5033
+ return info ;
5049
5034
}
5050
5035
5051
5036
if (!type->isTypeParameter ()) {
@@ -5059,13 +5044,8 @@ findGenericParameterReferences(CanGenericSignature genericSig,
5059
5044
5060
5045
// A direct reference to 'Self'.
5061
5046
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 ();
5069
5049
5070
5050
return GenericParameterReferenceInfo::forSelfRef (position);
5071
5051
}
@@ -5077,9 +5057,9 @@ findGenericParameterReferences(CanGenericSignature genericSig,
5077
5057
}
5078
5058
5079
5059
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);
5083
5063
}
5084
5064
5085
5065
// A reference to an associated type rooted on 'Self'.
@@ -5090,9 +5070,8 @@ GenericParameterReferenceInfo
5090
5070
swift::findGenericParameterReferences (const ValueDecl *value,
5091
5071
CanGenericSignature sig,
5092
5072
GenericTypeParamType *genericParam,
5093
- bool treatNonResultCovarianceAsInvariant,
5094
5073
std::optional<unsigned > skipParamIndex) {
5095
- assert (isa<TypeDecl>(value) == false );
5074
+ assert (! isa<TypeDecl>(value));
5096
5075
assert (sig->getGenericParamOrdinal (genericParam) <
5097
5076
sig.getGenericParams ().size ());
5098
5077
@@ -5102,25 +5081,25 @@ swift::findGenericParameterReferences(const ValueDecl *value,
5102
5081
if (type->hasError ())
5103
5082
return GenericParameterReferenceInfo ();
5104
5083
5084
+ // For functions and subscripts, take skipParamIndex into account.
5105
5085
if (isa<AbstractFunctionDecl>(value) || isa<SubscriptDecl>(value)) {
5106
- // For a method, skip the 'self' parameter.
5086
+ // And for a method, skip the 'self' parameter.
5107
5087
if (value->hasCurriedSelf ())
5108
5088
type = type->castTo <AnyFunctionType>()->getResult ();
5109
5089
5110
5090
return ::findGenericParameterReferencesInFunction (
5111
5091
sig, genericParam, type->castTo <AnyFunctionType>(),
5112
- TypePosition::Covariant, treatNonResultCovarianceAsInvariant ,
5113
- /* canBeCovariantResult= */ true , skipParamIndex);
5092
+ TypePosition::Covariant, /* canBeCovariantResult= */ true ,
5093
+ skipParamIndex);
5114
5094
}
5115
5095
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 );
5120
5099
}
5121
5100
5122
5101
GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences (
5123
- Type baseTy, bool treatNonResultCovariantSelfAsInvariant ) const {
5102
+ Type baseTy) const {
5124
5103
assert (baseTy->isExistentialType ());
5125
5104
assert (!baseTy->hasTypeParameter ());
5126
5105
@@ -5139,9 +5118,7 @@ GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences(
5139
5118
GenericSignature ());
5140
5119
5141
5120
auto genericParam = sig.getGenericParams ().front ();
5142
- return findGenericParameterReferences (this , sig, genericParam,
5143
- treatNonResultCovariantSelfAsInvariant,
5144
- std::nullopt);
5121
+ return findGenericParameterReferences (this , sig, genericParam, std::nullopt);
5145
5122
}
5146
5123
5147
5124
TypeDecl::CanBeInvertible::Result
0 commit comments