Skip to content

Commit 990e4e9

Browse files
committed
---
yaml --- r: 349173 b: refs/heads/master-next c: 65c03d5 h: refs/heads/master i: 349171: 1638829
1 parent ae01fb5 commit 990e4e9

File tree

2 files changed

+78
-19
lines changed

2 files changed

+78
-19
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
refs/heads/master: 3574c513bbc5578dd9346b4ea9ab5995c5927bb5
3-
refs/heads/master-next: b15ef15a60c74f37bdf9098aa5fd79eb9ce575b8
3+
refs/heads/master-next: 65c03d5f065ae7a376d11a2f5bb4b2bb00372524
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea
66
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-b: 66d897bfcf64a82cb9a87f5e663d889189d06d07

branches/master-next/lib/Sema/CSSimplify.cpp

Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,14 @@ matchCallArguments(ArrayRef<AnyFunctionType::Param> args,
590590
if (paramInfo.hasDefaultArgument(paramIdx))
591591
continue;
592592

593-
listener.missingArgument(paramIdx);
593+
if (potentiallyOutOfOrder)
594+
return true;
595+
596+
if (auto newArgIdx = listener.missingArgument(paramIdx)) {
597+
parameterBindings[paramIdx].push_back(*newArgIdx);
598+
continue;
599+
}
600+
594601
return true;
595602
}
596603
}
@@ -790,20 +797,58 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
790797

791798
class ArgumentFailureTracker : public MatchCallArgumentListener {
792799
ConstraintSystem &CS;
793-
ArrayRef<AnyFunctionType::Param> Arguments;
800+
SmallVectorImpl<AnyFunctionType::Param> &Arguments;
794801
ArrayRef<AnyFunctionType::Param> Parameters;
795802
SmallVectorImpl<ParamBinding> &Bindings;
796803
ConstraintLocatorBuilder Locator;
797804

805+
unsigned NumSynthesizedArgs = 0;
806+
798807
public:
799808
ArgumentFailureTracker(ConstraintSystem &cs,
800-
ArrayRef<AnyFunctionType::Param> args,
809+
SmallVectorImpl<AnyFunctionType::Param> &args,
801810
ArrayRef<AnyFunctionType::Param> params,
802811
SmallVectorImpl<ParamBinding> &bindings,
803812
ConstraintLocatorBuilder locator)
804813
: CS(cs), Arguments(args), Parameters(params), Bindings(bindings),
805814
Locator(locator) {}
806815

816+
~ArgumentFailureTracker() override {
817+
if (NumSynthesizedArgs > 0) {
818+
ArrayRef<AnyFunctionType::Param> argRef(Arguments);
819+
820+
auto *fix =
821+
AddMissingArguments::create(CS, argRef.take_back(NumSynthesizedArgs),
822+
CS.getConstraintLocator(Locator));
823+
824+
// Not having an argument is the same impact as having a type mismatch.
825+
(void)CS.recordFix(fix, /*impact=*/NumSynthesizedArgs * 2);
826+
}
827+
}
828+
829+
Optional<unsigned> missingArgument(unsigned paramIdx) override {
830+
if (!CS.shouldAttemptFixes())
831+
return None;
832+
833+
const auto &param = Parameters[paramIdx];
834+
835+
unsigned newArgIdx = Arguments.size();
836+
auto argLoc =
837+
Locator
838+
.withPathElement(
839+
LocatorPathElt::ApplyArgToParam(newArgIdx, paramIdx))
840+
.withPathElement(LocatorPathElt::SynthesizedArgument(newArgIdx));
841+
842+
auto *argType = CS.createTypeVariable(
843+
CS.getConstraintLocator(argLoc),
844+
TVO_CanBindToInOut | TVO_CanBindToLValue | TVO_CanBindToNoEscape);
845+
846+
Arguments.push_back(param.withType(argType));
847+
++NumSynthesizedArgs;
848+
849+
return newArgIdx;
850+
}
851+
807852
bool missingLabel(unsigned paramIndex) override {
808853
return !CS.shouldAttemptFixes();
809854
}
@@ -883,19 +928,19 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
883928

884929
// Match up the call arguments to the parameters.
885930
SmallVector<ParamBinding, 4> parameterBindings;
886-
ArgumentFailureTracker listener(cs, argsWithLabels, params, parameterBindings,
887-
locator);
888-
if (constraints::matchCallArguments(argsWithLabels, params,
889-
paramInfo,
890-
hasTrailingClosure,
891-
cs.shouldAttemptFixes(), listener,
892-
parameterBindings)) {
893-
if (!cs.shouldAttemptFixes())
894-
return cs.getTypeMatchFailure(locator);
931+
{
932+
ArgumentFailureTracker listener(cs, argsWithLabels, params,
933+
parameterBindings, locator);
934+
if (constraints::matchCallArguments(
935+
argsWithLabels, params, paramInfo, hasTrailingClosure,
936+
cs.shouldAttemptFixes(), listener, parameterBindings)) {
937+
if (!cs.shouldAttemptFixes())
938+
return cs.getTypeMatchFailure(locator);
895939

896-
if (AllowTupleSplatForSingleParameter::attempt(cs, argsWithLabels, params,
897-
parameterBindings, locator))
898-
return cs.getTypeMatchFailure(locator);
940+
if (AllowTupleSplatForSingleParameter::attempt(
941+
cs, argsWithLabels, params, parameterBindings, locator))
942+
return cs.getTypeMatchFailure(locator);
943+
}
899944
}
900945

901946
// If this application is part of an operator, then we allow an implicit
@@ -904,6 +949,15 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
904949
auto *anchor = locator.getAnchor();
905950
assert(anchor && "locator without anchor expression?");
906951

952+
auto isSynthesizedArgument = [](const AnyFunctionType::Param &arg) -> bool {
953+
if (auto *typeVar = arg.getPlainType()->getAs<TypeVariableType>()) {
954+
auto *locator = typeVar->getImpl().getLocator();
955+
return locator->isLastElement(ConstraintLocator::SynthesizedArgument);
956+
}
957+
958+
return false;
959+
};
960+
907961
for (unsigned paramIdx = 0, numParams = parameterBindings.size();
908962
paramIdx != numParams; ++paramIdx){
909963
// Skip unfulfilled parameters. There's nothing to do for them.
@@ -918,10 +972,11 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
918972
for (auto argIdx : parameterBindings[paramIdx]) {
919973
auto loc = locator.withPathElement(LocatorPathElt::ApplyArgToParam(
920974
argIdx, paramIdx, param.getParameterFlags()));
921-
auto argTy = argsWithLabels[argIdx].getOldType();
975+
const auto &argument = argsWithLabels[argIdx];
976+
auto argTy = argument.getOldType();
922977

923978
bool matchingAutoClosureResult = param.isAutoClosure();
924-
if (param.isAutoClosure()) {
979+
if (param.isAutoClosure() && !isSynthesizedArgument(argument)) {
925980
auto &ctx = cs.getASTContext();
926981
auto *fnType = paramTy->castTo<FunctionType>();
927982
auto *argExpr = getArgumentExpr(locator.getAnchor(), argIdx);
@@ -960,7 +1015,11 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
9601015
// If argument comes for declaration it should loose
9611016
// `@autoclosure` flag, because in context it's used
9621017
// as a function type represented by autoclosure.
963-
assert(!argsWithLabels[argIdx].isAutoClosure());
1018+
//
1019+
// Special case here are synthesized arguments because
1020+
// they mirror parameter flags to ease diagnosis.
1021+
assert(!argsWithLabels[argIdx].isAutoClosure() ||
1022+
isSynthesizedArgument(argument));
9641023

9651024
cs.addConstraint(
9661025
subKind, argTy, paramTy,

0 commit comments

Comments
 (0)