@@ -4370,11 +4370,6 @@ namespace {
4370
4370
4371
4371
auto dc = subscript->getInnermostDeclContext ();
4372
4372
4373
- // FIXME: It's not correct to turn the subscript's parameter list
4374
- // into a single type here. Further down we pass it to coerceToType(),
4375
- // but the rules for argument list conversions are different than
4376
- // tuple conversions, and coerceToType() doesn't handle varargs or
4377
- // default arguments.
4378
4373
auto indexType = AnyFunctionType::composeInput (
4379
4374
cs.TC .Context ,
4380
4375
subscript->getInterfaceType ()
@@ -4409,19 +4404,18 @@ namespace {
4409
4404
/* trailingClosure*/ nullptr );
4410
4405
cs.setType (origComponent.getIndexExpr (), index->getType ());
4411
4406
}
4412
-
4413
- auto resolvedTy = foundDecl->openedType ->castTo <AnyFunctionType>()
4414
- ->getResult ();
4415
-
4416
- resolvedTy = simplifyType (resolvedTy);
4417
-
4407
+
4408
+ auto subscriptType =
4409
+ simplifyType (foundDecl->openedType )->castTo <AnyFunctionType>();
4410
+ auto resolvedTy = subscriptType->getResult ();
4418
4411
auto ref = ConcreteDeclRef (subscript, subs);
4419
-
4412
+
4420
4413
// Coerce the indices to the type the subscript expects.
4421
- auto indexExpr = coerceToType (origComponent.getIndexExpr (),
4422
- indexType,
4423
- locator);
4424
-
4414
+ auto indexExpr = coerceCallArguments (
4415
+ origComponent.getIndexExpr (), subscriptType,
4416
+ /* applyExpr*/ nullptr , origComponent.getSubscriptLabels (),
4417
+ /* hasTrailingClosure */ false , locator);
4418
+
4425
4419
component = KeyPathExpr::Component
4426
4420
::forSubscriptWithPrebuiltIndexExpr (ref, indexExpr,
4427
4421
origComponent.getSubscriptLabels(),
@@ -5645,9 +5639,29 @@ Expr *ExprRewriter::coerceCallArguments(
5645
5639
continue ;
5646
5640
}
5647
5641
5648
- // Convert the argument.
5649
- auto convertedArg = coerceToType (arg, paramType,
5650
- getArgLocator (argIdx, paramIdx));
5642
+ Expr *convertedArg = nullptr ;
5643
+
5644
+ // Since it was allowed to pass function types to @autoclosure
5645
+ // parameters in Swift versions < 5, it has to be handled as
5646
+ // a regular function coversion by `coerceToType`.
5647
+ if (param.isAutoClosure () && !argType->is <FunctionType>()) {
5648
+ // If parameter is an autoclosure, we need to make sure that:
5649
+ // - argument type is coerced to parameter result type
5650
+ // - impilict autoclosure is created to wrap argument expression
5651
+ // - new types are propagated to constraint system
5652
+ auto *closureType = param.getPlainType ()->castTo <FunctionType>();
5653
+
5654
+ arg = coerceToType (
5655
+ arg, closureType->getResult (),
5656
+ locator.withPathElement (ConstraintLocator::AutoclosureResult));
5657
+
5658
+ convertedArg = cs.TC .buildAutoClosureExpr (dc, arg, closureType);
5659
+ cs.cacheExprTypes (convertedArg);
5660
+ } else {
5661
+ convertedArg =
5662
+ coerceToType (arg, paramType, getArgLocator (argIdx, paramIdx));
5663
+ }
5664
+
5651
5665
if (!convertedArg)
5652
5666
return nullptr ;
5653
5667
@@ -6536,59 +6550,10 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
6536
6550
isInDefaultArgumentContext = (initalizerCtx->getInitializerKind () ==
6537
6551
InitializerKind::DefaultArgument);
6538
6552
auto toEI = toFunc->getExtInfo ();
6539
-
6540
- auto fromFunc = fromType->getAs <FunctionType>();
6541
-
6542
- // Coercion to an autoclosure type produces an implicit closure.
6543
- // The constraint solver only performs this conversion when the source
6544
- // type is not an autoclosure function type. That's a weird rule in
6545
- // some rules, but it's easy to follow here. Really we just shouldn't
6546
- // represent autoclosures as a bit on function types.
6547
- // FIXME: The type checker is more lenient, and allows @autoclosures to
6548
- // be subtypes of non-@autoclosures, which is bogus.
6549
- if (toFunc->isAutoClosure () &&
6550
- (!fromFunc || !fromFunc->isAutoClosure ())) {
6551
- // The function type without @noescape if we are in the default argument
6552
- // context.
6553
- auto newToFuncType = toFunc;
6554
-
6555
- // Remove the noescape attribute so that we can apply a separate function
6556
- // conversion instruction if we are in a default argument context.
6557
- if (isInDefaultArgumentContext && toEI.isNoEscape ())
6558
- newToFuncType = toFunc->withExtInfo (toEI.withNoEscape (false ))
6559
- ->castTo <FunctionType>();
6560
-
6561
- // Convert the value to the expected result type of the function.
6562
- expr = coerceToType (
6563
- expr, toFunc->getResult (),
6564
- locator.withPathElement (ConstraintLocator::AutoclosureResult));
6565
-
6566
- // We'll set discriminator values on all the autoclosures in a
6567
- // later pass.
6568
- auto discriminator = AutoClosureExpr::InvalidDiscriminator;
6569
- auto closure = cs.cacheType (new (tc.Context ) AutoClosureExpr (
6570
- expr, newToFuncType, discriminator, dc));
6571
- closure->setParameterList (ParameterList::createEmpty (tc.Context ));
6572
-
6573
- // Compute the capture list, now that we have analyzed the expression.
6574
- tc.ClosuresWithUncomputedCaptures .push_back (closure);
6575
-
6576
- // Apply the noescape conversion.
6577
- if (!newToFuncType->isEqual (toFunc)) {
6578
- assert (isInDefaultArgumentContext);
6579
- assert (newToFuncType
6580
- ->withExtInfo (newToFuncType->getExtInfo ().withNoEscape (true ))
6581
- ->isEqual (toFunc));
6582
- return cs.cacheType (new (tc.Context )
6583
- FunctionConversionExpr (closure, toFunc));
6584
- }
6585
-
6586
- return closure;
6587
- }
6588
-
6589
6553
// Coercion from one function type to another, this produces a
6590
6554
// FunctionConversionExpr in its full generality.
6591
- if (fromFunc) {
6555
+ if (auto fromFunc = fromType->getAs <FunctionType>()) {
6556
+ assert (toType->is <FunctionType>());
6592
6557
// If we have a ClosureExpr, then we can safely propagate the 'no escape'
6593
6558
// bit to the closure without invalidating prior analysis.
6594
6559
auto fromEI = fromFunc->getExtInfo ();
0 commit comments