@@ -491,9 +491,7 @@ namespace {
491
491
492
492
// Handle operator requirements found in protocols.
493
493
if (auto proto = dyn_cast<ProtocolDecl>(decl->getDeclContext ())) {
494
- bool isCurried = shouldBuildCurryThunk (choice,
495
- /* baseIsInstance=*/ false ,
496
- /* extraUncurryLevel=*/ false );
494
+ bool isCurried = shouldBuildCurryThunk (choice, /* baseIsInstance=*/ false );
497
495
498
496
// If we have a concrete conformance, build a call to the witness.
499
497
//
@@ -558,8 +556,7 @@ namespace {
558
556
cs.cacheExprTypes (base);
559
557
560
558
return buildMemberRef (base, SourceLoc (), overload, loc, locator,
561
- locator, implicit, /* extraUncurryLevel=*/ false ,
562
- semantics);
559
+ locator, implicit, semantics);
563
560
}
564
561
565
562
if (isa<TypeDecl>(decl) && !isa<ModuleDecl>(decl)) {
@@ -669,6 +666,10 @@ namespace {
669
666
670
667
// / Calculates the nesting depth of the current application.
671
668
unsigned getArgCount (unsigned maxArgCount) {
669
+ // FIXME: Walking over the ExprStack to figure out the number of argument
670
+ // lists being applied is brittle. We should instead be checking
671
+ // hasAppliedSelf to figure out if the self param is applied, and looking
672
+ // at the FunctionRefKind to see if the parameter list is applied.
672
673
unsigned e = ExprStack.size ();
673
674
unsigned argCount;
674
675
@@ -812,8 +813,7 @@ namespace {
812
813
// / converted into a fully-applied member reference with a pair of
813
814
// / closures.
814
815
bool shouldBuildCurryThunk (OverloadChoice choice,
815
- bool baseIsInstance,
816
- bool extraUncurryLevel) {
816
+ bool baseIsInstance) {
817
817
ValueDecl *member = choice.getDecl ();
818
818
auto isDynamic = choice.getKind () == OverloadChoiceKind::DeclViaDynamic;
819
819
@@ -848,29 +848,20 @@ namespace {
848
848
isa<CallExpr>(prev) &&
849
849
isa<TypeExpr>(cast<CallExpr>(prev)->getFn ())) {
850
850
assert (maxArgCount == 2 );
851
- return 1 ;
851
+ return 2 ;
852
852
}
853
853
854
854
// Similarly, ".foo(...)" really applies two argument lists.
855
855
if (auto *unresolvedMemberExpr = dyn_cast<UnresolvedMemberExpr>(prev)) {
856
856
if (unresolvedMemberExpr->hasArguments () ||
857
857
unresolvedMemberExpr->hasTrailingClosure ())
858
- return 1 ;
859
- return 0 ;
858
+ return 2 ;
859
+ return 1 ;
860
860
}
861
861
862
862
return getArgCount (maxArgCount);
863
863
}();
864
864
865
- // Sometimes we build a member reference that has an implicit
866
- // level of function application in the AST. For example,
867
- // @dynamicCallable and callAsFunction are handled this way.
868
- //
869
- // FIXME: It would be nice to simplify this and the argCount
870
- // computation above somehow.
871
- if (extraUncurryLevel)
872
- argCount++;
873
-
874
865
// If we have fewer argument lists than expected, build a thunk.
875
866
if (argCount < maxArgCount)
876
867
return true ;
@@ -1062,7 +1053,7 @@ namespace {
1062
1053
SelectedOverload overload, DeclNameLoc memberLoc,
1063
1054
ConstraintLocatorBuilder locator,
1064
1055
ConstraintLocatorBuilder memberLocator, bool Implicit,
1065
- bool extraUncurryLevel, AccessSemantics semantics) {
1056
+ AccessSemantics semantics) {
1066
1057
auto choice = overload.choice ;
1067
1058
auto openedType = overload.openedType ;
1068
1059
auto openedFullType = overload.openedFullType ;
@@ -1116,8 +1107,7 @@ namespace {
1116
1107
1117
1108
bool isUnboundInstanceMember =
1118
1109
(!baseIsInstance && member->isInstanceMember ());
1119
- bool isPartialApplication =
1120
- shouldBuildCurryThunk (choice, baseIsInstance, extraUncurryLevel);
1110
+ bool isPartialApplication = shouldBuildCurryThunk (choice, baseIsInstance);
1121
1111
1122
1112
auto refTy = simplifyType (openedFullType);
1123
1113
@@ -1549,12 +1539,11 @@ namespace {
1549
1539
ConstraintLocatorBuilder locator,
1550
1540
ConstraintLocatorBuilder calleeLocator);
1551
1541
1552
- // Resolve `@dynamicCallable` applications.
1553
- Expr *finishApplyDynamicCallable (ApplyExpr *apply,
1554
- SelectedOverload selected,
1555
- FuncDecl *method,
1556
- AnyFunctionType *methodType,
1557
- ConstraintLocatorBuilder applyFunctionLoc);
1542
+ // / Build the function and argument for a `@dynamicCallable` application.
1543
+ std::pair</* fn*/ Expr *, /* arg*/ Expr *>
1544
+ buildDynamicCallable (ApplyExpr *apply, SelectedOverload selected,
1545
+ FuncDecl *method, AnyFunctionType *methodType,
1546
+ ConstraintLocatorBuilder applyFunctionLoc);
1558
1547
1559
1548
private:
1560
1549
// / Simplify the given type by substituting all occurrences of
@@ -2761,7 +2750,7 @@ namespace {
2761
2750
return buildMemberRef (
2762
2751
expr->getBase (), expr->getDotLoc (), selected, expr->getNameLoc (),
2763
2752
cs.getConstraintLocator (expr), memberLocator, expr->isImplicit (),
2764
- /* extraUncurryLevel= */ false , expr->getAccessSemantics ());
2753
+ expr->getAccessSemantics ());
2765
2754
}
2766
2755
2767
2756
Expr *visitDynamicMemberRefExpr (DynamicMemberRefExpr *expr) {
@@ -2804,8 +2793,7 @@ namespace {
2804
2793
auto *exprLoc = cs.getConstraintLocator (expr);
2805
2794
auto result = buildMemberRef (
2806
2795
base, expr->getDotLoc (), selected, expr->getNameLoc (), exprLoc,
2807
- memberLocator, expr->isImplicit (), /* extraUncurryLevel=*/ true ,
2808
- AccessSemantics::Ordinary);
2796
+ memberLocator, expr->isImplicit (), AccessSemantics::Ordinary);
2809
2797
if (!result)
2810
2798
return nullptr ;
2811
2799
@@ -2953,8 +2941,7 @@ namespace {
2953
2941
if (cs.getType (base)->is <AnyMetatypeType>()) {
2954
2942
return buildMemberRef (
2955
2943
base, dotLoc, overload, nameLoc, cs.getConstraintLocator (expr),
2956
- ctorLocator, implicit, /* extraUncurryLevel=*/ true ,
2957
- AccessSemantics::Ordinary);
2944
+ ctorLocator, implicit, AccessSemantics::Ordinary);
2958
2945
}
2959
2946
2960
2947
// The subexpression must be either 'self' or 'super'.
@@ -3127,8 +3114,7 @@ namespace {
3127
3114
case OverloadChoiceKind::DeclViaDynamic:
3128
3115
return buildMemberRef (base, dotLoc, selected, nameLoc,
3129
3116
cs.getConstraintLocator (expr), memberLocator,
3130
- implicit, /* extraUncurryLevel=*/ false ,
3131
- AccessSemantics::Ordinary);
3117
+ implicit, AccessSemantics::Ordinary);
3132
3118
3133
3119
case OverloadChoiceKind::TupleIndex: {
3134
3120
Type toType = simplifyType (cs.getType (expr));
@@ -7142,23 +7128,31 @@ static Expr *buildCallAsFunctionMethodRef(
7142
7128
// Create direct reference to `callAsFunction` method.
7143
7129
auto *fn = apply->getFn ();
7144
7130
auto *arg = apply->getArg ();
7131
+
7132
+ // HACK: Temporarily push the fn expr onto the expr stack to make sure we
7133
+ // don't try to prematurely close an existential when applying the curried
7134
+ // member ref. This can be removed once existential opening is refactored not
7135
+ // to rely on the shape of the AST prior to rewriting.
7136
+ rewriter.ExprStack .push_back (fn);
7137
+ SWIFT_DEFER {
7138
+ rewriter.ExprStack .pop_back ();
7139
+ };
7140
+
7145
7141
auto *declRef = rewriter.buildMemberRef (
7146
7142
fn, /* dotLoc*/ SourceLoc (), selected, DeclNameLoc (arg->getStartLoc ()),
7147
- calleeLoc, calleeLoc, /* implicit*/ true ,
7148
- /* extraUncurryLevel=*/ true , AccessSemantics::Ordinary);
7143
+ calleeLoc, calleeLoc, /* implicit*/ true , AccessSemantics::Ordinary);
7149
7144
if (!declRef)
7150
7145
return nullptr ;
7151
7146
declRef->setImplicit (apply->isImplicit ());
7152
7147
return declRef;
7153
7148
}
7154
7149
7155
7150
// Resolve `@dynamicCallable` applications.
7156
- Expr *
7157
- ExprRewriter::finishApplyDynamicCallable (ApplyExpr *apply,
7158
- SelectedOverload selected,
7159
- FuncDecl *method,
7160
- AnyFunctionType *methodType,
7161
- ConstraintLocatorBuilder loc) {
7151
+ std::pair<Expr *, Expr *>
7152
+ ExprRewriter::buildDynamicCallable (ApplyExpr *apply, SelectedOverload selected,
7153
+ FuncDecl *method,
7154
+ AnyFunctionType *methodType,
7155
+ ConstraintLocatorBuilder loc) {
7162
7156
auto &ctx = cs.getASTContext ();
7163
7157
auto *fn = apply->getFn ();
7164
7158
@@ -7176,11 +7170,19 @@ ExprRewriter::finishApplyDynamicCallable(ApplyExpr *apply,
7176
7170
auto argumentLabel = methodType->getParams ()[0 ].getLabel ();
7177
7171
bool useKwargsMethod = argumentLabel == ctx.Id_withKeywordArguments ;
7178
7172
7173
+ // HACK: Temporarily push the fn expr onto the expr stack to make sure we
7174
+ // don't try to prematurely close an existential when applying the curried
7175
+ // member ref. This can be removed once existential opening is refactored not
7176
+ // to rely on the shape of the AST prior to rewriting.
7177
+ ExprStack.push_back (fn);
7178
+ SWIFT_DEFER {
7179
+ ExprStack.pop_back ();
7180
+ };
7181
+
7179
7182
// Construct expression referencing the `dynamicallyCall` method.
7180
7183
auto member = buildMemberRef (fn, SourceLoc (), selected,
7181
7184
DeclNameLoc (method->getNameLoc ()), loc, loc,
7182
- /* implicit=*/ true , /* extraUncurryLevel=*/ true ,
7183
- AccessSemantics::Ordinary);
7185
+ /* implicit=*/ true , AccessSemantics::Ordinary);
7184
7186
7185
7187
// Construct argument to the method (either an array or dictionary
7186
7188
// expression).
@@ -7210,8 +7212,7 @@ ExprRewriter::finishApplyDynamicCallable(ApplyExpr *apply,
7210
7212
handleStringLiteralExpr (cast<LiteralExpr>(labelExpr));
7211
7213
7212
7214
Expr *valueExpr = coerceToType (arg->getElement (i), valueType, loc);
7213
- if (!valueExpr)
7214
- return nullptr ;
7215
+ assert (valueExpr && " Failed to coerce?" );
7215
7216
Expr *pair = TupleExpr::createImplicit (ctx, {labelExpr, valueExpr}, {});
7216
7217
auto eltTypes = { TupleTypeElt (keyType), TupleTypeElt (valueType) };
7217
7218
cs.setType (pair, TupleType::get (eltTypes, ctx));
@@ -7224,22 +7225,21 @@ ExprRewriter::finishApplyDynamicCallable(ApplyExpr *apply,
7224
7225
}
7225
7226
argument->setImplicit ();
7226
7227
7227
- // Construct call to the `dynamicallyCall` method.
7228
- auto result = CallExpr::createImplicit (ctx, member, argument,
7229
- { argumentLabel });
7230
- cs.setType (result->getArg (), AnyFunctionType::composeInput (ctx, params,
7231
- false ));
7232
- cs.setType (result, methodType->getResult ());
7233
- cs.cacheExprTypes (result);
7234
- return result;
7228
+ // Build the argument list expr.
7229
+ argument = TupleExpr::createImplicit (ctx, {argument}, {argumentLabel});
7230
+ cs.setType (argument,
7231
+ TupleType::get ({TupleTypeElt (argumentType, argumentLabel)}, ctx));
7232
+
7233
+ return std::make_pair (member, argument);
7235
7234
}
7236
7235
7237
7236
Expr *ExprRewriter::finishApply (ApplyExpr *apply, Type openedType,
7238
7237
ConstraintLocatorBuilder locator,
7239
7238
ConstraintLocatorBuilder calleeLocator) {
7240
7239
auto &ctx = cs.getASTContext ();
7241
-
7242
- auto fn = apply->getFn ();
7240
+
7241
+ auto *arg = apply->getArg ();
7242
+ auto *fn = apply->getFn ();
7243
7243
7244
7244
bool hasTrailingClosure =
7245
7245
isa<CallExpr>(apply) && cast<CallExpr>(apply)->hasTrailingClosure ();
@@ -7408,7 +7408,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
7408
7408
if (method && methodType) {
7409
7409
// Handle a call to a @dynamicCallable method.
7410
7410
if (isValidDynamicCallableMethod (method, methodType))
7411
- return finishApplyDynamicCallable (
7411
+ std::tie (fn, arg) = buildDynamicCallable (
7412
7412
apply, *selected, method, methodType, applyFunctionLoc);
7413
7413
}
7414
7414
}
@@ -7465,13 +7465,11 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
7465
7465
// the function.
7466
7466
SmallVector<Identifier, 2 > argLabelsScratch;
7467
7467
if (auto fnType = cs.getType (fn)->getAs <FunctionType>()) {
7468
- auto origArg = apply->getArg ();
7469
- Expr *arg = coerceCallArguments (origArg, fnType, callee,
7470
- apply,
7471
- apply->getArgumentLabels (argLabelsScratch),
7472
- hasTrailingClosure,
7473
- locator.withPathElement (
7474
- ConstraintLocator::ApplyArgument));
7468
+ arg = coerceCallArguments (arg, fnType, callee, apply,
7469
+ apply->getArgumentLabels (argLabelsScratch),
7470
+ hasTrailingClosure,
7471
+ locator.withPathElement (
7472
+ ConstraintLocator::ApplyArgument));
7475
7473
if (!arg) {
7476
7474
return nullptr ;
7477
7475
}
@@ -7542,7 +7540,6 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
7542
7540
Expr *declRef = buildMemberRef (fn, /* dotLoc=*/ SourceLoc (), *selected,
7543
7541
DeclNameLoc (fn->getEndLoc ()), locator,
7544
7542
ctorLocator, /* implicit=*/ true ,
7545
- /* extraUncurryLevel=*/ true ,
7546
7543
AccessSemantics::Ordinary);
7547
7544
if (!declRef)
7548
7545
return nullptr ;
0 commit comments