@@ -4825,7 +4825,9 @@ GenericParameterReferenceInfo::operator|=(const GenericParameterReferenceInfo &o
4825
4825
4826
4826
// / Forward declaration.
4827
4827
static GenericParameterReferenceInfo
4828
- findGenericParameterReferencesRec (CanGenericSignature, GenericTypeParamType *,
4828
+ findGenericParameterReferencesRec (CanGenericSignature,
4829
+ GenericTypeParamType *,
4830
+ GenericTypeParamType *,
4829
4831
Type, TypePosition, bool );
4830
4832
4831
4833
// / Determine whether a function type with the given result type may have
@@ -4846,7 +4848,9 @@ static bool canResultTypeHaveCovariantGenericParameterResult(Type resultTy) {
4846
4848
// / \param position The current position in terms of variance.
4847
4849
// / \param skipParamIndex The index of the parameter that shall be skipped.
4848
4850
static GenericParameterReferenceInfo findGenericParameterReferencesInFunction (
4849
- CanGenericSignature genericSig, GenericTypeParamType *genericParam,
4851
+ CanGenericSignature genericSig,
4852
+ GenericTypeParamType *origParam,
4853
+ GenericTypeParamType *openedParam,
4850
4854
const AnyFunctionType *fnType, TypePosition position,
4851
4855
bool canBeCovariantResult, std::optional<unsigned > skipParamIndex) {
4852
4856
// If there are no type parameters, we're done.
@@ -4864,7 +4868,7 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
4864
4868
// inout types are invariant.
4865
4869
if (param.isInOut ()) {
4866
4870
inputInfo |= ::findGenericParameterReferencesRec (
4867
- genericSig, genericParam , param.getPlainType (),
4871
+ genericSig, origParam, openedParam , param.getPlainType (),
4868
4872
TypePosition::Invariant, /* canBeCovariantResult=*/ false );
4869
4873
continue ;
4870
4874
}
@@ -4877,7 +4881,7 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
4877
4881
paramPos = TypePosition::Invariant;
4878
4882
4879
4883
inputInfo |= ::findGenericParameterReferencesRec (
4880
- genericSig, genericParam , param.getParameterType (), paramPos,
4884
+ genericSig, origParam, openedParam , param.getParameterType (), paramPos,
4881
4885
/* canBeCovariantResult=*/ false );
4882
4886
}
4883
4887
@@ -4887,7 +4891,7 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
4887
4891
canResultTypeHaveCovariantGenericParameterResult (fnType->getResult ());
4888
4892
4889
4893
const auto resultInfo = ::findGenericParameterReferencesRec (
4890
- genericSig, genericParam , fnType->getResult (),
4894
+ genericSig, origParam, openedParam , fnType->getResult (),
4891
4895
position, canBeCovariantResult);
4892
4896
4893
4897
return inputInfo |= resultInfo;
@@ -4899,7 +4903,8 @@ static GenericParameterReferenceInfo findGenericParameterReferencesInFunction(
4899
4903
// / \param position The current position in terms of variance.
4900
4904
static GenericParameterReferenceInfo
4901
4905
findGenericParameterReferencesRec (CanGenericSignature genericSig,
4902
- GenericTypeParamType *genericParam,
4906
+ GenericTypeParamType *origParam,
4907
+ GenericTypeParamType *openedParam,
4903
4908
Type type,
4904
4909
TypePosition position,
4905
4910
bool canBeCovariantResult) {
@@ -4912,7 +4917,7 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
4912
4917
auto info = GenericParameterReferenceInfo ();
4913
4918
for (auto &elt : tuple->getElements ()) {
4914
4919
info |= findGenericParameterReferencesRec (
4915
- genericSig, genericParam , elt.getType (), position,
4920
+ genericSig, origParam, openedParam , elt.getType (), position,
4916
4921
/* canBeCovariantResult=*/ false );
4917
4922
}
4918
4923
@@ -4923,27 +4928,28 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
4923
4928
// the parameter type.
4924
4929
if (auto funcTy = type->getAs <AnyFunctionType>()) {
4925
4930
return findGenericParameterReferencesInFunction (
4926
- genericSig, genericParam , funcTy,
4931
+ genericSig, origParam, openedParam , funcTy,
4927
4932
position, canBeCovariantResult,
4928
4933
/* skipParamIndex=*/ std::nullopt);
4929
4934
}
4930
4935
4931
4936
// Metatypes preserve variance.
4932
4937
if (auto metaTy = type->getAs <MetatypeType>()) {
4933
- return findGenericParameterReferencesRec (genericSig, genericParam ,
4938
+ return findGenericParameterReferencesRec (genericSig, origParam, openedParam ,
4934
4939
metaTy->getInstanceType (),
4935
4940
position, canBeCovariantResult);
4936
4941
}
4937
4942
4938
4943
// Optionals preserve variance.
4939
4944
if (auto optType = type->getOptionalObjectType ()) {
4940
4945
return findGenericParameterReferencesRec (
4941
- genericSig, genericParam, optType, position, canBeCovariantResult);
4946
+ genericSig, origParam, openedParam, optType,
4947
+ position, canBeCovariantResult);
4942
4948
}
4943
4949
4944
4950
// DynamicSelfType preserves variance.
4945
4951
if (auto selfType = type->getAs <DynamicSelfType>()) {
4946
- return findGenericParameterReferencesRec (genericSig, genericParam ,
4952
+ return findGenericParameterReferencesRec (genericSig, origParam, openedParam ,
4947
4953
selfType->getSelfType (), position,
4948
4954
/* canBeCovariantResult=*/ false );
4949
4955
}
@@ -4954,7 +4960,7 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
4954
4960
// Don't forget to look in the parent.
4955
4961
if (const auto parent = nominal->getParent ()) {
4956
4962
info |= findGenericParameterReferencesRec (
4957
- genericSig, genericParam , parent, TypePosition::Invariant,
4963
+ genericSig, origParam, openedParam , parent, TypePosition::Invariant,
4958
4964
/* canBeCovariantResult=*/ false );
4959
4965
}
4960
4966
@@ -4963,20 +4969,20 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
4963
4969
if (bgt->isArray ()) {
4964
4970
// Swift.Array preserves variance in its 'Value' type.
4965
4971
info |= findGenericParameterReferencesRec (
4966
- genericSig, genericParam , bgt->getGenericArgs ().front (),
4972
+ genericSig, origParam, openedParam , bgt->getGenericArgs ().front (),
4967
4973
position, /* canBeCovariantResult=*/ false );
4968
4974
} else if (bgt->isDictionary ()) {
4969
4975
// Swift.Dictionary preserves variance in its 'Element' type.
4970
4976
info |= findGenericParameterReferencesRec (
4971
- genericSig, genericParam , bgt->getGenericArgs ().front (),
4977
+ genericSig, origParam, openedParam , bgt->getGenericArgs ().front (),
4972
4978
TypePosition::Invariant, /* canBeCovariantResult=*/ false );
4973
4979
info |= findGenericParameterReferencesRec (
4974
- genericSig, genericParam , bgt->getGenericArgs ().back (),
4980
+ genericSig, origParam, openedParam , bgt->getGenericArgs ().back (),
4975
4981
position, /* canBeCovariantResult=*/ false );
4976
4982
} else {
4977
4983
for (const auto ¶mType : bgt->getGenericArgs ()) {
4978
4984
info |= findGenericParameterReferencesRec (
4979
- genericSig, genericParam , paramType,
4985
+ genericSig, origParam, openedParam , paramType,
4980
4986
TypePosition::Invariant, /* canBeCovariantResult=*/ false );
4981
4987
}
4982
4988
}
@@ -5001,14 +5007,14 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
5001
5007
5002
5008
case RequirementKind::SameType:
5003
5009
info |= findGenericParameterReferencesRec (
5004
- genericSig, genericParam , req.getFirstType (),
5010
+ genericSig, origParam, openedParam , req.getFirstType (),
5005
5011
TypePosition::Invariant, /* canBeCovariantResult=*/ false );
5006
5012
5007
5013
LLVM_FALLTHROUGH;
5008
5014
5009
5015
case RequirementKind::Superclass:
5010
5016
info |= findGenericParameterReferencesRec (
5011
- genericSig, genericParam , req.getSecondType (),
5017
+ genericSig, origParam, openedParam , req.getSecondType (),
5012
5018
TypePosition::Invariant, /* canBeCovariantResult=*/ false );
5013
5019
break ;
5014
5020
}
@@ -5026,7 +5032,7 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
5026
5032
5027
5033
for (auto member : comp->getMembers ()) {
5028
5034
info |= findGenericParameterReferencesRec (
5029
- genericSig, genericParam , member,
5035
+ genericSig, origParam, openedParam , member,
5030
5036
TypePosition::Invariant, /* canBeCovariantResult=*/ false );
5031
5037
}
5032
5038
@@ -5039,7 +5045,7 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
5039
5045
5040
5046
for (auto arg : pack->getElementTypes ()) {
5041
5047
info |= findGenericParameterReferencesRec (
5042
- genericSig, genericParam , arg,
5048
+ genericSig, origParam, openedParam , arg,
5043
5049
TypePosition::Invariant, /* canBeCovariantResult=*/ false );
5044
5050
}
5045
5051
@@ -5049,7 +5055,7 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
5049
5055
// Pack expansions are invariant.
5050
5056
if (auto *expansion = type->getAs <PackExpansionType>()) {
5051
5057
return findGenericParameterReferencesRec (
5052
- genericSig, genericParam , expansion->getPatternType (),
5058
+ genericSig, origParam, openedParam , expansion->getPatternType (),
5053
5059
TypePosition::Invariant, /* canBeCovariantResult=*/ false );
5054
5060
}
5055
5061
@@ -5067,29 +5073,46 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
5067
5073
abort ();
5068
5074
}
5069
5075
5070
- Type selfTy (genericParam);
5071
- if (!type->getRootGenericParam ()->isEqual (selfTy)) {
5076
+ if (!type->getRootGenericParam ()->isEqual (origParam)) {
5072
5077
return GenericParameterReferenceInfo ();
5073
5078
}
5074
5079
5075
5080
// A direct reference to 'Self'.
5076
- if (selfTy-> isEqual (type )) {
5081
+ if (type-> is <GenericTypeParamType>( )) {
5077
5082
if (position == TypePosition::Covariant && canBeCovariantResult)
5078
5083
return GenericParameterReferenceInfo::forCovariantResult ();
5079
5084
5080
5085
return GenericParameterReferenceInfo::forSelfRef (position);
5081
5086
}
5082
5087
5083
- // If the type parameter is beyond the domain of the existential generic
5084
- // signature, ignore it.
5085
- if (!genericSig->isValidTypeParameter (type)) {
5086
- return GenericParameterReferenceInfo ();
5087
- }
5088
-
5089
- if (const auto concreteTy = genericSig->getConcreteType (type)) {
5090
- return findGenericParameterReferencesRec (
5091
- genericSig, genericParam, concreteTy,
5092
- position, canBeCovariantResult);
5088
+ if (origParam != openedParam) {
5089
+ // Replace the original parameter with the parameter in the opened
5090
+ // signature.
5091
+ type = type.subst (
5092
+ [&](SubstitutableType *type) {
5093
+ ASSERT (type->isEqual (origParam));
5094
+ return openedParam;
5095
+ },
5096
+ MakeAbstractConformanceForGenericType ());
5097
+ }
5098
+
5099
+ if (genericSig) {
5100
+ // If the type parameter is beyond the domain of the opened
5101
+ // signature, ignore it.
5102
+ if (!genericSig->isValidTypeParameter (type)) {
5103
+ return GenericParameterReferenceInfo ();
5104
+ }
5105
+
5106
+ if (auto reducedTy = genericSig.getReducedType (type)) {
5107
+ if (!reducedTy->isEqual (type)) {
5108
+ // Note: origParam becomes openedParam for the recursive call,
5109
+ // because concreteTy is written in terms of genericSig and not
5110
+ // the signature of the old origParam.
5111
+ return findGenericParameterReferencesRec (
5112
+ CanGenericSignature (), openedParam, openedParam, reducedTy,
5113
+ position, canBeCovariantResult);
5114
+ }
5115
+ }
5093
5116
}
5094
5117
5095
5118
// A reference to an associated type rooted on 'Self'.
@@ -5099,11 +5122,10 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig,
5099
5122
GenericParameterReferenceInfo
5100
5123
swift::findGenericParameterReferences (const ValueDecl *value,
5101
5124
CanGenericSignature sig,
5102
- GenericTypeParamType *genericParam,
5125
+ GenericTypeParamType *origParam,
5126
+ GenericTypeParamType *openedParam,
5103
5127
std::optional<unsigned > skipParamIndex) {
5104
5128
assert (!isa<TypeDecl>(value));
5105
- assert (sig->getGenericParamOrdinal (genericParam) <
5106
- sig.getGenericParams ().size ());
5107
5129
5108
5130
auto type = value->getInterfaceType ();
5109
5131
@@ -5118,12 +5140,12 @@ swift::findGenericParameterReferences(const ValueDecl *value,
5118
5140
type = type->castTo <AnyFunctionType>()->getResult ();
5119
5141
5120
5142
return ::findGenericParameterReferencesInFunction (
5121
- sig, genericParam , type->castTo <AnyFunctionType>(),
5143
+ sig, origParam, openedParam , type->castTo <AnyFunctionType>(),
5122
5144
TypePosition::Covariant, /* canBeCovariantResult=*/ true ,
5123
5145
skipParamIndex);
5124
5146
}
5125
5147
5126
- return ::findGenericParameterReferencesRec (sig, genericParam , type,
5148
+ return ::findGenericParameterReferencesRec (sig, origParam, openedParam , type,
5127
5149
TypePosition::Covariant,
5128
5150
/* canBeCovariantResult=*/ true );
5129
5151
}
@@ -5148,7 +5170,8 @@ GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences(
5148
5170
GenericSignature ());
5149
5171
5150
5172
auto genericParam = sig.getGenericParams ().front ();
5151
- return findGenericParameterReferences (this , sig, genericParam, std::nullopt);
5173
+ return findGenericParameterReferences (this , sig, genericParam, genericParam,
5174
+ std::nullopt);
5152
5175
}
5153
5176
5154
5177
TypeDecl::CanBeInvertible::Result
0 commit comments