@@ -110,36 +110,31 @@ bool constraints::doesMemberRefApplyCurriedSelf(Type baseTy,
110
110
// curried self.
111
111
if (decl->isInstanceMember ()) {
112
112
assert (baseTy);
113
- if (isa<AbstractFunctionDecl>(decl) && baseTy->is <AnyMetatypeType>())
113
+ if (isa<AbstractFunctionDecl>(decl) &&
114
+ baseTy->getRValueType ()->is <AnyMetatypeType>())
114
115
return false ;
115
116
}
116
117
117
118
// Otherwise the reference applies self.
118
119
return true ;
119
120
}
120
121
121
- bool constraints::areConservativelyCompatibleArgumentLabels (
122
- OverloadChoice choice,
123
- ArrayRef<Identifier> labels ,
124
- bool hasTrailingClosure) {
122
+ static bool
123
+ areConservativelyCompatibleArgumentLabels ( OverloadChoice choice,
124
+ ArrayRef<FunctionType::Param> args ,
125
+ bool hasTrailingClosure) {
125
126
ValueDecl *decl = nullptr ;
126
- Type baseType;
127
127
switch (choice.getKind ()) {
128
128
case OverloadChoiceKind::Decl:
129
129
case OverloadChoiceKind::DeclViaBridge:
130
130
case OverloadChoiceKind::DeclViaDynamic:
131
131
case OverloadChoiceKind::DeclViaUnwrappedOptional:
132
132
decl = choice.getDecl ();
133
- baseType = choice.getBaseType ();
134
- if (baseType)
135
- baseType = baseType->getRValueType ();
136
133
break ;
137
134
138
- case OverloadChoiceKind::KeyPathApplication:
139
- // Key path applications are written as if subscript[keyPath:].
140
- return !hasTrailingClosure && labels.size () == 1 && labels[0 ].is (" keyPath" );
141
-
142
135
case OverloadChoiceKind::BaseType:
136
+ // KeyPath application is not filtered in `performMemberLookup`.
137
+ case OverloadChoiceKind::KeyPathApplication:
143
138
case OverloadChoiceKind::DynamicMemberLookup:
144
139
case OverloadChoiceKind::KeyPathDynamicMemberLookup:
145
140
case OverloadChoiceKind::TupleIndex:
@@ -149,17 +144,13 @@ bool constraints::areConservativelyCompatibleArgumentLabels(
149
144
if (!decl->hasParameterList ())
150
145
return true ;
151
146
152
- SmallVector<AnyFunctionType::Param, 8 > argInfos;
153
- for (auto argLabel : labels) {
154
- argInfos.push_back (AnyFunctionType::Param (Type (), argLabel, {}));
155
- }
156
-
157
147
// This is a member lookup, which generally means that the call arguments
158
148
// (if we have any) will apply to the second level of parameters, with
159
149
// the member lookup applying the curried self at the first level. But there
160
150
// are cases where we can get an unapplied declaration reference back.
161
151
auto hasAppliedSelf =
162
- decl->hasCurriedSelf () && doesMemberRefApplyCurriedSelf (baseType, decl);
152
+ decl->hasCurriedSelf () &&
153
+ doesMemberRefApplyCurriedSelf (choice.getBaseType (), decl);
163
154
164
155
auto *fnType = decl->getInterfaceType ()->castTo <AnyFunctionType>();
165
156
if (hasAppliedSelf) {
@@ -173,10 +164,9 @@ bool constraints::areConservativelyCompatibleArgumentLabels(
173
164
MatchCallArgumentListener listener;
174
165
SmallVector<ParamBinding, 8 > unusedParamBindings;
175
166
176
- return !matchCallArguments (argInfos, params, paramInfo,
177
- hasTrailingClosure,
178
- /* allow fixes*/ false ,
179
- listener, unusedParamBindings);
167
+ return !matchCallArguments (args, params, paramInfo, hasTrailingClosure,
168
+ /* allow fixes*/ false , listener,
169
+ unusedParamBindings);
180
170
}
181
171
182
172
Expr *constraints::getArgumentLabelTargetExpr (Expr *fn) {
@@ -873,14 +863,19 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
873
863
874
864
class ArgumentFailureTracker : public MatchCallArgumentListener {
875
865
ConstraintSystem &CS;
866
+ ArrayRef<AnyFunctionType::Param> Arguments;
867
+ ArrayRef<AnyFunctionType::Param> Parameters;
876
868
SmallVectorImpl<ParamBinding> &Bindings;
877
869
ConstraintLocatorBuilder Locator;
878
870
879
871
public:
880
872
ArgumentFailureTracker (ConstraintSystem &cs,
873
+ ArrayRef<AnyFunctionType::Param> args,
874
+ ArrayRef<AnyFunctionType::Param> params,
881
875
SmallVectorImpl<ParamBinding> &bindings,
882
876
ConstraintLocatorBuilder locator)
883
- : CS(cs), Bindings(bindings), Locator(locator) {}
877
+ : CS(cs), Arguments(args), Parameters(params), Bindings(bindings),
878
+ Locator (locator) {}
884
879
885
880
bool missingLabel (unsigned paramIndex) override {
886
881
return !CS.shouldAttemptFixes ();
@@ -912,9 +907,27 @@ class ArgumentFailureTracker : public MatchCallArgumentListener {
912
907
if (!anchor)
913
908
return true ;
914
909
910
+ unsigned numExtraneous = 0 ;
911
+ for (unsigned paramIdx = 0 , n = Bindings.size (); paramIdx != n;
912
+ ++paramIdx) {
913
+ if (Bindings[paramIdx].empty ())
914
+ continue ;
915
+
916
+ const auto paramLabel = Parameters[paramIdx].getLabel ();
917
+ for (auto argIdx : Bindings[paramIdx]) {
918
+ auto argLabel = Arguments[argIdx].getLabel ();
919
+ if (paramLabel.empty () && !argLabel.empty ())
920
+ ++numExtraneous;
921
+ }
922
+ }
923
+
915
924
auto *locator = CS.getConstraintLocator (anchor);
916
925
auto *fix = RelabelArguments::create (CS, newLabels, locator);
917
926
CS.recordFix (fix);
927
+ // Re-labeling fixes with extraneous labels should take
928
+ // lower priority vs. other fixes on same/different
929
+ // overload(s) where labels did line up correctly.
930
+ CS.increaseScore (ScoreKind::SK_Fix, numExtraneous);
918
931
return false ;
919
932
}
920
933
};
@@ -944,7 +957,8 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
944
957
945
958
// Match up the call arguments to the parameters.
946
959
SmallVector<ParamBinding, 4 > parameterBindings;
947
- ArgumentFailureTracker listener (cs, parameterBindings, locator);
960
+ ArgumentFailureTracker listener (cs, argsWithLabels, params, parameterBindings,
961
+ locator);
948
962
if (constraints::matchCallArguments (argsWithLabels, params,
949
963
paramInfo,
950
964
hasTrailingClosure,
@@ -4175,19 +4189,15 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
4175
4189
4176
4190
// If we have a simple name, determine whether there are argument
4177
4191
// labels we can use to restrict the set of lookup results.
4178
- Optional<ArgumentLabelState> argumentLabels;
4179
- if (memberName.isSimpleName ()) {
4180
- argumentLabels = getArgumentLabels (*this ,
4181
- ConstraintLocatorBuilder (memberLocator));
4182
-
4192
+ if (baseObjTy->isAnyObject () && memberName.isSimpleName ()) {
4183
4193
// If we're referencing AnyObject and we have argument labels, put
4184
4194
// the argument labels into the name: we don't want to look for
4185
4195
// anything else, because the cost of the general search is so
4186
4196
// high.
4187
- if (baseObjTy->isAnyObject () && argumentLabels) {
4197
+ if (auto argumentLabels =
4198
+ getArgumentLabels (*this , ConstraintLocatorBuilder (memberLocator))) {
4188
4199
memberName = DeclName (TC.Context , memberName.getBaseName (),
4189
4200
argumentLabels->Labels );
4190
- argumentLabels.reset ();
4191
4201
}
4192
4202
}
4193
4203
@@ -4226,7 +4236,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
4226
4236
bridgedType = classType;
4227
4237
}
4228
4238
}
4229
- bool labelMismatch = false ;
4230
4239
4231
4240
// Local function that adds the given declaration if it is a
4232
4241
// reasonable choice.
@@ -4291,20 +4300,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
4291
4300
hasInstanceMethods = true ;
4292
4301
}
4293
4302
4294
- // If the argument labels for this result are incompatible with
4295
- // the call site, skip it.
4296
- // FIXME: The subscript check here forces the use of the
4297
- // function-application simplification logic to handle labels.
4298
- if (argumentLabels &&
4299
- (!candidate.isDecl () || !isa<SubscriptDecl>(candidate.getDecl ())) &&
4300
- !areConservativelyCompatibleArgumentLabels (
4301
- candidate, argumentLabels->Labels ,
4302
- argumentLabels->HasTrailingClosure )) {
4303
- labelMismatch = true ;
4304
- result.addUnviable (candidate, MemberLookupResult::UR_LabelMismatch);
4305
- return ;
4306
- }
4307
-
4308
4303
// If our base is an existential type, we can't make use of any
4309
4304
// member whose signature involves associated types.
4310
4305
if (instanceTy->isExistentialType ()) {
@@ -4494,8 +4489,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
4494
4489
};
4495
4490
4496
4491
// Add all results from this lookup.
4497
- retry_after_fail:
4498
- labelMismatch = false ;
4499
4492
for (auto result : lookup)
4500
4493
addChoice (getOverloadChoice (result.getValueDecl (),
4501
4494
/* isBridged=*/ false ,
@@ -4603,14 +4596,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
4603
4596
}
4604
4597
}
4605
4598
4606
- // If we rejected some possibilities due to an argument-label
4607
- // mismatch and ended up with nothing, try again ignoring the
4608
- // labels. This allows us to perform typo correction on the labels.
4609
- if (result.ViableCandidates .empty () && labelMismatch && shouldAttemptFixes ()){
4610
- argumentLabels.reset ();
4611
- goto retry_after_fail;
4612
- }
4613
-
4614
4599
// If we have no viable or unviable candidates, and we're generating,
4615
4600
// diagnostics, rerun the query with inaccessible members included, so we can
4616
4601
// include them in the unviable candidates list.
@@ -4855,7 +4840,6 @@ fixMemberRef(ConstraintSystem &cs, Type baseTy,
4855
4840
: nullptr ;
4856
4841
}
4857
4842
4858
- case MemberLookupResult::UR_LabelMismatch:
4859
4843
// TODO(diagnostics): Add a new fix that is suggests to
4860
4844
// add `subscript(dynamicMember: {Writable}KeyPath<T, U>)`
4861
4845
// overload here, that would help if such subscript has
@@ -5882,7 +5866,6 @@ ConstraintSystem::simplifyKeyPathApplicationConstraint(
5882
5866
Type ConstraintSystem::simplifyAppliedOverloads (
5883
5867
TypeVariableType *fnTypeVar,
5884
5868
const FunctionType *argFnType,
5885
- Optional<ArgumentLabelState> argumentLabels,
5886
5869
ConstraintLocatorBuilder locator) {
5887
5870
Type fnType (fnTypeVar);
5888
5871
@@ -5923,6 +5906,8 @@ Type ConstraintSystem::simplifyAppliedOverloads(
5923
5906
return markFailure ();
5924
5907
};
5925
5908
5909
+ auto argumentInfo = getArgumentLabels (*this , locator);
5910
+
5926
5911
// Consider each of the constraints in the disjunction.
5927
5912
retry_after_fail:
5928
5913
bool hasUnhandledConstraints = false ;
@@ -5936,12 +5921,18 @@ Type ConstraintSystem::simplifyAppliedOverloads(
5936
5921
5937
5922
// Determine whether the argument labels we have conflict with those of
5938
5923
// this overload choice.
5939
- if (argumentLabels &&
5940
- !areConservativelyCompatibleArgumentLabels (
5941
- choice, argumentLabels->Labels ,
5942
- argumentLabels->HasTrailingClosure )) {
5943
- labelMismatch = true ;
5944
- return false ;
5924
+ if (argumentInfo) {
5925
+ auto args = argFnType->getParams ();
5926
+
5927
+ SmallVector<FunctionType::Param, 8 > argsWithLabels;
5928
+ argsWithLabels.append (args.begin (), args.end ());
5929
+ FunctionType::relabelParams (argsWithLabels, argumentInfo->Labels );
5930
+
5931
+ if (!areConservativelyCompatibleArgumentLabels (
5932
+ choice, argsWithLabels, argumentInfo->HasTrailingClosure )) {
5933
+ labelMismatch = true ;
5934
+ return false ;
5935
+ }
5945
5936
}
5946
5937
5947
5938
// Determine the type that this choice will have.
@@ -5968,7 +5959,7 @@ Type ConstraintSystem::simplifyAppliedOverloads(
5968
5959
switch (filterResult) {
5969
5960
case SolutionKind::Error:
5970
5961
if (labelMismatch && shouldAttemptFixes ()) {
5971
- argumentLabels = None ;
5962
+ argumentInfo. reset () ;
5972
5963
goto retry_after_fail;
5973
5964
}
5974
5965
@@ -6081,16 +6072,20 @@ ConstraintSystem::simplifyApplicableFnConstraint(
6081
6072
6082
6073
};
6083
6074
6084
- // If the right-hand side is a type variable, try to simplify the overload
6085
- // set.
6086
- if (auto typeVar = desugar2->getAs <TypeVariableType>()) {
6087
- auto argumentLabels = getArgumentLabels (*this , locator);
6088
- Type newType2 =
6089
- simplifyAppliedOverloads (typeVar, func1, argumentLabels, locator);
6090
- if (!newType2)
6091
- return SolutionKind::Error;
6075
+ // Don't attempt this optimization in "diagnostic mode" because
6076
+ // in such mode we'd like to attempt all of the available
6077
+ // overloads regardless of of problems related to missing or
6078
+ // extraneous labels and/or arguments.
6079
+ if (!(solverState && shouldAttemptFixes ())) {
6080
+ // If the right-hand side is a type variable,
6081
+ // try to simplify the overload set.
6082
+ if (auto typeVar = desugar2->getAs <TypeVariableType>()) {
6083
+ Type newType2 = simplifyAppliedOverloads (typeVar, func1, locator);
6084
+ if (!newType2)
6085
+ return SolutionKind::Error;
6092
6086
6093
- desugar2 = newType2->getDesugaredType ();
6087
+ desugar2 = newType2->getDesugaredType ();
6088
+ }
6094
6089
}
6095
6090
6096
6091
// If right-hand side is a type variable, the constraint is unsolved.
0 commit comments