@@ -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 == 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