@@ -5775,8 +5775,8 @@ bool FailureDiagnosis::diagnoseClosureExpr(
57755775 // If we have a contextual type available for this closure, apply it to the
57765776 // ParamDecls in our parameter list. This ensures that any uses of them get
57775777 // appropriate types.
5778- if (contextualType && contextualType->is <AnyFunctionType >()) {
5779- auto fnType = contextualType->getAs <AnyFunctionType >();
5778+ if (contextualType && contextualType->is <FunctionType >()) {
5779+ auto fnType = contextualType->getAs <FunctionType >();
57805780 auto *params = CE->getParameters ();
57815781 auto inferredArgs = fnType->getParams ();
57825782
@@ -5791,36 +5791,6 @@ bool FailureDiagnosis::diagnoseClosureExpr(
57915791 unsigned inferredArgCount = inferredArgs.size ();
57925792
57935793 if (actualArgCount != inferredArgCount) {
5794- // If the closure didn't specify any arguments and it is in a context that
5795- // needs some, produce a fixit to turn "{...}" into "{ _,_ in ...}".
5796- if (actualArgCount == 0 && CE->getInLoc ().isInvalid ()) {
5797- auto diag =
5798- diagnose (CE->getStartLoc (), diag::closure_argument_list_missing,
5799- inferredArgCount);
5800- std::string fixText; // Let's provide fixits for up to 10 args.
5801-
5802- if (inferredArgCount <= 10 ) {
5803- fixText += " _" ;
5804- for (unsigned i = 0 ; i < inferredArgCount - 1 ; i ++) {
5805- fixText += " ,_" ;
5806- }
5807- fixText += " in " ;
5808- }
5809-
5810- if (!fixText.empty ()) {
5811- // Determine if there is already a space after the { in the closure to
5812- // make sure we introduce the right whitespace.
5813- auto afterBrace = CE->getStartLoc ().getAdvancedLoc (1 );
5814- auto text = CS.TC .Context .SourceMgr .extractText ({afterBrace, 1 });
5815- if (text.size () == 1 && text == " " )
5816- fixText = fixText.erase (fixText.size () - 1 );
5817- else
5818- fixText = fixText.erase (0 , 1 );
5819- diag.fixItInsertAfter (CE->getStartLoc (), fixText);
5820- }
5821- return true ;
5822- }
5823-
58245794 if (inferredArgCount == 1 && actualArgCount > 1 ) {
58255795 auto *argTupleTy = inferredArgs.front ().getOldType ()->getAs <TupleType>();
58265796 // Let's see if inferred argument is actually a tuple inside of Paren.
@@ -5956,49 +5926,33 @@ bool FailureDiagnosis::diagnoseClosureExpr(
59565926 }
59575927 }
59585928
5959- bool onlyAnonymousParams =
5960- std::all_of (params->begin (), params->end (), [](ParamDecl *param) {
5961- return !param->hasName ();
5962- });
5963-
5964- // Okay, the wrong number of arguments was used, complain about that.
5965- // Before doing so, strip attributes off the function type so that they
5966- // don't confuse the issue.
5967- fnType = FunctionType::get (fnType->getParams (), fnType->getResult (),
5968- fnType->getExtInfo ());
5969- auto diag = diagnose (
5970- params->getStartLoc (), diag::closure_argument_list_tuple, fnType,
5971- inferredArgCount, actualArgCount, (actualArgCount == 1 ));
5972-
5973- // If closure expects no parameters but N was given,
5974- // and all of them are anonymous let's suggest removing them.
5975- if (inferredArgCount == 0 && onlyAnonymousParams) {
5976- auto inLoc = CE->getInLoc ();
5977- auto &sourceMgr = CS.getASTContext ().SourceMgr ;
5978-
5979- if (inLoc.isValid ())
5980- diag.fixItRemoveChars (params->getStartLoc (),
5981- Lexer::getLocForEndOfToken (sourceMgr, inLoc));
5929+ // Extraneous arguments.
5930+ if (inferredArgCount < actualArgCount) {
5931+ auto diag = diagnose (
5932+ params->getStartLoc (), diag::closure_argument_list_tuple, fnType,
5933+ inferredArgCount, actualArgCount, (actualArgCount == 1 ));
5934+
5935+ bool onlyAnonymousParams =
5936+ std::all_of (params->begin (), params->end (),
5937+ [](ParamDecl *param) { return !param->hasName (); });
5938+
5939+ // If closure expects no parameters but N was given,
5940+ // and all of them are anonymous let's suggest removing them.
5941+ if (inferredArgCount == 0 && onlyAnonymousParams) {
5942+ auto inLoc = CE->getInLoc ();
5943+ auto &sourceMgr = CS.getASTContext ().SourceMgr ;
5944+
5945+ if (inLoc.isValid ())
5946+ diag.fixItRemoveChars (params->getStartLoc (),
5947+ Lexer::getLocForEndOfToken (sourceMgr, inLoc));
5948+ }
59825949 return true ;
59835950 }
59845951
5985- // If the number of parameters is less than number of inferred
5986- // and all of the parameters are anonymous, let's suggest a fix-it
5987- // with the rest of the missing parameters.
5988- if (actualArgCount < inferredArgCount) {
5989- SmallString<32 > fixIt;
5990- llvm::raw_svector_ostream OS (fixIt);
5991-
5992- OS << " ," ;
5993- auto numMissing = inferredArgCount - actualArgCount;
5994- for (unsigned i = 0 ; i != numMissing; ++i) {
5995- OS << ((onlyAnonymousParams) ? " _" : " <#arg#>" );
5996- OS << ((i == numMissing - 1 ) ? " " : " ," );
5997- }
5998-
5999- diag.fixItInsertAfter (params->getEndLoc (), OS.str ());
6000- }
6001- return true ;
5952+ MissingArgumentsFailure failure (
5953+ expr, CS, fnType, inferredArgCount - actualArgCount,
5954+ CS.getConstraintLocator (CE, ConstraintLocator::ContextualType));
5955+ return failure.diagnoseAsError ();
60025956 }
60035957
60045958 // Coerce parameter types here only if there are no unresolved
0 commit comments