@@ -2002,8 +2002,7 @@ static bool fixMissingArguments(ConstraintSystem &cs, ASTNode anchor,
2002
2002
// synthesized arguments to it.
2003
2003
if (argumentTuple) {
2004
2004
cs.addConstraint (ConstraintKind::Bind, *argumentTuple,
2005
- FunctionType::composeTuple (ctx, args,
2006
- /* canonicalVararg=*/ false ),
2005
+ FunctionType::composeTuple (ctx, args),
2007
2006
cs.getConstraintLocator (anchor));
2008
2007
}
2009
2008
@@ -2206,21 +2205,39 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
2206
2205
// take multiple arguments to be passed as an argument in places
2207
2206
// that expect a function that takes a single tuple (of the same
2208
2207
// arity);
2209
- auto canImplodeParams = [&](ArrayRef<AnyFunctionType::Param> params) {
2208
+ auto canImplodeParams = [&](ArrayRef<AnyFunctionType::Param> params,
2209
+ const FunctionType *destFn) {
2210
2210
if (params.size () == 1 )
2211
2211
return false ;
2212
2212
2213
- for ( auto param : params)
2214
- if (param. isVariadic () || param. isInOut () || param. isAutoClosure ())
2215
- return false ;
2213
+ // We do not support imploding into a @differentiable function.
2214
+ if (destFn-> isDifferentiable ())
2215
+ return false ;
2216
2216
2217
+ for (auto ¶m : params) {
2218
+ // We generally cannot handle parameter flags, though we can carve out an
2219
+ // exception for ownership flags such as __owned, which we can thunk, and
2220
+ // flags that can freely dropped from a function type such as
2221
+ // @_nonEphemeral. Note that @noDerivative can also be freely dropped, as
2222
+ // we've already ensured that the destination function is not
2223
+ // @differentiable.
2224
+ auto flags = param.getParameterFlags ();
2225
+ flags = flags.withValueOwnership (
2226
+ param.isInOut () ? ValueOwnership::InOut : ValueOwnership::Default);
2227
+ flags = flags.withNonEphemeral (false )
2228
+ .withNoDerivative (false );
2229
+ if (!flags.isNone ())
2230
+ return false ;
2231
+ }
2217
2232
return true ;
2218
2233
};
2219
2234
2220
2235
auto implodeParams = [&](SmallVectorImpl<AnyFunctionType::Param> ¶ms) {
2236
+ // Form an imploded tuple type, dropping the parameter flags as although
2237
+ // canImplodeParams makes sure we're not dealing with vargs, inout, etc,
2238
+ // we may still have e.g ownership flags left over, which we can drop.
2221
2239
auto input = AnyFunctionType::composeTuple (getASTContext (), params,
2222
- /* canonicalVararg=*/ false );
2223
-
2240
+ /* wantParamFlags*/ false );
2224
2241
params.clear ();
2225
2242
// If fixes are disabled let's do an easy thing and implode
2226
2243
// tuple directly into parameters list.
@@ -2255,12 +2272,12 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
2255
2272
if (last != path.rend ()) {
2256
2273
if (last->getKind () == ConstraintLocator::ApplyArgToParam) {
2257
2274
if (isSingleTupleParam (ctx, func2Params) &&
2258
- canImplodeParams (func1Params)) {
2275
+ canImplodeParams (func1Params, /* destFn */ func2 )) {
2259
2276
implodeParams (func1Params);
2260
2277
increaseScore (SK_FunctionConversion);
2261
2278
} else if (!ctx.isSwiftVersionAtLeast (5 ) &&
2262
2279
isSingleTupleParam (ctx, func1Params) &&
2263
- canImplodeParams (func2Params)) {
2280
+ canImplodeParams (func2Params, /* destFn */ func1 )) {
2264
2281
auto *simplified = locator.trySimplifyToExpr ();
2265
2282
// We somehow let tuple unsplatting function conversions
2266
2283
// through in some cases in Swift 4, so let's let that
@@ -2296,11 +2313,11 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
2296
2313
// 2. `case .bar(let tuple) = e` allows to match multiple
2297
2314
// parameters with a single tuple argument.
2298
2315
if (isSingleTupleParam (ctx, func1Params) &&
2299
- canImplodeParams (func2Params)) {
2316
+ canImplodeParams (func2Params, /* destFn */ func1 )) {
2300
2317
implodeParams (func2Params);
2301
2318
increaseScore (SK_FunctionConversion);
2302
2319
} else if (isSingleTupleParam (ctx, func2Params) &&
2303
- canImplodeParams (func1Params)) {
2320
+ canImplodeParams (func1Params, /* destFn */ func2 )) {
2304
2321
implodeParams (func1Params);
2305
2322
increaseScore (SK_FunctionConversion);
2306
2323
}
@@ -2311,7 +2328,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
2311
2328
auto *anchor = locator.trySimplifyToExpr ();
2312
2329
if (isa_and_nonnull<ClosureExpr>(anchor) &&
2313
2330
isSingleTupleParam (ctx, func2Params) &&
2314
- canImplodeParams (func1Params)) {
2331
+ canImplodeParams (func1Params, /* destFn */ func2 )) {
2315
2332
auto *fix = AllowClosureParamDestructuring::create (
2316
2333
*this , func2, getConstraintLocator (anchor));
2317
2334
if (recordFix (fix))
@@ -6073,8 +6090,7 @@ ConstraintSystem::simplifyConstructionConstraint(
6073
6090
6074
6091
// Tuple construction is simply tuple conversion.
6075
6092
Type argType = AnyFunctionType::composeTuple (getASTContext (),
6076
- fnType->getParams (),
6077
- /* canonicalVararg=*/ false );
6093
+ fnType->getParams ());
6078
6094
Type resultType = fnType->getResult ();
6079
6095
6080
6096
ConstraintLocatorBuilder builder (locator);
@@ -7006,8 +7022,7 @@ ConstraintSystem::simplifyFunctionComponentConstraint(
7006
7022
7007
7023
if (kind == ConstraintKind::FunctionInput) {
7008
7024
type = AnyFunctionType::composeTuple (getASTContext (),
7009
- funcTy->getParams (),
7010
- /* canonicalVararg=*/ false );
7025
+ funcTy->getParams ());
7011
7026
locKind = ConstraintLocator::FunctionArgument;
7012
7027
} else if (kind == ConstraintKind::FunctionResult) {
7013
7028
type = funcTy->getResult ();
0 commit comments