@@ -484,9 +484,7 @@ namespace {
484
484
485
485
// Handle operator requirements found in protocols.
486
486
if (auto proto = dyn_cast<ProtocolDecl>(decl->getDeclContext ())) {
487
- bool isCurried = shouldBuildCurryThunk (choice,
488
- /* baseIsInstance=*/ false ,
489
- /* extraUncurryLevel=*/ false );
487
+ bool isCurried = shouldBuildCurryThunk (choice, /* baseIsInstance=*/ false );
490
488
491
489
// If we have a concrete conformance, build a call to the witness.
492
490
//
@@ -551,8 +549,7 @@ namespace {
551
549
cs.cacheExprTypes (base);
552
550
553
551
return buildMemberRef (base, SourceLoc (), overload, loc, locator,
554
- locator, implicit, /* extraUncurryLevel=*/ false ,
555
- semantics);
552
+ locator, implicit, semantics);
556
553
}
557
554
558
555
if (isa<TypeDecl>(decl) && !isa<ModuleDecl>(decl)) {
@@ -662,6 +659,10 @@ namespace {
662
659
663
660
// / Calculates the nesting depth of the current application.
664
661
unsigned getArgCount (unsigned maxArgCount) {
662
+ // FIXME: Walking over the ExprStack to figure out the number of argument
663
+ // lists being applied is brittle. We should instead be checking
664
+ // hasAppliedSelf to figure out if the self param is applied, and looking
665
+ // at the FunctionRefKind to see if the parameter list is applied.
665
666
unsigned e = ExprStack.size ();
666
667
unsigned argCount;
667
668
@@ -805,8 +806,7 @@ namespace {
805
806
// / converted into a fully-applied member reference with a pair of
806
807
// / closures.
807
808
bool shouldBuildCurryThunk (OverloadChoice choice,
808
- bool baseIsInstance,
809
- bool extraUncurryLevel) {
809
+ bool baseIsInstance) {
810
810
ValueDecl *member = choice.getDecl ();
811
811
auto isDynamic = choice.getKind () == OverloadChoiceKind::DeclViaDynamic;
812
812
@@ -841,29 +841,20 @@ namespace {
841
841
isa<CallExpr>(prev) &&
842
842
isa<TypeExpr>(cast<CallExpr>(prev)->getFn ())) {
843
843
assert (maxArgCount == 2 );
844
- return 1 ;
844
+ return 2 ;
845
845
}
846
846
847
847
// Similarly, ".foo(...)" really applies two argument lists.
848
848
if (auto *unresolvedMemberExpr = dyn_cast<UnresolvedMemberExpr>(prev)) {
849
849
if (unresolvedMemberExpr->hasArguments () ||
850
850
unresolvedMemberExpr->hasTrailingClosure ())
851
- return 1 ;
852
- return 0 ;
851
+ return 2 ;
852
+ return 1 ;
853
853
}
854
854
855
855
return getArgCount (maxArgCount);
856
856
}();
857
857
858
- // Sometimes we build a member reference that has an implicit
859
- // level of function application in the AST. For example,
860
- // @dynamicCallable and callAsFunction are handled this way.
861
- //
862
- // FIXME: It would be nice to simplify this and the argCount
863
- // computation above somehow.
864
- if (extraUncurryLevel)
865
- argCount++;
866
-
867
858
// If we have fewer argument lists than expected, build a thunk.
868
859
if (argCount < maxArgCount)
869
860
return true ;
@@ -1055,7 +1046,7 @@ namespace {
1055
1046
SelectedOverload overload, DeclNameLoc memberLoc,
1056
1047
ConstraintLocatorBuilder locator,
1057
1048
ConstraintLocatorBuilder memberLocator, bool Implicit,
1058
- bool extraUncurryLevel, AccessSemantics semantics) {
1049
+ AccessSemantics semantics) {
1059
1050
auto choice = overload.choice ;
1060
1051
auto openedType = overload.openedType ;
1061
1052
auto openedFullType = overload.openedFullType ;
@@ -1109,8 +1100,7 @@ namespace {
1109
1100
1110
1101
bool isUnboundInstanceMember =
1111
1102
(!baseIsInstance && member->isInstanceMember ());
1112
- bool isPartialApplication =
1113
- shouldBuildCurryThunk (choice, baseIsInstance, extraUncurryLevel);
1103
+ bool isPartialApplication = shouldBuildCurryThunk (choice, baseIsInstance);
1114
1104
1115
1105
auto refTy = simplifyType (openedFullType);
1116
1106
@@ -2753,7 +2743,7 @@ namespace {
2753
2743
return buildMemberRef (
2754
2744
expr->getBase (), expr->getDotLoc (), selected, expr->getNameLoc (),
2755
2745
cs.getConstraintLocator (expr), memberLocator, expr->isImplicit (),
2756
- /* extraUncurryLevel= */ false , expr->getAccessSemantics ());
2746
+ expr->getAccessSemantics ());
2757
2747
}
2758
2748
2759
2749
Expr *visitDynamicMemberRefExpr (DynamicMemberRefExpr *expr) {
@@ -2796,8 +2786,7 @@ namespace {
2796
2786
auto *exprLoc = cs.getConstraintLocator (expr);
2797
2787
auto result = buildMemberRef (
2798
2788
base, expr->getDotLoc (), selected, expr->getNameLoc (), exprLoc,
2799
- memberLocator, expr->isImplicit (), /* extraUncurryLevel=*/ true ,
2800
- AccessSemantics::Ordinary);
2789
+ memberLocator, expr->isImplicit (), AccessSemantics::Ordinary);
2801
2790
if (!result)
2802
2791
return nullptr ;
2803
2792
@@ -2945,8 +2934,7 @@ namespace {
2945
2934
if (cs.getType (base)->is <AnyMetatypeType>()) {
2946
2935
return buildMemberRef (
2947
2936
base, dotLoc, overload, nameLoc, cs.getConstraintLocator (expr),
2948
- ctorLocator, implicit, /* extraUncurryLevel=*/ true ,
2949
- AccessSemantics::Ordinary);
2937
+ ctorLocator, implicit, AccessSemantics::Ordinary);
2950
2938
}
2951
2939
2952
2940
// The subexpression must be either 'self' or 'super'.
@@ -3119,8 +3107,7 @@ namespace {
3119
3107
case OverloadChoiceKind::DeclViaDynamic:
3120
3108
return buildMemberRef (base, dotLoc, selected, nameLoc,
3121
3109
cs.getConstraintLocator (expr), memberLocator,
3122
- implicit, /* extraUncurryLevel=*/ false ,
3123
- AccessSemantics::Ordinary);
3110
+ implicit, AccessSemantics::Ordinary);
3124
3111
3125
3112
case OverloadChoiceKind::TupleIndex: {
3126
3113
Type toType = simplifyType (cs.getType (expr));
@@ -7134,10 +7121,19 @@ static Expr *buildCallAsFunctionMethodRef(
7134
7121
// Create direct reference to `callAsFunction` method.
7135
7122
auto *fn = apply->getFn ();
7136
7123
auto *arg = apply->getArg ();
7124
+
7125
+ // HACK: Temporarily push the fn expr onto the expr stack to make sure we
7126
+ // don't try to prematurely close an existential when applying the curried
7127
+ // member ref. This can be removed once existential opening is refactored not
7128
+ // to rely on the shape of the AST prior to rewriting.
7129
+ rewriter.ExprStack .push_back (fn);
7130
+ SWIFT_DEFER {
7131
+ rewriter.ExprStack .pop_back ();
7132
+ };
7133
+
7137
7134
auto *declRef = rewriter.buildMemberRef (
7138
7135
fn, /* dotLoc*/ SourceLoc (), selected, DeclNameLoc (arg->getStartLoc ()),
7139
- calleeLoc, calleeLoc, /* implicit*/ true ,
7140
- /* extraUncurryLevel=*/ true , AccessSemantics::Ordinary);
7136
+ calleeLoc, calleeLoc, /* implicit*/ true , AccessSemantics::Ordinary);
7141
7137
if (!declRef)
7142
7138
return nullptr ;
7143
7139
declRef->setImplicit (apply->isImplicit ());
@@ -7167,11 +7163,19 @@ ExprRewriter::buildDynamicCallable(ApplyExpr *apply, SelectedOverload selected,
7167
7163
auto argumentLabel = methodType->getParams ()[0 ].getLabel ();
7168
7164
bool useKwargsMethod = argumentLabel == ctx.Id_withKeywordArguments ;
7169
7165
7166
+ // HACK: Temporarily push the fn expr onto the expr stack to make sure we
7167
+ // don't try to prematurely close an existential when applying the curried
7168
+ // member ref. This can be removed once existential opening is refactored not
7169
+ // to rely on the shape of the AST prior to rewriting.
7170
+ ExprStack.push_back (fn);
7171
+ SWIFT_DEFER {
7172
+ ExprStack.pop_back ();
7173
+ };
7174
+
7170
7175
// Construct expression referencing the `dynamicallyCall` method.
7171
7176
auto member = buildMemberRef (fn, SourceLoc (), selected,
7172
7177
DeclNameLoc (method->getNameLoc ()), loc, loc,
7173
- /* implicit=*/ true , /* extraUncurryLevel=*/ true ,
7174
- AccessSemantics::Ordinary);
7178
+ /* implicit=*/ true , AccessSemantics::Ordinary);
7175
7179
7176
7180
// Construct argument to the method (either an array or dictionary
7177
7181
// expression).
@@ -7529,7 +7533,6 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
7529
7533
Expr *declRef = buildMemberRef (fn, /* dotLoc=*/ SourceLoc (), *selected,
7530
7534
DeclNameLoc (fn->getEndLoc ()), locator,
7531
7535
ctorLocator, /* implicit=*/ true ,
7532
- /* extraUncurryLevel=*/ true ,
7533
7536
AccessSemantics::Ordinary);
7534
7537
if (!declRef)
7535
7538
return nullptr ;
0 commit comments