@@ -745,6 +745,22 @@ static bool getPositionInArgs(DeclContext &DC, Expr *Args, Expr *CCExpr,
745745 return false ;
746746}
747747
748+ // / For function call arguments \p Args, return the argument at \p Position
749+ // / computed by \c getPositionInArgs
750+ static Expr *getArgAtPosition (Expr *Args, unsigned Position) {
751+ if (isa<ParenExpr>(Args)) {
752+ assert (Position == 0 );
753+ return Args;
754+ }
755+
756+ if (auto *tuple = dyn_cast<TupleExpr>(Args)) {
757+ return tuple->getElement (Position);
758+ } else {
759+ llvm_unreachable (" Unable to retrieve arg at position returned by "
760+ " getPositionInArgs?" );
761+ }
762+ }
763+
748764// / Get index of \p CCExpr in \p Params. Note that the position in \p Params may
749765// / be different than the position in \p Args if there are defaulted arguments
750766// / in \p Params which don't occur in \p Args.
@@ -848,15 +864,15 @@ class ExprContextAnalyzer {
848864 bool analyzeApplyExpr (Expr *E) {
849865 // Collect parameter lists for possible func decls.
850866 SmallVector<FunctionTypeAndDecl, 2 > Candidates;
851- Expr *Arg = nullptr ;
867+ Expr *Args = nullptr ;
852868 if (auto *applyExpr = dyn_cast<ApplyExpr>(E)) {
853869 if (!collectPossibleCalleesForApply (*DC, applyExpr, Candidates))
854870 return false ;
855- Arg = applyExpr->getArg ();
871+ Args = applyExpr->getArg ();
856872 } else if (auto *subscriptExpr = dyn_cast<SubscriptExpr>(E)) {
857873 if (!collectPossibleCalleesForSubscript (*DC, subscriptExpr, Candidates))
858874 return false ;
859- Arg = subscriptExpr->getIndex ();
875+ Args = subscriptExpr->getIndex ();
860876 } else {
861877 llvm_unreachable (" unexpected expression kind" );
862878 }
@@ -866,14 +882,43 @@ class ExprContextAnalyzer {
866882 // Determine the position of code completion token in call argument.
867883 unsigned PositionInArgs;
868884 bool HasName;
869- if (!getPositionInArgs (*DC, Arg , ParsedExpr, PositionInArgs, HasName))
885+ if (!getPositionInArgs (*DC, Args , ParsedExpr, PositionInArgs, HasName))
870886 return false ;
871887
872888 // Collect possible types (or labels) at the position.
873889 {
874- bool MayNeedName = !HasName && !E->isImplicit () &&
875- (isa<CallExpr>(E) | isa<SubscriptExpr>(E) ||
876- isa<UnresolvedMemberExpr>(E));
890+ bool MayBeArgForLabeledParam =
891+ HasName || E->isImplicit () ||
892+ (!isa<CallExpr>(E) && !isa<SubscriptExpr>(E) &&
893+ !isa<UnresolvedMemberExpr>(E));
894+
895+ // If the completion position cannot be the actual argument, it must be
896+ // able to be an argument label.
897+ bool MayBeLabel = !MayBeArgForLabeledParam;
898+
899+ // Alternatively, the code completion position may complete to an argument
900+ // label if we are currently completing variadic args.
901+ // E.g.
902+ // func foo(x: Int..., y: Int...) {}
903+ // foo(x: 1, #^COMPLETE^#)
904+ // #^COMPLETE^# may complete to either an additional variadic arg or to
905+ // the argument label `y`.
906+ //
907+ // Varargs are represented by a VarargExpansionExpr that contains an
908+ // ArrayExpr on the call side.
909+ if (auto Vararg = dyn_cast<VarargExpansionExpr>(
910+ getArgAtPosition (Args, PositionInArgs))) {
911+ if (auto Array = dyn_cast_or_null<ArrayExpr>(Vararg->getSubExpr ())) {
912+ if (Array->getNumElements () > 0 &&
913+ !isa<CodeCompletionExpr>(Array->getElement (0 ))) {
914+ // We can only complete as argument label if we have at least one
915+ // proper vararg before the code completion token. We shouldn't be
916+ // suggesting labels for:
917+ // foo(x: #^COMPLETE^#)
918+ MayBeLabel = true ;
919+ }
920+ }
921+ }
877922 SmallPtrSet<CanType, 4 > seenTypes;
878923 llvm::SmallSet<std::pair<Identifier, CanType>, 4 > seenArgs;
879924 for (auto &typeAndDecl : Candidates) {
@@ -883,7 +928,7 @@ class ExprContextAnalyzer {
883928
884929 auto Params = typeAndDecl.Type ->getParams ();
885930 unsigned PositionInParams;
886- if (!getPositionInParams (*DC, Arg , ParsedExpr, Params,
931+ if (!getPositionInParams (*DC, Args , ParsedExpr, Params,
887932 PositionInParams)) {
888933 // If the argument doesn't have a matching position in the parameters,
889934 // indicate that with optional nullptr param.
@@ -907,11 +952,13 @@ class ExprContextAnalyzer {
907952 paramList && (paramList->get (Pos)->isDefaultArgument () ||
908953 paramList->get (Pos)->isVariadic ());
909954
910- if (paramType.hasLabel () && MayNeedName ) {
955+ if (MayBeLabel && paramType.hasLabel ()) {
911956 if (seenArgs.insert ({paramType.getLabel (), ty->getCanonicalType ()})
912957 .second )
913958 recordPossibleParam (¶mType, !canSkip);
914- } else {
959+ }
960+
961+ if (MayBeArgForLabeledParam || !paramType.hasLabel ()) {
915962 auto argTy = ty;
916963 if (paramType.isInOut ())
917964 argTy = InOutType::get (argTy);
0 commit comments