diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 6cacdd41d8a97..06cd4fd158a57 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -5514,11 +5514,10 @@ Expr *ExprRewriter::coerceCallArguments(Expr *arg, AnyFunctionType *funcType, MatchCallArgumentListener listener; SmallVector parameterBindings; - bool failed = constraints::matchCallArguments(args, params, - paramInfo, - arg->getUnlabeledTrailingClosureIndexOfPackedArgument(), - /*allowFixes=*/false, listener, - parameterBindings); + bool failed = constraints::matchCallArguments( + args, params, paramInfo, + arg->getUnlabeledTrailingClosureIndexOfPackedArgument(), listener, + parameterBindings); assert((matchCanFail || !failed) && "Call arguments did not match up?"); (void)failed; diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 51bc765d50ed6..a77f1cf9bf123 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -168,8 +168,7 @@ static bool areConservativelyCompatibleArgumentLabels( SmallVector unusedParamBindings; return !matchCallArguments(args, params, paramInfo, - unlabeledTrailingClosureArgIndex, - /*allow fixes*/ false, listener, + unlabeledTrailingClosureArgIndex, listener, unusedParamBindings); } @@ -221,7 +220,6 @@ matchCallArguments(SmallVectorImpl &args, ArrayRef params, const ParameterListInfo ¶mInfo, Optional unlabeledTrailingClosureArgIndex, - bool allowFixes, MatchCallArgumentListener &listener, SmallVectorImpl ¶meterBindings) { assert(params.size() == paramInfo.size() && "Default map does not match"); @@ -238,11 +236,6 @@ matchCallArguments(SmallVectorImpl &args, unsigned numArgs = args.size(); SmallVector claimedArgs(numArgs, false); SmallVector actualArgNames; - unsigned numClaimedArgs = 0; - - // Indicates whether any of the arguments are potentially out-of-order, - // requiring further checking at the end. - bool potentiallyOutOfOrder = false; // Local function that claims the argument at \c argNumber, returning the // index of the claimed argument. This is primarily a helper for @@ -276,161 +269,36 @@ matchCallArguments(SmallVectorImpl &args, } claimedArgs[argNumber] = true; - ++numClaimedArgs; return argNumber; }; - // Local function that skips over any claimed arguments. - auto skipClaimedArgs = [&](unsigned &nextArgIdx) { - while (nextArgIdx != numArgs && claimedArgs[nextArgIdx]) - ++nextArgIdx; - }; - - // Local function that retrieves the next unclaimed argument with the given - // name (which may be empty). This routine claims the argument. - auto claimNextNamed = [&](unsigned &nextArgIdx, Identifier paramLabel, - bool ignoreNameMismatch, - bool forVariadic = false) -> Optional { - // Skip over any claimed arguments. - skipClaimedArgs(nextArgIdx); - - // If we've claimed all of the arguments, there's nothing more to do. - if (numClaimedArgs == numArgs) - return None; - - // Go hunting for an unclaimed argument whose name does match. - Optional claimedWithSameName; - for (unsigned i = nextArgIdx; i != numArgs; ++i) { - auto argLabel = args[i].getLabel(); - - if (argLabel != paramLabel) { - // If this is an attempt to claim additional unlabeled arguments - // for variadic parameter, we have to stop at first labeled argument. - if (forVariadic) - return None; - - // Otherwise we can continue trying to find argument which - // matches parameter with or without label. - continue; - } - - // Skip claimed arguments. - if (claimedArgs[i]) { - assert(!forVariadic && "Cannot be for a variadic claim"); - // Note that we have already claimed an argument with the same name. - if (!claimedWithSameName) - claimedWithSameName = i; - continue; - } - - // We found a match. If the match wasn't the next one, we have - // potentially out of order arguments. - if (i != nextArgIdx) { - assert(!forVariadic && "Cannot be for a variadic claim"); - // Avoid claiming un-labeled defaulted parameters - // by out-of-order un-labeled arguments or parts - // of variadic argument sequence, because that might - // be incorrect: - // ```swift - // func foo(_ a: Int, _ b: Int = 0, c: Int = 0, _ d: Int) {} - // foo(1, c: 2, 3) // -> `3` will be claimed as '_ b:'. - // ``` - if (argLabel.empty()) - continue; - - potentiallyOutOfOrder = true; - } - - // Claim it. - return claim(paramLabel, i); - } - - // If we're not supposed to attempt any fixes, we're done. - if (!allowFixes) - return None; - - // Several things could have gone wrong here, and we'll check for each - // of them at some point: - // - The keyword argument might be redundant, in which case we can point - // out the issue. - // - The argument might be unnamed, in which case we try to fix the - // problem by adding the name. - // - The argument might have extraneous label, in which case we try to - // fix the problem by removing such label. - // - The keyword argument might be a typo for an actual argument name, in - // which case we should find the closest match to correct to. - - // Missing or extraneous label. - if (nextArgIdx != numArgs && ignoreNameMismatch) { - auto argLabel = args[nextArgIdx].getLabel(); - // Claim this argument if we are asked to ignore labeling failure, - // only if argument doesn't have a label when parameter expected - // it to, or vice versa. - if (paramLabel.empty() || argLabel.empty()) - return claim(paramLabel, nextArgIdx); - } - - // Redundant keyword arguments. - if (claimedWithSameName) { - // FIXME: We can provide better diagnostics here. - return None; - } - - // Typo correction is handled in a later pass. - return None; - }; - // Local function that attempts to bind the given parameter to arguments in // the list. - bool haveUnfulfilledParams = false; - auto bindNextParameter = [&](unsigned paramIdx, unsigned &nextArgIdx, - bool ignoreNameMismatch) { + // `ignoreNameMismatch` indicates whether it allows match labeled and + // unlabeled. It claims multiple arguments if parameter is variadic. + auto bindParameter = [&](unsigned paramIdx, unsigned argIdx) { const auto ¶m = params[paramIdx]; - // Handle variadic parameters. - if (param.isVariadic()) { - // Claim the next argument with the name of this parameter. - auto claimed = - claimNextNamed(nextArgIdx, param.getLabel(), ignoreNameMismatch); - - // If there was no such argument, leave the parameter unfulfilled. - if (!claimed) { - haveUnfulfilledParams = true; - return; - } - - // Record the first argument for the variadic. - parameterBindings[paramIdx].push_back(*claimed); - - // If the argument is itself variadic, we're forwarding varargs - // with a VarargExpansionExpr; don't collect any more arguments. - if (args[*claimed].isVariadic()) { - return; - } + claim(param.getLabel(), argIdx); + parameterBindings[paramIdx].push_back(argIdx); + argIdx++; - auto currentNextArgIdx = nextArgIdx; - { - nextArgIdx = *claimed; - // Claim any additional unnamed arguments. - while ( - (claimed = claimNextNamed(nextArgIdx, Identifier(), false, true))) { - parameterBindings[paramIdx].push_back(*claimed); + // Claim variadic tails + if (param.isVariadic()) { + for (; argIdx < args.size(); argIdx++) { + if (claimedArgs[argIdx]) { + break; } - } - nextArgIdx = currentNextArgIdx; - return; - } + const auto &arg = args[argIdx]; + if (!arg.getLabel().empty()) { + break; + } - // Try to claim an argument for this parameter. - if (auto claimed = - claimNextNamed(nextArgIdx, param.getLabel(), ignoreNameMismatch)) { - parameterBindings[paramIdx].push_back(*claimed); - return; + claim(/*expectedName=*/Identifier(), argIdx); + parameterBindings[paramIdx].push_back(argIdx); + } } - - // There was no argument to claim. Leave the argument unfulfilled. - haveUnfulfilledParams = true; }; // If we have an unlabeled trailing closure, we match trailing closure @@ -538,7 +406,8 @@ matchCallArguments(SmallVectorImpl &args, if (isExtraClosure) { // Claim the unlabeled trailing closure without an associated // parameter to suppress further complaints about it. - claim(Identifier(), unlabeledArgIdx, /*ignoreNameClash=*/true); + claim(/*expectedName=*/Identifier(), unlabeledArgIdx, + /*ignoreNameClash=*/true); } else { unlabeledParamIdx = prevParamIdx - 1; } @@ -552,20 +421,35 @@ matchCallArguments(SmallVectorImpl &args, } } - { - unsigned nextArgIdx = 0; - // Mark through the parameters, binding them to their arguments. - for (auto paramIdx : indices(params)) { - if (parameterBindings[paramIdx].empty()) - bindNextParameter(paramIdx, nextArgIdx, false); + // Step 1: Bind labeled parameters. + + for (unsigned paramIdx : indices(params)) { + if (!parameterBindings[paramIdx].empty()) { + continue; + } + const auto ¶m = params[paramIdx]; + if (param.getLabel().empty()) { + continue; + } + + for (unsigned argIdx : indices(args)) { + if (claimedArgs[argIdx]) { + continue; + } + const auto &arg = args[argIdx]; + if (param.getLabel() == arg.getLabel()) { + bindParameter(paramIdx, argIdx); + break; + } } } - // If we have any unclaimed arguments, complain about those. - if (numClaimedArgs != numArgs) { + // Step 2: Bind labeled parameters with typo correction. + + { // Find all of the named, unclaimed arguments. llvm::SmallVector unclaimedNamedArgs; - for (auto argIdx : indices(args)) { + for (unsigned argIdx : indices(args)) { if (claimedArgs[argIdx]) continue; if (!args[argIdx].getLabel().empty()) unclaimedNamedArgs.push_back(argIdx); @@ -574,12 +458,9 @@ matchCallArguments(SmallVectorImpl &args, if (!unclaimedNamedArgs.empty()) { // Find all of the named, unfulfilled parameters. llvm::SmallVector unfulfilledNamedParams; - bool hasUnfulfilledUnnamedParams = false; for (auto paramIdx : indices(params)) { if (parameterBindings[paramIdx].empty()) { - if (params[paramIdx].getLabel().empty()) - hasUnfulfilledUnnamedParams = true; - else + if (!params[paramIdx].getLabel().empty()) unfulfilledNamedParams.push_back(paramIdx); } } @@ -612,9 +493,8 @@ matchCallArguments(SmallVectorImpl &args, if (bestScore > 0) { // Bind this parameter to the argument. auto paramIdx = unfulfilledNamedParams[best]; - auto paramLabel = params[paramIdx].getLabel(); - parameterBindings[paramIdx].push_back(claim(paramLabel, argIdx)); + bindParameter(paramIdx, argIdx); // Erase this parameter from the list of unfulfilled named // parameters, so we don't try to fulfill it again. @@ -623,98 +503,220 @@ matchCallArguments(SmallVectorImpl &args, break; } } - - // Update haveUnfulfilledParams, because we may have fulfilled some - // parameters above. - haveUnfulfilledParams = hasUnfulfilledUnnamedParams || - !unfulfilledNamedParams.empty(); } } + } - // Find all of the unfulfilled parameters, and match them up - // semi-positionally. - if (numClaimedArgs != numArgs) { - // Restart at the first argument/parameter. - unsigned nextArgIdx = 0; - haveUnfulfilledParams = false; - for (auto paramIdx : indices(params)) { - // Skip fulfilled parameters. - if (!parameterBindings[paramIdx].empty()) + auto bindUnlabeledParameters = [&](unsigned startParamIdx, + unsigned endParamIdx, unsigned startArgIdx, + unsigned endArgIdx) { + while (true) { + SmallVector unclaimedUnlabeledParamIdxs; + unsigned numUnclaimedLabeledParamAtLeft = 0; + SmallVector unclaimedUnlabeledArgIdxs; + unsigned numUnclaimedLabeledArgAtLeft = 0; + + for (unsigned paramIdx = startParamIdx; paramIdx < endParamIdx; + paramIdx++) { + if (!parameterBindings[paramIdx].empty()) { continue; + } - bindNextParameter(paramIdx, nextArgIdx, true); + const auto ¶m = params[paramIdx]; + if (param.getLabel().empty()) { + unclaimedUnlabeledParamIdxs.push_back(paramIdx); + } else { + if (unclaimedUnlabeledParamIdxs.empty() && !param.isVariadic() && + !paramInfo.hasDefaultArgument(paramIdx)) { + numUnclaimedLabeledParamAtLeft++; + } + } } - } - // If there are as many arguments as parameters but we still - // haven't claimed all of the arguments, it could mean that - // labels don't line up, if so let's try to claim arguments - // with incorrect labels, and let OoO/re-labeling logic diagnose that. - if (numArgs == numParams && numClaimedArgs != numArgs) { - for (auto i : indices(args)) { - if (claimedArgs[i] || !parameterBindings[i].empty()) + for (unsigned argIdx = startArgIdx; argIdx < endArgIdx; argIdx++) { + if (claimedArgs[argIdx]) { continue; + } - // If parameter has a default value, we don't really - // now if label doesn't match because it's incorrect - // or argument belongs to some other parameter, so - // we just leave this parameter unfulfilled. - if (paramInfo.hasDefaultArgument(i)) - continue; + const auto &arg = args[argIdx]; + if (arg.getLabel().empty()) { + unclaimedUnlabeledArgIdxs.push_back(argIdx); + } else { + if (unclaimedUnlabeledArgIdxs.empty()) { + numUnclaimedLabeledArgAtLeft++; + } + } + } + + if (unclaimedUnlabeledParamIdxs.empty() || + unclaimedUnlabeledArgIdxs.empty()) { + break; + } - // Looks like there was no parameter claimed at the same - // position, it could only mean that label is completely - // different, because typo correction has been attempted already. - parameterBindings[i].push_back(claim(params[i].getLabel(), i)); + if (unclaimedUnlabeledParamIdxs.size() <= + unclaimedUnlabeledArgIdxs.size()) { + unsigned maxSkip = unclaimedUnlabeledArgIdxs.size() - + unclaimedUnlabeledParamIdxs.size(); + unsigned skip = std::min(maxSkip, numUnclaimedLabeledParamAtLeft); + bindParameter(unclaimedUnlabeledParamIdxs.front(), + unclaimedUnlabeledArgIdxs[skip]); + } else { + unsigned maxSkip = unclaimedUnlabeledParamIdxs.size() - + unclaimedUnlabeledArgIdxs.size(); + unsigned skip = std::min(maxSkip, numUnclaimedLabeledArgAtLeft); + bindParameter(unclaimedUnlabeledParamIdxs[skip], + unclaimedUnlabeledArgIdxs.front()); } } + }; - // If we still haven't claimed all of the arguments, - // fail if there is no recovery. - if (numClaimedArgs != numArgs) { - for (auto index : indices(claimedArgs)) { - if (claimedArgs[index]) - continue; + auto bindParametersPositionally = + [&](unsigned startParamIdx, unsigned endParamIdx, unsigned startArgIdx, + unsigned endArgIdx, bool ignoreLabel) { + for (unsigned paramIdx = startParamIdx; paramIdx < endParamIdx; + paramIdx++) { + if (!parameterBindings[paramIdx].empty()) { + continue; + } + const auto ¶m = params[paramIdx]; - if (listener.extraArgument(index)) - return true; - } + for (unsigned argIdx = startArgIdx; argIdx < endArgIdx; argIdx++) { + if (claimedArgs[argIdx]) { + continue; + } + const auto &arg = args[argIdx]; + + if (ignoreLabel || param.getLabel() == arg.getLabel() || + param.getLabel().empty() || arg.getLabel().empty()) { + bindParameter(paramIdx, argIdx); + break; + } + } + } + }; + + auto iterateGroups = + [&](const std::function + &f) { + unsigned startParamIdx = 0; + unsigned startArgIdx = 0; + + while (true) { + if (startParamIdx >= params.size()) { + break; + } + + unsigned endParamIdx = params.size(); + unsigned nextStartParamIdx = endParamIdx; + unsigned nextStartArgIdx = args.size(); + for (unsigned paramIdx = startParamIdx; paramIdx < params.size(); + paramIdx++) { + if (!parameterBindings[paramIdx].empty()) { + endParamIdx = paramIdx; + nextStartParamIdx = paramIdx + 1; + nextStartArgIdx = parameterBindings[paramIdx].back() + 1; + break; + } + } + + unsigned endArgIdx = args.size(); + for (unsigned argIdx = startArgIdx; argIdx < args.size(); argIdx++) { + if (claimedArgs[argIdx]) { + endArgIdx = argIdx; + break; + } + } + + f(startParamIdx, endParamIdx, startArgIdx, endArgIdx); + + startParamIdx = nextStartParamIdx; + startArgIdx = nextStartArgIdx; + } + }; + + // Step 3: Bind unlabeled parameters in group. + + iterateGroups([&](unsigned startParamIdx, unsigned endParamIdx, + unsigned startArgIdx, unsigned endArgIdx) { + bindUnlabeledParameters(startParamIdx, endParamIdx, startArgIdx, endArgIdx); + bindParametersPositionally(startParamIdx, endParamIdx, startArgIdx, + endArgIdx, + /*ignoreLabel=*/false); + }); + + // Step 4: Bind remaining parameters forcibly. + + iterateGroups([&](unsigned startParamIdx, unsigned endParamIdx, + unsigned startArgIdx, unsigned endArgIdx) { + bindParametersPositionally(startParamIdx, endParamIdx, startArgIdx, + endArgIdx, + /*ignoreLabel=*/true); + }); + + // Step 5: Report remaining arguments as extraneous. + + for (unsigned argIdx : indices(args)) { + if (claimedArgs[argIdx]) { + continue; } - // FIXME: If we had the actual parameters and knew the body names, those - // matches would be best. - potentiallyOutOfOrder = true; - } + if (unlabeledTrailingClosureArgIndex && + *unlabeledTrailingClosureArgIndex <= argIdx) { + // extra trailing closures are already reported above. + continue; + } - // If we have any unfulfilled parameters, check them now. - if (haveUnfulfilledParams) { - for (auto paramIdx : indices(params)) { - // If we have a binding for this parameter, we're done. - if (!parameterBindings[paramIdx].empty()) - continue; + if (listener.extraArgument(argIdx)) { + return true; + } + } - const auto ¶m = params[paramIdx]; + // Step 6: Report remaining parameters as missing argument. - // Variadic parameters can be unfulfilled. - if (param.isVariadic()) - continue; + for (unsigned paramIdx : indices(params)) { + if (!parameterBindings[paramIdx].empty()) { + continue; + } - // Parameters with defaults can be unfulfilled. - if (paramInfo.hasDefaultArgument(paramIdx)) - continue; + const auto ¶m = params[paramIdx]; - if (auto newArgIdx = listener.missingArgument(paramIdx)) { - parameterBindings[paramIdx].push_back(*newArgIdx); - continue; - } + if (param.isVariadic() || paramInfo.hasDefaultArgument(paramIdx)) { + continue; + } + if (auto newArgIdx = listener.missingArgument(paramIdx)) { + parameterBindings[paramIdx].push_back(*newArgIdx); + } else { return true; } } - // If any arguments were provided out-of-order, check whether we have - // violated any of the reordering rules. + // Step 7: Report label errors + + bool potentiallyOutOfOrder = false; + Optional prevArgIdx; + for (unsigned paramIdx : indices(params)) { + if (parameterBindings[paramIdx].empty()) { + continue; + } + + const unsigned argIdx = parameterBindings[paramIdx].front(); + if (numArgs <= argIdx) { + // missing argument + continue; + } + + if (prevArgIdx && argIdx <= *prevArgIdx) { + potentiallyOutOfOrder = true; + break; + } + prevArgIdx = argIdx; + } + if (potentiallyOutOfOrder) { + // If any arguments were provided out-of-order, check whether we have + // violated any of the reordering rules. + // If we've seen label failures and now there is an out-of-order // parameter (or even worse - OoO parameter with label re-naming), // we most likely have no idea what would be the best @@ -783,6 +785,12 @@ matchCallArguments(SmallVectorImpl &args, continue; } + // Allow label mismatch for unlabeled trailing closure. + if (unlabeledTrailingClosureArgIndex && + *unlabeledTrailingClosureArgIndex == fromArgIdx) { + continue; + } + // First let's double check if out-of-order argument is nothing // more than a simple label mismatch, because in situation where // one argument requires label and another one doesn't, but caller @@ -1105,10 +1113,9 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments( { ArgumentFailureTracker listener(cs, argsWithLabels, params, parameterBindings, locator); - if (constraints::matchCallArguments( - argsWithLabels, params, paramInfo, - argInfo->UnlabeledTrailingClosureIndex, - cs.shouldAttemptFixes(), listener, parameterBindings)) + if (constraints::matchCallArguments(argsWithLabels, params, paramInfo, + argInfo->UnlabeledTrailingClosureIndex, + listener, parameterBindings)) return cs.getTypeMatchFailure(locator); auto extraArguments = listener.getExtraneousArguments(); diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h index 28b68e4779354..ec24af4c3bdf6 100644 --- a/lib/Sema/ConstraintSystem.h +++ b/lib/Sema/ConstraintSystem.h @@ -4924,7 +4924,6 @@ class MatchCallArgumentListener { /// \param paramInfo Declaration-level information about the parameters. /// \param unlabeledTrailingClosureIndex The index of an unlabeled trailing closure, /// if any. -/// \param allowFixes Whether to allow fixes when matching arguments. /// /// \param listener Listener that will be notified when certain problems occur, /// e.g., to produce a diagnostic. @@ -4936,7 +4935,6 @@ bool matchCallArguments(SmallVectorImpl &args, ArrayRef params, const ParameterListInfo ¶mInfo, Optional unlabeledTrailingClosureIndex, - bool allowFixes, MatchCallArgumentListener &listener, SmallVectorImpl ¶meterBindings); diff --git a/test/Constraints/argument_matching.swift b/test/Constraints/argument_matching.swift index febabc64f094d..173ea070369f7 100644 --- a/test/Constraints/argument_matching.swift +++ b/test/Constraints/argument_matching.swift @@ -71,7 +71,9 @@ secondArgumentNotLabeled(10, 20) // expected-error@-1 {{missing argument label 'a:' in call}} func f_31849281(x: Int, y: Int, z: Int) {} -f_31849281(42, y: 10, x: 20) // expected-error {{incorrect argument labels in call (have '_:y:x:', expected 'x:y:z:')}} {{12-12=x: }} {{23-24=z}} +// expected-note@-1 {{'f_31849281(x:y:z:)' declared here}} +f_31849281(42, y: 10, x: 20) // expected-error {{extra argument in call}} +// expected-error@-1 {{missing argument for parameter 'z' in call}} // ------------------------------------------- // Extraneous keywords @@ -84,31 +86,40 @@ nokeywords1(x: 1, y: 1) // expected-error{{extraneous argument labels 'x:y:' in // Some missing, some extraneous keywords // ------------------------------------------- func somekeywords1(_ x: Int, y: Int, z: Int) { } +// expected-note@-1 {{'somekeywords1(_:y:z:)' declared here}} somekeywords1(x: 1, y: 2, z: 3) // expected-error{{extraneous argument label 'x:' in call}}{{15-18=}} somekeywords1(1, 2, 3) // expected-error{{missing argument labels 'y:z:' in call}}{{18-18=y: }}{{21-21=z: }} -somekeywords1(x: 1, 2, z: 3) // expected-error{{incorrect argument labels in call (have 'x:_:z:', expected '_:y:z:')}}{{15-18=}}{{21-21=y: }} +somekeywords1(x: 1, 2, z: 3) // expected-error{{extra argument in call}} +// expected-error@-1 {{missing argument for parameter #1 in call}} // SR-2242: poor diagnostic when argument label is omitted func r27212391(x: Int, _ y: Int) { + // expected-note@-1 2 {{'r27212391(x:_:)' declared here}} let _: Int = x + y } func r27212391(a: Int, x: Int, _ y: Int) { + // expected-note@-1 3 {{'r27212391(a:x:_:)' declared here}} let _: Int = a + x + y } r27212391(3, 5) // expected-error {{missing argument label 'x:' in call}} -r27212391(3, y: 5) // expected-error {{incorrect argument labels in call (have '_:y:', expected 'x:_:')}} -r27212391(3, x: 5) // expected-error {{argument 'x' must precede unnamed argument #1}} {{11-11=x: 5, }} {{12-18=}} -r27212391(y: 3, x: 5) // expected-error {{incorrect argument labels in call (have 'y:x:', expected 'x:_:')}} {{11-12=x}} {{17-20=}} +r27212391(3, y: 5) // expected-error {{extra argument in call}} +// expected-error@-1 {{missing argument for parameter #2 in call}} +r27212391(3, x: 5) // expected-error {{missing argument label 'a:' in call}} {{11-11=a: }} +// expected-error@-1 {{missing argument for parameter #3 in call}} +r27212391(y: 3, x: 5) // expected-error {{extra argument 'y' in call}} +// expected-error@-1 {{missing argument for parameter #2 in call}} r27212391(y: 3, 5) // expected-error {{incorrect argument label in call (have 'y:_:', expected 'x:_:')}} r27212391(x: 3, x: 5) // expected-error {{extraneous argument label 'x:' in call}} -r27212391(a: 1, 3, y: 5) // expected-error {{incorrect argument labels in call (have 'a:_:y:', expected 'a:x:_:')}} -r27212391(1, x: 3, y: 5) // expected-error {{incorrect argument labels in call (have '_:x:y:', expected 'a:x:_:')}} -r27212391(a: 1, y: 3, x: 5) // expected-error {{incorrect argument labels in call (have 'a:y:x:', expected 'a:x:_:')}} -r27212391(a: 1, 3, x: 5) // expected-error {{argument 'x' must precede unnamed argument #2}} {{17-17=x: 5, }} {{18-24=}} +r27212391(a: 1, 3, y: 5) // expected-error {{extra argument 'y' in call}} +r27212391(1, x: 3, y: 5) // expected-error {{extra argument in call}} +r27212391(a: 1, y: 3, x: 5) // expected-error {{extra argument 'y' in call}} +// expected-error@-1 {{missing argument for parameter #3 in call}} +r27212391(a: 1, 3, x: 5) // expected-error {{extra argument in call}} +// expected-error@-1 {{missing argument for parameter #3 in call}} // ------------------------------------------- // Out-of-order keywords @@ -200,6 +211,7 @@ func testLabelErrorDefault() { // Variadics // ------------------------------------------- func variadics1(x: Int, y: Int, _ z: Int...) { } +// expected-note@-1 {{'variadics1(x:y:_:)' declared here}} // Using variadics (in-order, complete) variadics1(x: 1, y: 2) @@ -208,7 +220,7 @@ variadics1(x: 1, y: 2, 1, 2) variadics1(x: 1, y: 2, 1, 2, 3) // Using various (out-of-order) -variadics1(1, 2, 3, 4, 5, x: 6, y: 7) // expected-error {{incorrect argument labels in call (have '_:_:_:_:_:x:y:', expected 'x:y:_:')}} {{12-12=x: }} {{15-15=y: }} {{27-30=}} {{33-36=}} +variadics1(1, 2, 3, 4, 5, x: 6, y: 7) // expected-error {{extra arguments at positions #1, #2, #3, #4, #5 in call}} func variadics2(x: Int, y: Int = 2, z: Int...) { } // expected-note {{'variadics2(x:y:z:)' declared here}} @@ -226,6 +238,7 @@ variadics2(z: 1, 2, 3, y: 2) // expected-error{{missing argument for parameter ' variadics2(z: 1, 2, 3, x: 1) // expected-error{{argument 'x' must precede argument 'z'}} {{12-12=x: 1, }} {{22-28=}} func variadics3(_ x: Int..., y: Int = 2, z: Int = 3) { } +// expected-note@-1 {{'variadics3(_:y:z:)' declared here}} // Using variadics (in-order, complete) variadics3(1, 2, 3, y: 0, z: 1) @@ -246,8 +259,8 @@ variadics3(1) variadics3() // Using variadics (out-of-order) -variadics3(y: 0, 1, 2, 3) // expected-error{{unnamed argument #2 must precede argument 'y'}} {{12-12=1, 2, 3, }} {{16-25=}} -variadics3(z: 1, 1) // expected-error{{unnamed argument #2 must precede argument 'z'}} {{12-12=1, }} {{16-19=}} +variadics3(y: 0, 1, 2, 3) // expected-error{{extra arguments at positions #3, #4 in call}} +variadics3(z: 1, 1) // expected-error{{extra argument in call}} func variadics4(x: Int..., y: Int = 2, z: Int = 3) { } @@ -274,6 +287,7 @@ variadics4(y: 0, x: 1, 2, 3) // expected-error{{argument 'x' must precede argume variadics4(z: 1, x: 1) // expected-error{{argument 'x' must precede argument 'z'}} {{12-12=x: 1, }} {{16-22=}} func variadics5(_ x: Int, y: Int, _ z: Int...) { } // expected-note {{declared here}} +// expected-note@-1 {{'variadics5(_:y:_:)' declared here}} // Using variadics (in-order, complete) variadics5(1, y: 2) @@ -282,7 +296,7 @@ variadics5(1, y: 2, 1, 2) variadics5(1, y: 2, 1, 2, 3) // Using various (out-of-order) -variadics5(1, 2, 3, 4, 5, 6, y: 7) // expected-error{{argument 'y' must precede unnamed argument #2}} {{15-15=y: 7, }} {{28-34=}} +variadics5(1, 2, 3, 4, 5, 6, y: 7) // expected-error{{extra arguments at positions #2, #3, #4, #5, #6 in call}} variadics5(y: 1, 2, 3, 4, 5, 6, 7) // expected-error{{missing argument for parameter #1 in call}} func variadics6(x: Int..., y: Int = 2, z: Int) { } // expected-note 4 {{'variadics6(x:y:z:)' declared here}} @@ -306,12 +320,13 @@ variadics6(x: 1) // expected-error{{missing argument for parameter 'z' in call}} variadics6() // expected-error{{missing argument for parameter 'z' in call}} func outOfOrder(_ a : Int, b: Int) { - outOfOrder(b: 42, 52) // expected-error {{unnamed argument #2 must precede argument 'b'}} {{14-14=52, }} {{19-23=}} + // expected-note@-1 {{'outOfOrder(_:b:)' declared here}} + outOfOrder(b: 42, 52) // expected-error {{extra argument in call}} + // expected-error@-1 {{missing argument for parameter #1 in call}} } struct Variadics7 { - func f(alpha: Int..., bravo: Int) {} // expected-note {{'f(alpha:bravo:)' declared here}} - // expected-note@-1 {{'f(alpha:bravo:)' declared here}} + func f(alpha: Int..., bravo: Int) {} func test() { // no error @@ -327,8 +342,8 @@ struct Variadics7 { // typo A f(alphax: 0, bravo: 3) // expected-error {{incorrect argument label in call (have 'alphax:bravo:', expected 'alpha:bravo:')}} - f(alphax: 0, 1, bravo: 3) // expected-error {{extra argument in call}} - f(alphax: 0, 1, 2, bravo: 3) // expected-error {{extra arguments at positions #2, #3 in call}} + f(alphax: 0, 1, bravo: 3) // expected-error {{incorrect argument label in call (have 'alphax:_:bravo:', expected 'alpha:_:bravo:')}} + f(alphax: 0, 1, 2, bravo: 3) // expected-error {{incorrect argument label in call (have 'alphax:_:_:bravo:', expected 'alpha:_:_:bravo:')}} // typo B f(bravox: 0) // expected-error {{incorrect argument label in call (have 'bravox:', expected 'bravo:')}} @@ -338,13 +353,13 @@ struct Variadics7 { // OoO + typo A B f(bravox: 0, alphax: 1) // expected-error {{incorrect argument labels in call (have 'bravox:alphax:', expected 'alpha:bravo:')}} - f(bravox: 0, alphax: 1, 2) // expected-error {{extra argument in call}} - f(bravox: 0, alphax: 1, 2, 3) // expected-error {{extra arguments at positions #3, #4 in call}} + f(bravox: 0, alphax: 1, 2) // expected-error {{incorrect argument labels in call (have 'bravox:alphax:_:', expected 'alpha:bravo:')}} + f(bravox: 0, alphax: 1, 2, 3) // expected-error {{incorrect argument labels in call (have 'bravox:alphax:_:_:', expected 'alpha:bravo:')}} } } struct Variadics8 { - func f(alpha: Int..., bravo: Int, charlie: Int) {} // expected-note {{'f(alpha:bravo:charlie:)' declared here}} + func f(alpha: Int..., bravo: Int, charlie: Int) {} func test() { // no error @@ -369,8 +384,8 @@ struct Variadics8 { // typo A f(alphax: 0, bravo: 3, charlie: 4) // expected-error {{incorrect argument label in call (have 'alphax:bravo:charlie:', expected 'alpha:bravo:charlie:')}} - f(alphax: 0, 1, bravo: 3, charlie: 4) // expected-error {{extra argument in call}} - f(alphax: 0, 1, 2, bravo: 3, charlie: 4) // expected-error {{extra arguments at positions #2, #3 in call}} + f(alphax: 0, 1, bravo: 3, charlie: 4) // expected-error {{incorrect argument label in call (have 'alphax:_:bravo:charlie:', expected 'alpha:_:bravo:charlie:')}} + f(alphax: 0, 1, 2, bravo: 3, charlie: 4) // expected-error {{incorrect argument label in call (have 'alphax:_:_:bravo:charlie:', expected 'alpha:_:_:bravo:charlie:')}} // typo B f(bravox: 3, charlie: 4) // expected-error {{incorrect argument label in call (have 'bravox:charlie:', expected 'bravo:charlie:')}} f(alpha: 0, bravox: 3, charlie: 4) // expected-error {{incorrect argument label in call (have 'alpha:bravox:charlie:', expected 'alpha:bravo:charlie:')}} @@ -404,7 +419,9 @@ struct Variadics8 { } func var_31849281(_ a: Int, _ b: Int..., c: Int) {} -var_31849281(1, c: 10, 3, 4, 5, 6, 7, 8, 9) // expected-error {{unnamed argument #3 must precede argument 'c'}} {{17-17=3, 4, 5, 6, 7, 8, 9, }} {{22-43=}} +// expected-note@-1 {{'var_31849281(_:_:c:)' declared here}} + +var_31849281(1, c: 10, 3, 4, 5, 6, 7, 8, 9) // expected-error {{extra arguments at positions #3, #4, #5, #6, #7, #8, #9 in call}} func testLabelErrorVariadic() { func f(aa: Int, bb: Int, cc: Int...) {} @@ -427,34 +444,36 @@ struct PositionsAroundDefaultsAndVariadics { func test_f1() { f1(true, 2, c: "3", [4]) - f1(true, c: "3", 2, [4]) // expected-error {{unnamed argument #4 must precede argument 'c'}} + f1(true, c: "3", 2, [4]) // expected-error {{extra argument in call}} + // expected-error@-1 {{cannot convert value of type 'Int' to expected argument type '[Int]'}} - f1(true, c: "3", [4], 2) // expected-error {{unnamed argument #4 must precede argument 'c'}} + f1(true, c: "3", [4], 2) // expected-error {{extra argument in call}} f1(true, c: "3", 2) // expected-error {{cannot convert value of type 'Int' to expected argument type '[Int]'}} f1(true, c: "3", [4]) - f1(c: "3", 2, [4]) // expected-error {{unnamed argument #3 must precede argument 'c'}} + f1(c: "3", 2, [4]) // expected-error {{extra argument in call}} + // expected-error@-1 {{cannot convert value of type 'Int' to expected argument type '[Int]'}} - f1(c: "3", [4], 2) // expected-error {{unnamed argument #3 must precede argument 'c'}} + f1(c: "3", [4], 2) // expected-error {{extra argument in call}} f1(c: "3", 2) // expected-error {{cannot convert value of type 'Int' to expected argument type '[Int]'}} f1(c: "3", [4]) - f1(b: "2", [3]) // expected-error {{incorrect argument labels in call (have 'b:_:', expected '_:_:c:_:')}} - // expected-error@-1 {{cannot convert value of type '[Int]' to expected argument type 'Bool'}} + f1(b: "2", [3]) + // expected-error@-1 {{incorrect argument label in call (have 'b:_:', expected 'c:_:')}} - f1(b: "2", 1) // expected-error {{incorrect argument labels in call (have 'b:_:', expected '_:_:c:_:')}} - // expected-error@-1 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + f1(b: "2", 1) // expected-error {{cannot convert value of type 'Int' to expected argument type '[Int]'}} + // expected-error@-1 {{incorrect argument label in call (have 'b:_:', expected 'c:_:')}} - f1(b: "2", [3], 1) // expected-error {{incorrect argument labels in call (have 'b:_:_:', expected '_:_:c:_:')}} - // expected-error@-1 {{cannot convert value of type '[Int]' to expected argument type 'Bool'}} + f1(b: "2", [3], 1) + // expected-error@-1 {{extra argument in call}} - f1(b: "2", 1, [3]) // expected-error {{incorrect argument labels in call (have 'b:_:_:', expected '_:_:c:_:')}} - // expected-error@-1 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} - // expected-error@-2 {{cannot convert value of type '[Int]' to expected argument type 'Int'}} + f1(b: "2", 1, [3]) + // expected-error@-1 {{cannot convert value of type 'Int' to expected argument type '[Int]'}} + // expected-error@-2 {{extra argument in call}} } // unlabeled variadics before labeled parameter @@ -475,11 +494,10 @@ struct PositionsAroundDefaultsAndVariadics { f2(true, c: "3", 21) // expected-error {{cannot convert value of type 'Int' to expected argument type '[Int]'}} - f2(true, c: "3", 21, [4]) // expected-error {{unnamed argument #4 must precede argument 'c'}} - // expected-error@-1 {{cannot pass array of type '[Int]' as variadic arguments of type 'Int'}} - // expected-note@-2 {{remove brackets to pass array elements directly}} + f2(true, c: "3", 21, [4]) // expected-error {{cannot convert value of type 'Int' to expected argument type '[Int]'}} + // expected-error@-1 {{extra argument in call}} - f2(true, c: "3", [4], 21) // expected-error {{unnamed argument #4 must precede argument 'c'}} + f2(true, c: "3", [4], 21) // expected-error {{extra argument in call}} f2(true, [4]) // expected-error {{cannot pass array of type '[Int]' as variadic arguments of type 'Int'}} // expected-note@-1 {{remove brackets to pass array elements directly}} @@ -502,12 +520,12 @@ struct PositionsAroundDefaultsAndVariadics { f2(c: "3", 21) // expected-error {{cannot convert value of type 'Int' to expected argument type '[Int]'}} - f2(c: "3", 21, [4]) // expected-error {{incorrect argument labels in call (have 'c:_:_:', expected '_:_:c:_:')}} + f2(c: "3", 21, [4]) // expected-error@-1 {{cannot convert value of type 'Int' to expected argument type '[Int]'}} - // expected-error@-2 {{cannot convert value of type '[Int]' to expected argument type 'Bool'}} + // expected-error@-2 {{extra argument in call}} - f2(c: "3", [4], 21) // expected-error {{incorrect argument labels in call (have 'c:_:_:', expected '_:_:c:_:')}} - // expected-error@-1 {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} + f2(c: "3", [4], 21) + // expected-error@-1 {{extra argument in call}} f2([4]) // expected-error {{cannot convert value of type '[Int]' to expected argument type 'Bool'}} @@ -581,9 +599,9 @@ struct PositionsAroundDefaultsAndVariadics { f4(true, b: "2", 31, d: [4]) f4(true, b: "2", d: [4]) - f4(true, 31, b: "2", d: [4]) // expected-error {{argument 'b' must precede unnamed argument #2}} + f4(true, 31, b: "2", d: [4]) // expected-error {{extra argument in call}} - f4(true, b: "2", d: [4], 31) // expected-error {{unnamed argument #4 must precede argument 'd'}} + f4(true, b: "2", d: [4], 31) // expected-error {{extra argument in call}} f4(true, b: "2", 31) f4(true, b: "2") @@ -608,7 +626,7 @@ struct PositionsAroundDefaultsAndVariadics { f4(31, b: "2", d: [4]) // expected-error {{type 'Int' cannot be used as a boolean; test for '!= 0' instead}} - f4(b: "2", d: [4], 31) // expected-error {{unnamed argument #3 must precede argument 'b'}} + f4(b: "2", d: [4], 31) // expected-error {{extra argument in call}} f4(b: "2", 31) f4(b: "2", 31, 32) @@ -643,7 +661,7 @@ struct PositionsAroundDefaultsAndVariadics { f5(true, c: 31, b: "2", d: [4]) // expected-error {{argument 'b' must precede argument 'c'}} - f5(true, b: "2", d: [4], 31) // expected-error {{incorrect argument labels in call (have '_:b:d:_:', expected '_:b:c:d:')}} + f5(true, b: "2", d: [4], 31) // expected-error {{extra argument in call}} f5(true, b: "2", c: 31) f5(true, b: "2") @@ -690,8 +708,121 @@ func testUnlabeledParameterBindingPosition() { do { func f(_ aa: Int) {} + f(1) // ok + + f(xx: 1) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + f(0, 1) // expected-error@-1:10 {{extra argument in call}} + + f(xx: 1, 2) + // expected-error@-1:11 {{extra argument 'xx' in call}} + + f(1, xx: 2) + // expected-error@-1:14 {{extra argument 'xx' in call}} + + f(xx: 1, yy: 2) + // expected-error@-1:18 {{extra argument 'yy' in call}} + } + + do { + func f(aa: Int) { } + + f(1) + // expected-error@-1:7 {{missing argument label 'aa:' in call}} + + f(aa: 1) // ok + + f(xx: 1) + // expected-error@-1 {{incorrect argument label in call (have 'xx:', expected 'aa:')}} + } + + do { + func f(_ aa: Int, _ bb: Int) { } + // expected-note@-1 3 {{'f' declared here}} + + f(1) + // expected-error@-1:8 {{missing argument for parameter #2 in call}} + + f(xx: 1) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:12 {{missing argument for parameter #2 in call}} + + f(1, 2) // ok + + f(1, xx: 2) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + + f(xx: 1, 2) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + + f(xx: 1, yy: 2) + // expected-error@-1 {{extraneous argument labels 'xx:yy:' in call}} + + f(xx: 1, 2, 3) + // expected-error@-1:11 {{extra argument 'xx' in call}} + + f(1, xx: 2, 3) + // expected-error@-1:14 {{extra argument 'xx' in call}} + + f(1, 2, xx: 3) + // expected-error@-1:17 {{extra argument 'xx' in call}} + + f(xx: 1, yy: 2, 3) + // expected-error@-1:18 {{extra argument 'yy' in call}} + + f(xx: 1, yy: 2, 3, 4) + // expected-error@-1:6 {{extra arguments at positions #1, #2 in call}} + } + + do { + func f(_ aa: Int = 0, _ bb: Int) { } + // expected-note@-1 {{'f' declared here}} + + f(1) + // expected-error@-1:8 {{missing argument for parameter #2 in call}} + + f(1, 2) // ok + } + + do { + func f(_ aa: Int, bb: Int) { } + // expected-note@-1 4 {{'f(_:bb:)' declared here}} + + f(1) + // expected-error@-1:8 {{missing argument for parameter 'bb' in call}} + + f(1, 2) + // expected-error@-1 {{missing argument label 'bb:' in call}} + + f(1, bb: 2) // ok + + f(xx: 1, 2) + // expected-error@-1:11 {{extra argument 'xx' in call}} + // expected-error@-2:12 {{missing argument for parameter 'bb' in call}} + + f(xx: 1, bb: 2) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + + f(bb: 1, 2, 3) + // expected-error@-1:6 {{extra arguments at positions #2, #3 in call}} + // expected-error@-2:7 {{missing argument for parameter #1 in call}} + + f(1, bb: 2, 3) + // expected-error@-1:17 {{extra argument in call}} + + f(1, 2, bb: 3) + // expected-error@-1:10 {{extra argument in call}} + + f(xx: 1, 2, 3) + // expected-error@-1:11 {{extra argument 'xx' in call}} + + f(1, xx: 2, 3) + // expected-error@-1:14 {{extra argument 'xx' in call}} + + f(1, 2, xx: 3) + // expected-error@-1:17 {{extra argument 'xx' in call}} } do { @@ -709,8 +840,7 @@ func testUnlabeledParameterBindingPosition() { // expected-error@-2:14 {{extra argument 'xx' in call}} f(xx: 0, 1) - // expected-error@-1:7 {{missing argument for parameter 'aa' in call}} - // expected-error@-2:14 {{extra argument in call}} + // expected-error@-1:6 {{incorrect argument label in call (have 'xx:_:', expected 'aa:_:')}} f(0, 1, 9) // expected-error@-1:13 {{extra argument in call}} @@ -718,16 +848,98 @@ func testUnlabeledParameterBindingPosition() { f(0, 1, xx: 9) // expected-error@-1:17 {{extra argument 'xx' in call}} + f(0, 1, 2) + // expected-error@-1:13 {{extra argument in call}} + f(xx: 91, 1, 92) - // expected-error@-1 {{extra arguments at positions #2, #3 in call}} - // expected-error@-2 {{missing argument for parameter 'aa' in call}} + // expected-error@-1:11 {{extra argument 'xx' in call}} + + f(1, xx: 2, 3) + // expected-error@-1:14 {{extra argument 'xx' in call}} + + f(1, 2, xx: 3) + // expected-error@-1:17 {{extra argument 'xx' in call}} + } + + do { + func f(_ aa: Int, _ bb: Int = 82, _ cc: Int) { } + // expected-note@-1 {{'f' declared here}} + + f(1, 2) + // expected-error@-1:11 {{missing argument for parameter #3 in call}} + + f(1, 2, 3) // ok + } + + do { + func f(_ aa: Int, _ bb: Int, cc: Int) { } + // expected-note@-1 6 {{'f(_:_:cc:)' declared here}} + + f(1, 2, cc: 3) // ok + + f(1, 2, xx: 3) + // expected-error@-1 {{incorrect argument label in call (have '_:_:xx:', expected '_:_:cc:')}} + + f(1, cc: 2, 3) + // expected-error@-1:8 {{missing argument for parameter #2 in call}} + // expected-error@-2:17 {{extra argument in call}} + + f(1, xx: 2, 3) + // expected-error@-1:14 {{extra argument 'xx' in call}} + // expected-error@-2:15 {{missing argument for parameter 'cc' in call}} + + f(cc: 1, 2, 3) + // expected-error@-1:6 {{extra arguments at positions #2, #3 in call}} + // expected-error@-2:6 {{missing arguments for parameters #1, #2 in call}} + + f(xx: 1, 2, 3) + // expected-error@-1:11 {{extra argument 'xx' in call}} + // expected-error@-2:15 {{missing argument for parameter 'cc' in call}} + + f(xx: 1, yy: 2, 3) + // expected-error@-1:18 {{extra argument 'yy' in call}} + // expected-error@-2:19 {{missing argument for parameter 'cc' in call}} + + f(xx: 1, 2, yy: 3) + // expected-error@-1 {{incorrect argument labels in call (have 'xx:_:yy:', expected '_:_:cc:')}} + + f(1, xx: 2, yy: 3) + // expected-error@-1 {{incorrect argument labels in call (have '_:xx:yy:', expected '_:_:cc:')}} } do { func f(_ aa: Int, bb: Int, _ cc: Int) { } + // expected-note@-1 6 {{'f(_:bb:_:)' declared here}} + + f(1) + // expected-error@-1:7 {{missing arguments for parameters 'bb', #3 in call}} + + f(1, 2) + // expected-error@-1:8 {{missing argument for parameter 'bb' in call}} + + f(1, 2, 3) + // expected-error@-1 {{missing argument label 'bb:' in call}} + + f(1, 2, bb: 3) + // expected-error@-1:10 {{extra argument in call}} + // expected-error@-2:11 {{missing argument for parameter #3 in call}} + + f(1, bb: 2, 3) // ok f(bb: 1, 0, 2) - // expected-error@-1 {{unnamed argument #3 must precede argument 'bb'}} + // expected-error@-1 {{extra argument in call}} + // expected-error@-2 {{missing argument for parameter #1 in call}} + + f(xx: 1, 2, 3) + // expected-error@-1:11 {{extra argument 'xx' in call}} + // expected-error@-2:12 {{missing argument for parameter 'bb' in call}} + + f(1, xx: 2, 3) + // expected-error@-1 {{incorrect argument label in call (have '_:xx:_:', expected '_:bb:_:')}} + + f(1, 2, xx: 3) + // expected-error@-1:8 {{missing argument for parameter 'bb' in call}} + // expected-error@-2:17 {{extra argument 'xx' in call}} } do { @@ -754,8 +966,51 @@ func testUnlabeledParameterBindingPosition() { // expected-note@+1 *{{'f(aa:_:_:)' declared here}} func f(aa: Int, _ bb: Int, _ cc: Int) {} + f(1) + // expected-error@-1:7 {{missing arguments for parameters 'aa', #3 in call}} + f(0, 1) // expected-error@-1:7 {{missing argument for parameter 'aa' in call}} + + f(1, 2, 3) + // expected-error@-1:6 {{missing argument label 'aa:' in call}} + + f(1, aa: 2, 3) + // expected-error@-1:7 {{extra argument in call}} + // expected-error@-2:15 {{missing argument for parameter #3 in call}} + + f(1, xx: 2, 3) + // expected-error@-1:7 {{missing argument for parameter 'aa' in call}} + // expected-error@-2:14 {{extra argument 'xx' in call}} + + f(aa: 1, 2, 3) // ok + + f(xx: 1, 2, 3) + // expected-error@-1 {{incorrect argument label in call (have 'xx:_:_:', expected 'aa:_:_:')}} + + f(xx: 1, 2, yy: 3) + // expected-error@-1:7 {{missing argument for parameter 'aa' in call}} + // expected-error@-2:21 {{extra argument 'yy' in call}} + + f(xx: 1, yy: 2, 3) + // expected-error@-1:7 {{missing argument for parameter 'aa' in call}} + // expected-error@-2:18 {{extra argument 'yy' in call}} + + f(1, xx: 2, yy: 3) + // expected-error@-1:7 {{missing argument for parameter 'aa' in call}} + // expected-error@-2:21 {{extra argument 'yy' in call}} + + f(1, 2, 3, 4) + // expected-error@-1:16 {{extra argument in call}} + + f(1, aa: 2, 3, 4) + // expected-error@-1:7 {{extra argument in call}} + + f(1, aa: 2, 3, xx: 4) + // expected-error@-1:7 {{extra argument in call}} + + f(1, aa: 2, xx: 3, 4) + // expected-error@-1:7 {{extra argument in call}} } do { @@ -771,11 +1026,42 @@ func testUnlabeledParameterBindingPosition() { func f(aa: Int, bb: Int, _ cc: Int) {} f(0, 2) - // expected-error@-1:6 {{missing argument labels 'aa:bb:' in call}} + // expected-error@-1:6 {{missing argument label 'aa:' in call}} // expected-error@-2:8 {{missing argument for parameter 'bb' in call}} f(0, bb: 1, 2) // expected-error@-1:6 {{missing argument label 'aa:' in call}} + + f(xx: 1, 2, 3) + // expected-error@-1:11 {{extra argument 'xx' in call}} + // expected-error@-2:12 {{missing argument for parameter 'bb' in call}} + + f(1, xx: 2, 3) + // expected-error@-1 {{incorrect argument labels in call (have '_:xx:_:', expected 'aa:bb:_:')}} + + f(1, 2, xx: 3) + // expected-error@-1:8 {{missing argument for parameter 'bb' in call}} + // expected-error@-2:17 {{extra argument 'xx' in call}} + } + + do { + func f(aa: Int, bb: Int, cc: Int) { } + // expected-note@-1 3 {{'f(aa:bb:cc:)' declared here}} + + f(1, aa: 2, bb: 3) + // expected-error@-1:7 {{extra argument in call}} + // expected-error@-2:15 {{missing argument for parameter 'cc' in call}} + + f(1, bb: 2, aa: 3) + // expected-error@-1:7 {{extra argument in call}} + // expected-error@-2:15 {{missing argument for parameter 'cc' in call}} + + f(aa: 1, 2, bb: 3) + // expected-error@-1:14 {{extra argument in call}} + // expected-error@-2 {{missing argument for parameter 'cc' in call}} + + f(aa: 1, bb: 2, 3) + // expected-error@-1 {{missing argument label 'cc:' in call}} } do { @@ -786,8 +1072,142 @@ func testUnlabeledParameterBindingPosition() { do { func f(_ aa: Int, _ bb: Int = 81, cc: Int = 82, _ dd: Int) {} + // expected-note@-1 2 {{'f(_:_:cc:_:)' declared here}} f(0, cc: 2, 3) // ok + + f(cc: 1, 2, 3, 4) + // expected-error@-1:6 {{extra arguments at positions #3, #4 in call}} + // expected-error@-2:7 {{missing argument for parameter #1 in call}} + } + + do { + func f(_ aa: Int, _ bb: Int, cc: Int, dd: Int) { } + // expected-note@-1 6 {{'f(_:_:cc:dd:)' declared here}} + + f(1, xx: 2) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:6 {{missing arguments for parameters 'cc', 'dd' in call}} + + f(xx: 1, 2) + // expected-error@-1:6 {{missing arguments for parameters 'cc', 'dd' in call}} + // expected-error@-2 {{extraneous argument label 'xx:' in call}} + + f(1, xx: 2, cc: 3) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:22 {{missing argument for parameter 'dd' in call}} + + f(1, xx: 2, dd: 3) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:15 {{missing argument for parameter 'cc' in call}} + + f(xx: 1, 2, cc: 3) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:22 {{missing argument for parameter 'dd' in call}} + + f(xx: 1, 2, dd: 3) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:15 {{missing argument for parameter 'cc' in call}} + + f(1, xx: 2, cc: 3, dd: 4) + // expected-error@-1:6 {{extraneous argument label 'xx:' in call}} + + f(xx: 1, 2, cc: 3, dd: 4) + // expected-error@-1:6 {{extraneous argument label 'xx:' in call}} + } + + do { + func f(_ aa: Int, bb: Int = 82, _ cc: Int, _ dd: Int) { } + // expected-note@-1 {{'f(_:bb:_:_:)' declared here}} + + f(1, bb: 2, 3, 4) // ok + + f(1, 2, bb: 3, 4) + // expected-error@-1:10 {{extra argument in call}} + // expected-error@-2:18 {{missing argument for parameter #4 in call}} + } + + do { + func f(aa: Int, _ bb: Int, cc: Int, _ dd: Int) { } + // expected-note@-1 3 {{'f(aa:_:cc:_:)' declared here}} + + f(1) + // expected-error@-1:7 {{missing arguments for parameters 'aa', 'cc', #4 in call}} + + f(1, 2) + // expected-error@-1:6 {{missing arguments for parameters 'aa', 'cc' in call}} + + f(1, 2, 3) + // expected-error@-1 {{missing argument label 'aa:' in call}} + // expected-error@-2:11 {{missing argument for parameter 'cc' in call}} + + f(1, 2, 3, 4) + // expected-error@-1:6 {{missing argument labels 'aa:cc:' in call}} + + f(1, 2, 3, 4, 5) + // expected-error@-1:19 {{extra argument in call}} + } + + do { + func f(aa: Int, bb: Int, _ cc: Int, _ dd: Int) { } + // expected-note@-1 6 {{'f(aa:bb:_:_:)' declared here}} + + f(1, xx: 2) + // expected-error@-1:6 {{missing arguments for parameters 'aa', 'bb' in call}} + // expected-error@-2 {{extraneous argument label 'xx:' in call}} + + f(xx: 1, 2) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:6 {{missing arguments for parameters 'aa', 'bb' in call}} + + f(bb: 1, 2, xx: 3) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:7 {{missing argument for parameter 'aa' in call}} + + f(bb: 1, xx: 2, 3) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:7 {{missing argument for parameter 'aa' in call}} + + f(aa: 1, 2, xx: 3) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:12 {{missing argument for parameter 'bb' in call}} + + f(aa: 1, xx: 2, 3) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + // expected-error@-2:12 {{missing argument for parameter 'bb' in call}} + + f(aa: 1, bb: 2, 3, xx: 4) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + + f(aa: 1, bb: 2, xx: 3, 4) + // expected-error@-1 {{extraneous argument label 'xx:' in call}} + } + + do { + func f(_ aa: Int, bb: Int, _ cc: Int, dd: Int, _ ee: Int) { } + // expected-note@-1 2 {{'f(_:bb:_:dd:_:)' declared here}} + + f(1, bb: 2, 3, 4, dd: 5) + // expected-error@-1:20 {{extra argument in call}} + // expected-error@-2:21 {{missing argument for parameter #5 in call}} + + f(1, dd: 2, 3, 4, bb: 5) + // expected-error@-1:15 {{missing argument for parameter #3 in call}} + // expected-error@-2:20 {{extra argument in call}} + + f(1, bb: 2, 3, dd: 4, 5) // ok + + f(1, dd: 2, 3, bb: 4, 5) + // expected-error@-1 {{incorrect argument labels in call (have '_:dd:_:bb:_:', expected '_:bb:_:dd:_:')}} + + f(1, 2, bb: 3, 4, dd: 5, 6) + // expected-error@-1:10 {{extra argument in call}} + + f(1, bb: 2, 3, 4, dd: 5, 6) + // expected-error@-1:20 {{extra argument in call}} + + f(1, dd: 2, 3, 4, bb: 5, 6) + // expected-error@-1:20 {{extra argument in call}} } } @@ -815,11 +1235,11 @@ extraargs1(x: 1, 2, 3) // expected-error{{extra arguments at positions #2, #3 in // Argument name mismatch // ------------------------------------------- -func mismatch1(thisFoo: Int = 0, bar: Int = 0, wibble: Int = 0) { } // expected-note {{'mismatch1(thisFoo:bar:wibble:)' declared here}} +func mismatch1(thisFoo: Int = 0, bar: Int = 0, wibble: Int = 0) { } -mismatch1(foo: 5) // expected-error {{extra argument 'foo' in call}} +mismatch1(foo: 5) // expected-error {{incorrect argument label in call (have 'foo:', expected 'thisFoo:')}} mismatch1(baz: 1, wobble: 2) // expected-error{{incorrect argument labels in call (have 'baz:wobble:', expected 'bar:wibble:')}} {{11-14=bar}} {{19-25=wibble}} -mismatch1(food: 1, zap: 2) // expected-error{{extra arguments at positions #1, #2 in call}} +mismatch1(food: 1, zap: 2) // expected-error{{incorrect argument labels in call (have 'food:zap:', expected 'thisFoo:bar:')}} // QoI: FailureDiagnosis doesn't look through 'try' struct rdar27891805 { @@ -1159,7 +1579,7 @@ _ = CurriedClass.method3(1, 2) // expected-error {{instance member 'me // expected-error@-1 {{missing argument label 'b:' in call}} CurriedClass.method3(c)(1.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} CurriedClass.method3(c)(1) // expected-error {{missing argument for parameter 'b' in call}} -CurriedClass.method3(c)(c: 1.0) // expected-error {{incorrect argument labels in call (have 'c:', expected '_:b:')}} +CurriedClass.method3(c)(c: 1.0) // expected-error {{incorrect argument label in call (have 'c:', expected 'b:')}} // expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Int'}} // expected-error@-2 {{missing argument for parameter #1 in call}} diff --git a/test/Constraints/diagnostics_swift4.swift b/test/Constraints/diagnostics_swift4.swift index 3cffe9d38ab67..55fd1495ab62f 100644 --- a/test/Constraints/diagnostics_swift4.swift +++ b/test/Constraints/diagnostics_swift4.swift @@ -6,7 +6,7 @@ func sr_2505(_ a: Any) {} // expected-note {{}} sr_2505() // expected-error {{missing argument for parameter #1 in call}} sr_2505(a: 1) // expected-error {{extraneous argument label 'a:' in call}} sr_2505(1, 2) // expected-error {{extra argument in call}} -sr_2505(a: 1, 2) // expected-error {{extra argument in call}} +sr_2505(a: 1, 2) // expected-error {{extra argument 'a' in call}} struct C_2505 { init(_ arg: Any) { diff --git a/test/Constraints/function.swift b/test/Constraints/function.swift index 16d0bf2455fce..a02d2ed1da2a4 100644 --- a/test/Constraints/function.swift +++ b/test/Constraints/function.swift @@ -36,7 +36,7 @@ var s: String = optFunc("hi") // Default arguments cause crash with tuple permutation func testArgumentShuffle(_ first: Int = 7, third: Int = 9) { } -testArgumentShuffle(third: 1, 2) // expected-error {{unnamed argument #2 must precede argument 'third'}} {{21-21=2, }} {{29-32=}} +testArgumentShuffle(third: 1, 2) // expected-error {{extra argument in call}} {{none}} diff --git a/test/Parse/multiple_trailing_closures.swift b/test/Parse/multiple_trailing_closures.swift index 0fb3976f9d493..0bab2f474610f 100644 --- a/test/Parse/multiple_trailing_closures.swift +++ b/test/Parse/multiple_trailing_closures.swift @@ -79,10 +79,12 @@ multiple_trailing_with_defaults(duration: 42) {} completion: {} func test_multiple_trailing_syntax_without_labels() { func fn(f: () -> Void, g: () -> Void) {} + // expected-note@-1 {{'fn(f:g:)' declared here}} fn {} g: {} // Ok fn {} _: {} // expected-error {{extra argument in call}} + // expected-error@-1 {{missing argument for parameter 'f' in call}} fn {} g: <#T##() -> Void#> // expected-error {{editor placeholder in source file}} diff --git a/test/decl/var/property_wrappers.swift b/test/decl/var/property_wrappers.swift index 51c06e93ecfcb..4e4eb1115b977 100644 --- a/test/decl/var/property_wrappers.swift +++ b/test/decl/var/property_wrappers.swift @@ -1208,7 +1208,7 @@ struct MissingPropertyWrapperUnwrap { struct InvalidPropertyDelegateUse { // TODO(diagnostics): We need to a tailored diagnostic for extraneous arguments in property delegate initialization - @Foo var x: Int = 42 // expected-error@:21 {{argument passed to call that takes no arguments}} + @Foo var x: Int = 42 // expected-error@:4 {{incorrect argument label in call (have 'wrappedValue:', expected 'prop:')}} func test() { self.x.foo() // expected-error {{value of type 'Int' has no member 'foo'}} diff --git a/test/stdlib/PrintDiagnostics.swift b/test/stdlib/PrintDiagnostics.swift index 11eb7301c3381..81608e24a2a37 100644 --- a/test/stdlib/PrintDiagnostics.swift +++ b/test/stdlib/PrintDiagnostics.swift @@ -5,10 +5,13 @@ var stream = "" print(3, &stream) // expected-error{{'&' used with non-inout argument of type 'Any'}} debugPrint(3, &stream) // expected-error{{'&' used with non-inout argument of type 'Any'}} -print(3, &stream, appendNewline: false) // expected-error {{extra argument 'appendNewline' in call}} +print(3, &stream, appendNewline: false) // expected-error {{incorrect argument label in call (have '_:_:appendNewline:', expected '_:_:separator:')}} // expected-error@-1:10 {{'&' used with non-inout argument of type 'Any'}} +// expected-error@-2:34 {{cannot convert value of type 'Bool' to expected argument type 'String'}} -debugPrint(3, &stream, appendNewline: false) // expected-error {{extra argument 'appendNewline' in call}} +debugPrint(3, &stream, appendNewline: false) // expected-error {{incorrect argument label in call (have '_:_:appendNewline:', expected '_:_:separator:')}} // expected-error@-1:15 {{'&' used with non-inout argument of type 'Any'}} +// expected-error@-2:39 {{cannot convert value of type 'Bool' to expected argument type 'String'}} -print(4, quack: 5) // expected-error {{extra argument 'quack' in call}} +print(4, quack: 5) // expected-error {{incorrect argument label in call (have '_:quack:', expected '_:separator:')}} +// expected-error@-1 {{cannot convert value of type 'Int' to expected argument type 'String'}}