@@ -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
@@ -2760,7 +2750,7 @@ namespace {
2760
2750
return buildMemberRef (
2761
2751
expr->getBase (), expr->getDotLoc (), selected, expr->getNameLoc (),
2762
2752
cs.getConstraintLocator (expr), memberLocator, expr->isImplicit (),
2763
- /* extraUncurryLevel= */ false , expr->getAccessSemantics ());
2753
+ expr->getAccessSemantics ());
2764
2754
}
2765
2755
2766
2756
Expr *visitDynamicMemberRefExpr (DynamicMemberRefExpr *expr) {
@@ -2803,8 +2793,7 @@ namespace {
2803
2793
auto *exprLoc = cs.getConstraintLocator (expr);
2804
2794
auto result = buildMemberRef (
2805
2795
base, expr->getDotLoc (), selected, expr->getNameLoc (), exprLoc,
2806
- memberLocator, expr->isImplicit (), /* extraUncurryLevel=*/ true ,
2807
- AccessSemantics::Ordinary);
2796
+ memberLocator, expr->isImplicit (), AccessSemantics::Ordinary);
2808
2797
if (!result)
2809
2798
return nullptr ;
2810
2799
@@ -2952,8 +2941,7 @@ namespace {
2952
2941
if (cs.getType (base)->is <AnyMetatypeType>()) {
2953
2942
return buildMemberRef (
2954
2943
base, dotLoc, overload, nameLoc, cs.getConstraintLocator (expr),
2955
- ctorLocator, implicit, /* extraUncurryLevel=*/ true ,
2956
- AccessSemantics::Ordinary);
2944
+ ctorLocator, implicit, AccessSemantics::Ordinary);
2957
2945
}
2958
2946
2959
2947
// The subexpression must be either 'self' or 'super'.
@@ -3126,8 +3114,7 @@ namespace {
3126
3114
case OverloadChoiceKind::DeclViaDynamic:
3127
3115
return buildMemberRef (base, dotLoc, selected, nameLoc,
3128
3116
cs.getConstraintLocator (expr), memberLocator,
3129
- implicit, /* extraUncurryLevel=*/ false ,
3130
- AccessSemantics::Ordinary);
3117
+ implicit, AccessSemantics::Ordinary);
3131
3118
3132
3119
case OverloadChoiceKind::TupleIndex: {
3133
3120
Type toType = simplifyType (cs.getType (expr));
@@ -7141,10 +7128,19 @@ static Expr *buildCallAsFunctionMethodRef(
7141
7128
// Create direct reference to `callAsFunction` method.
7142
7129
auto *fn = apply->getFn ();
7143
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
+
7144
7141
auto *declRef = rewriter.buildMemberRef (
7145
7142
fn, /* dotLoc*/ SourceLoc (), selected, DeclNameLoc (arg->getStartLoc ()),
7146
- calleeLoc, calleeLoc, /* implicit*/ true ,
7147
- /* extraUncurryLevel=*/ true , AccessSemantics::Ordinary);
7143
+ calleeLoc, calleeLoc, /* implicit*/ true , AccessSemantics::Ordinary);
7148
7144
if (!declRef)
7149
7145
return nullptr ;
7150
7146
declRef->setImplicit (apply->isImplicit ());
@@ -7174,11 +7170,19 @@ ExprRewriter::buildDynamicCallable(ApplyExpr *apply, SelectedOverload selected,
7174
7170
auto argumentLabel = methodType->getParams ()[0 ].getLabel ();
7175
7171
bool useKwargsMethod = argumentLabel == ctx.Id_withKeywordArguments ;
7176
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
+
7177
7182
// Construct expression referencing the `dynamicallyCall` method.
7178
7183
auto member = buildMemberRef (fn, SourceLoc (), selected,
7179
7184
DeclNameLoc (method->getNameLoc ()), loc, loc,
7180
- /* implicit=*/ true , /* extraUncurryLevel=*/ true ,
7181
- AccessSemantics::Ordinary);
7185
+ /* implicit=*/ true , AccessSemantics::Ordinary);
7182
7186
7183
7187
// Construct argument to the method (either an array or dictionary
7184
7188
// expression).
@@ -7536,7 +7540,6 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
7536
7540
Expr *declRef = buildMemberRef (fn, /* dotLoc=*/ SourceLoc (), *selected,
7537
7541
DeclNameLoc (fn->getEndLoc ()), locator,
7538
7542
ctorLocator, /* implicit=*/ true ,
7539
- /* extraUncurryLevel=*/ true ,
7540
7543
AccessSemantics::Ordinary);
7541
7544
if (!declRef)
7542
7545
return nullptr ;
0 commit comments