@@ -5490,7 +5490,7 @@ Solution::resolveLocatorToDecl(ConstraintLocator *locator) const {
5490
5490
// / index. This looks through inheritance for inherited default args.
5491
5491
static ConcreteDeclRef getDefaultArgOwner (ConcreteDeclRef owner,
5492
5492
unsigned index) {
5493
- auto *param = getParameterAt (owner. getDecl () , index);
5493
+ auto *param = getParameterAt (owner, index);
5494
5494
assert (param);
5495
5495
if (param->getDefaultArgumentKind () == DefaultArgumentKind::Inherited) {
5496
5496
return getDefaultArgOwner (owner.getOverriddenDecl (), index);
@@ -5851,6 +5851,65 @@ static void applyContextualClosureFlags(
5851
5851
}
5852
5852
}
5853
5853
5854
+ // For variadic generic declarations we need to compute a substituted
5855
+ // version of bindings because all of the packs are exploaded in the
5856
+ // substituted function type.
5857
+ //
5858
+ // \code
5859
+ // func fn<each T>(_: repeat each T) {}
5860
+ //
5861
+ // fn("", 42)
5862
+ // \endcode
5863
+ //
5864
+ // The type of `fn` in the call is `(String, Int) -> Void` but bindings
5865
+ // have only one parameter at index `0` with two argument positions: 0, 1.
5866
+ static bool shouldSubstituteParameterBindings (ConcreteDeclRef callee) {
5867
+ auto subst = callee.getSubstitutions ();
5868
+ if (subst.empty ())
5869
+ return false ;
5870
+
5871
+ auto sig = subst.getGenericSignature ();
5872
+ return llvm::any_of (
5873
+ sig.getGenericParams (),
5874
+ [&](const GenericTypeParamType *GP) { return GP->isParameterPack (); });
5875
+ }
5876
+
5877
+ // / Compute parameter binding substitutions by exploding pack expansions
5878
+ // / into multiple bindings (if they matched more than one argument) and
5879
+ // / ignoring empty ones.
5880
+ static void computeParameterBindingsSubstitutions (
5881
+ ConcreteDeclRef callee, ArrayRef<AnyFunctionType::Param> params,
5882
+ ArrayRef<ParamBinding> origBindings,
5883
+ SmallVectorImpl<ParamBinding> &substitutedBindings) {
5884
+ for (unsigned bindingIdx = 0 , numBindings = origBindings.size ();
5885
+ bindingIdx != numBindings; ++bindingIdx) {
5886
+ if (origBindings[bindingIdx].size () > 1 ) {
5887
+ const auto ¶m = params[substitutedBindings.size ()];
5888
+ if (!param.isVariadic ()) {
5889
+ #ifndef NDEBUG
5890
+ auto *PD = getParameterAt (callee.getDecl (), bindingIdx);
5891
+ assert (PD && PD->getInterfaceType ()->is <PackExpansionType>());
5892
+ #endif
5893
+ // Explode binding set to match substituted function parameters.
5894
+ for (auto argIdx : origBindings[bindingIdx])
5895
+ substitutedBindings.push_back ({argIdx});
5896
+ continue ;
5897
+ }
5898
+ }
5899
+
5900
+ const auto &bindings = origBindings[bindingIdx];
5901
+ if (bindings.size () == 0 ) {
5902
+ auto *PD = getParameterAt (callee.getDecl (), bindingIdx);
5903
+ // Skip pack expansions with no arguments because they are not
5904
+ // present in the substituted function type.
5905
+ if (PD->getInterfaceType ()->is <PackExpansionType>())
5906
+ continue ;
5907
+ }
5908
+
5909
+ substitutedBindings.push_back (bindings);
5910
+ }
5911
+ }
5912
+
5854
5913
ArgumentList *ExprRewriter::coerceCallArguments (
5855
5914
ArgumentList *args, AnyFunctionType *funcType, ConcreteDeclRef callee,
5856
5915
ApplyExpr *apply, ConstraintLocatorBuilder locator,
@@ -5904,9 +5963,18 @@ ArgumentList *ExprRewriter::coerceCallArguments(
5904
5963
assert (solution.argumentMatchingChoices .count (locatorPtr) == 1 );
5905
5964
auto parameterBindings = solution.argumentMatchingChoices .find (locatorPtr)
5906
5965
->second .parameterBindings ;
5966
+ bool shouldSubstituteBindings = shouldSubstituteParameterBindings (callee);
5967
+
5968
+ SmallVector<ParamBinding, 4 > substitutedBindings;
5969
+ if (shouldSubstituteBindings) {
5970
+ computeParameterBindingsSubstitutions (callee, params, parameterBindings,
5971
+ substitutedBindings);
5972
+ } else {
5973
+ substitutedBindings = parameterBindings;
5974
+ }
5907
5975
5908
5976
SmallVector<Argument, 4 > newArgs;
5909
- for (unsigned paramIdx = 0 , numParams = parameterBindings .size ();
5977
+ for (unsigned paramIdx = 0 , numParams = substitutedBindings .size ();
5910
5978
paramIdx != numParams; ++paramIdx) {
5911
5979
// Extract the parameter.
5912
5980
const auto ¶m = params[paramIdx];
@@ -5920,7 +5988,7 @@ ArgumentList *ExprRewriter::coerceCallArguments(
5920
5988
5921
5989
// The first argument of this vararg parameter may have had a label;
5922
5990
// save its location.
5923
- auto &varargIndices = parameterBindings [paramIdx];
5991
+ auto &varargIndices = substitutedBindings [paramIdx];
5924
5992
SourceLoc labelLoc;
5925
5993
if (!varargIndices.empty ())
5926
5994
labelLoc = args->getLabelLoc (varargIndices[0 ]);
@@ -5969,11 +6037,22 @@ ArgumentList *ExprRewriter::coerceCallArguments(
5969
6037
}
5970
6038
5971
6039
// Handle default arguments.
5972
- if (parameterBindings[paramIdx].empty ()) {
6040
+ if (substitutedBindings[paramIdx].empty ()) {
6041
+ auto paramIdxForDefault = paramIdx;
6042
+ // If bindings were substituted we need to find "original"
6043
+ // (or contextless) parameter index for the default argument.
6044
+ if (shouldSubstituteBindings) {
6045
+ auto *paramList = getParameterList (callee.getDecl ());
6046
+ assert (paramList);
6047
+ paramIdxForDefault =
6048
+ paramList->getOrigParamIndex (callee.getSubstitutions (), paramIdx);
6049
+ }
6050
+
5973
6051
auto owner = getDefaultArgOwner (callee, paramIdx);
5974
6052
auto paramTy = param.getParameterType ();
5975
6053
auto *defArg = new (ctx) DefaultArgumentExpr (
5976
- owner, paramIdx, args->getStartLoc (), paramTy, dc);
6054
+ owner, paramIdxForDefault, args->getStartLoc (), paramTy, dc);
6055
+
5977
6056
cs.cacheType (defArg);
5978
6057
newArgs.emplace_back (SourceLoc (), param.getLabel (), defArg);
5979
6058
continue ;
@@ -5982,8 +6061,8 @@ ArgumentList *ExprRewriter::coerceCallArguments(
5982
6061
// Otherwise, we have a plain old ordinary argument.
5983
6062
5984
6063
// Extract the argument used to initialize this parameter.
5985
- assert (parameterBindings [paramIdx].size () == 1 );
5986
- unsigned argIdx = parameterBindings [paramIdx].front ();
6064
+ assert (substitutedBindings [paramIdx].size () == 1 );
6065
+ unsigned argIdx = substitutedBindings [paramIdx].front ();
5987
6066
auto arg = args->get (argIdx);
5988
6067
auto *argExpr = arg.getExpr ();
5989
6068
auto argType = cs.getType (argExpr);
@@ -6027,7 +6106,7 @@ ArgumentList *ExprRewriter::coerceCallArguments(
6027
6106
};
6028
6107
6029
6108
if (paramInfo.hasExternalPropertyWrapper (paramIdx)) {
6030
- auto *paramDecl = getParameterAt (callee. getDecl () , paramIdx);
6109
+ auto *paramDecl = getParameterAt (callee, paramIdx);
6031
6110
assert (paramDecl);
6032
6111
6033
6112
auto appliedWrapper = appliedPropertyWrappers[appliedWrapperIndex++];
0 commit comments