@@ -771,22 +771,22 @@ static Expr *getArgAtPosition(Expr *Args, unsigned Position) {
771
771
// / be different than the position in \p Args if there are defaulted arguments
772
772
// / in \p Params which don't occur in \p Args.
773
773
// /
774
- // / \returns \c true if success, \c false if \p CCExpr is not a part of \p Args.
775
- static bool getPositionInParams (DeclContext &DC, Expr *Args, Expr *CCExpr,
776
- ArrayRef<AnyFunctionType::Param> Params,
777
- unsigned &PosInParams) {
774
+ // / \returns the position index number on success, \c None if \p CCExpr is not
775
+ // / a part of \p Args.
776
+ static Optional<unsigned >
777
+ getPositionInParams (DeclContext &DC, Expr *Args, Expr *CCExpr,
778
+ ArrayRef<AnyFunctionType::Param> Params, bool Lenient) {
778
779
if (isa<ParenExpr>(Args)) {
779
- PosInParams = 0 ;
780
- return true ;
780
+ return 0 ;
781
781
}
782
782
783
783
auto *tuple = dyn_cast<TupleExpr>(Args);
784
784
if (!tuple) {
785
- return false ;
785
+ return None ;
786
786
}
787
787
788
788
auto &SM = DC.getASTContext ().SourceMgr ;
789
- PosInParams = 0 ;
789
+ unsigned PosInParams = 0 ;
790
790
unsigned PosInArgs = 0 ;
791
791
bool LastParamWasVariadic = false ;
792
792
// We advance PosInArgs until we find argument that is after the code
@@ -847,16 +847,22 @@ static bool getPositionInParams(DeclContext &DC, Expr *Args, Expr *CCExpr,
847
847
}
848
848
849
849
if (!AdvancedPosInParams) {
850
- // If there is no matching argument label. These arguments can't be
851
- // applied to the params.
852
- return false ;
850
+ if (Lenient) {
851
+ // We haven't performed any special advance logic. Assume the argument
852
+ // and parameter match, so advance PosInParams by 1.
853
+ PosInParams += 1 ;
854
+ } else {
855
+ // If there is no matching argument label. These arguments can't be
856
+ // applied to the params.
857
+ return None;
858
+ }
853
859
}
854
860
}
855
861
if (PosInArgs < tuple->getNumElements () && PosInParams < Params.size ()) {
856
862
// We didn't search until the end, so we found a position in Params. Success
857
- return true ;
863
+ return PosInParams ;
858
864
} else {
859
- return false ;
865
+ return None ;
860
866
}
861
867
}
862
868
@@ -947,21 +953,45 @@ class ExprContextAnalyzer {
947
953
}
948
954
SmallPtrSet<CanType, 4 > seenTypes;
949
955
llvm::SmallSet<std::pair<Identifier, CanType>, 4 > seenArgs;
950
- for (auto &typeAndDecl : Candidates) {
951
- DeclContext *memberDC = nullptr ;
952
- if (typeAndDecl.Decl )
953
- memberDC = typeAndDecl.Decl ->getInnermostDeclContext ();
956
+ llvm::SmallVector<Optional<unsigned >, 2 > posInParams;
957
+ {
958
+ bool found = false ;
959
+ for (auto &typeAndDecl : Candidates) {
960
+ Optional<unsigned > pos = getPositionInParams (
961
+ *DC, Args, ParsedExpr, typeAndDecl.Type ->getParams (),
962
+ /* lenient=*/ false );
963
+ posInParams.push_back (pos);
964
+ found |= pos.hasValue ();
965
+ }
966
+ if (!found) {
967
+ // If applicable overload is not found, retry with considering
968
+ // non-matching argument labels mis-typed.
969
+ for (auto i : indices (Candidates)) {
970
+ posInParams[i] = getPositionInParams (
971
+ *DC, Args, ParsedExpr, Candidates[i].Type ->getParams (),
972
+ /* lenient=*/ true );
973
+ }
974
+ }
975
+ }
976
+ assert (posInParams.size () == Candidates.size ());
954
977
955
- auto Params = typeAndDecl.Type ->getParams ();
956
- unsigned PositionInParams;
957
- if (!getPositionInParams (*DC, Args, ParsedExpr, Params,
958
- PositionInParams)) {
978
+ for (auto i : indices (Candidates)) {
979
+ if (!posInParams[i].hasValue ()) {
959
980
// If the argument doesn't have a matching position in the parameters,
960
981
// indicate that with optional nullptr param.
961
982
if (seenArgs.insert ({Identifier (), CanType ()}).second )
962
983
recordPossibleParam (nullptr , /* isRequired=*/ false );
963
984
continue ;
964
985
}
986
+
987
+ auto &typeAndDecl = Candidates[i];
988
+ DeclContext *memberDC = nullptr ;
989
+ if (typeAndDecl.Decl )
990
+ memberDC = typeAndDecl.Decl ->getInnermostDeclContext ();
991
+
992
+ auto Params = typeAndDecl.Type ->getParams ();
993
+ auto PositionInParams = *posInParams[i];
994
+
965
995
ParameterList *paramList = nullptr ;
966
996
if (auto VD = typeAndDecl.Decl ) {
967
997
paramList = getParameterList (VD);
0 commit comments