Skip to content

Commit 11c45c9

Browse files
authored
Merge pull request #68136 from xedin/rdar-114341979
[CSSimplify] Modernize binary function argument reordering fix
2 parents f61bd58 + b5b335c commit 11c45c9

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4879,12 +4879,13 @@ static bool repairOutOfOrderArgumentsInBinaryFunction(
48794879
if (!argument)
48804880
return false;
48814881

4882-
auto currArgIdx =
4883-
locator->castLastElementTo<LocatorPathElt::ApplyArgToParam>().getArgIdx();
4882+
auto argLoc = locator->castLastElementTo<LocatorPathElt::ApplyArgToParam>();
4883+
auto currArgIdx = argLoc.getArgIdx();
4884+
auto currParamIdx = argLoc.getParamIdx();
48844885

48854886
// Argument is extraneous and has been re-ordered to match one
48864887
// of two parameter types.
4887-
if (currArgIdx >= 2)
4888+
if (currArgIdx >= 2 || currArgIdx != currParamIdx)
48884889
return false;
48894890

48904891
auto otherArgIdx = currArgIdx == 0 ? 1 : 0;
@@ -4901,29 +4902,54 @@ static bool repairOutOfOrderArgumentsInBinaryFunction(
49014902
return false;
49024903
}
49034904

4904-
auto matchArgToParam = [&](Type argType, Type paramType, ASTNode anchor) {
4905-
auto *loc = cs.getConstraintLocator(anchor);
4905+
auto getReorderedArgumentLocator = [&](unsigned argIdx) {
4906+
auto paramIdx = argIdx == 0 ? 1 : 0;
4907+
return cs.getConstraintLocator(
4908+
parentLoc, LocatorPathElt::ApplyArgToParam(
4909+
argIdx, paramIdx,
4910+
fnType->getParams()[paramIdx].getParameterFlags()));
4911+
};
4912+
4913+
auto matchArgToParam = [&](Type argType, Type paramType, unsigned argIdx) {
4914+
auto *loc = getReorderedArgumentLocator(argIdx);
49064915
// If argument (and/or parameter) is a generic type let's not even try this
49074916
// fix because it would be impossible to match given types without delaying
49084917
// until more context becomes available.
49094918
if (argType->hasTypeVariable() || paramType->hasTypeVariable())
49104919
return cs.getTypeMatchFailure(loc);
49114920

4921+
// FIXME: There is currently no easy way to avoid attempting
4922+
// fixes, matchTypes do not propagate `TMF_ApplyingFix` flag.
4923+
llvm::SaveAndRestore<ConstraintSystemOptions> options(
4924+
cs.Options, cs.Options - ConstraintSystemFlags::AllowFixes);
4925+
4926+
// Check optionality, if argument is more optional than parameter
4927+
// they are not going to match. This saves us one disjunction because
4928+
// optionals are matched as deep-equality and optional-to-optional.
4929+
{
4930+
unsigned numArgUnwraps;
4931+
unsigned numParamUnwraps;
4932+
4933+
std::tie(argType, numArgUnwraps) = getObjectTypeAndNumUnwraps(argType);
4934+
std::tie(paramType, numParamUnwraps) =
4935+
getObjectTypeAndNumUnwraps(paramType);
4936+
4937+
if (numArgUnwraps > numParamUnwraps)
4938+
return cs.getTypeMatchFailure(loc);
4939+
}
4940+
49124941
return cs.matchTypes(
4913-
argType->lookThroughAllOptionalTypes(),
4914-
paramType->lookThroughAllOptionalTypes(),
4942+
argType, paramType,
49154943
isOperatorRef ? ConstraintKind::OperatorArgumentConversion
49164944
: ConstraintKind::ArgumentConversion,
49174945
ConstraintSystem::TypeMatchFlags::TMF_ApplyingFix, loc);
49184946
};
49194947

4920-
auto result = matchArgToParam(argType, paramType, argument);
4948+
auto result = matchArgToParam(argType, paramType, currArgIdx);
49214949
if (result.isSuccess()) {
49224950
// Let's check whether other argument matches current parameter type,
49234951
// if it does - it's definitely out-of-order arguments issue.
4924-
auto *otherArgLoc = cs.getConstraintLocator(
4925-
parentLoc, LocatorPathElt::ApplyArgToParam(otherArgIdx, otherArgIdx,
4926-
ParameterTypeFlags()));
4952+
auto *otherArgLoc = getReorderedArgumentLocator(otherArgIdx);
49274953
auto otherArg = simplifyLocatorToAnchor(otherArgLoc);
49284954
// Argument could be synthesized.
49294955
if (!otherArg)
@@ -4932,7 +4958,7 @@ static bool repairOutOfOrderArgumentsInBinaryFunction(
49324958
argType = cs.getType(otherArg);
49334959
paramType = fnType->getParams()[currArgIdx].getOldType();
49344960

4935-
result = matchArgToParam(argType, paramType, otherArg);
4961+
result = matchArgToParam(argType, paramType, otherArgIdx);
49364962
if (result.isSuccess()) {
49374963
conversionsOrFixes.push_back(MoveOutOfOrderArgument::create(
49384964
cs, otherArgIdx, currArgIdx, {{0}, {1}}, parentLoc));

0 commit comments

Comments
 (0)