Skip to content

Commit 7ca0f46

Browse files
authored
Merge pull request #19947 from xedin/replace-curry-level-with-flag
[ConstraintSystem] Replace curry level with a boolean flag
2 parents 2f8a4db + c219af0 commit 7ca0f46

File tree

8 files changed

+161
-162
lines changed

8 files changed

+161
-162
lines changed

include/swift/AST/Types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3078,7 +3078,7 @@ END_CAN_TYPE_WRAPPER(FunctionType, AnyFunctionType)
30783078
/// it.
30793079
SmallBitVector
30803080
computeDefaultMap(ArrayRef<AnyFunctionType::Param> params,
3081-
const ValueDecl *paramOwner, unsigned level);
3081+
const ValueDecl *paramOwner, bool skipCurriedSelf);
30823082

30833083
/// Turn a param list into a symbolic and printable representation that does not
30843084
/// include the types, something like (: , b:, c:)

lib/AST/Type.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ Type TypeBase::replaceCovariantResultType(Type newResultType,
749749

750750
SmallBitVector
751751
swift::computeDefaultMap(ArrayRef<AnyFunctionType::Param> params,
752-
const ValueDecl *paramOwner, unsigned level) {
752+
const ValueDecl *paramOwner, bool skipCurriedSelf) {
753753
SmallBitVector resultVector(params.size());
754754
// No parameter owner means no parameter list means no default arguments
755755
// - hand back the zeroed bitvector.
@@ -762,15 +762,15 @@ swift::computeDefaultMap(ArrayRef<AnyFunctionType::Param> params,
762762
const ParameterList *paramList = nullptr;
763763
if (auto *func = dyn_cast<AbstractFunctionDecl>(paramOwner)) {
764764
if (func->hasImplicitSelfDecl()) {
765-
if (level == 1)
765+
if (skipCurriedSelf)
766766
paramList = func->getParameters();
767-
} else if (level == 0)
767+
} else if (!skipCurriedSelf)
768768
paramList = func->getParameters();
769769
} else if (auto *subscript = dyn_cast<SubscriptDecl>(paramOwner)) {
770-
if (level == 1)
770+
if (skipCurriedSelf)
771771
paramList = subscript->getIndices();
772772
} else if (auto *enumElement = dyn_cast<EnumElementDecl>(paramOwner)) {
773-
if (level == 1)
773+
if (skipCurriedSelf)
774774
paramList = enumElement->getParameterList();
775775
}
776776

lib/Sema/CSApply.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5450,36 +5450,36 @@ static bool isReferenceToMetatypeMember(ConstraintSystem &cs, Expr *expr) {
54505450
return false;
54515451
}
54525452

5453-
static unsigned computeCallLevel(ConstraintSystem &cs, ConcreteDeclRef callee,
5454-
ApplyExpr *apply) {
5455-
// If we do not have a callee, return a level of 0.
5453+
static bool hasCurriedSelf(ConstraintSystem &cs, ConcreteDeclRef callee,
5454+
ApplyExpr *apply) {
5455+
// If we do not have a callee, return false.
54565456
if (!callee) {
5457-
return 0;
5457+
return false;
54585458
}
54595459

5460-
// Only calls to members of types can have level > 0.
5460+
// Only calls to members of types can have curried 'self'.
54615461
auto calleeDecl = callee.getDecl();
54625462
if (!calleeDecl->getDeclContext()->isTypeContext()) {
5463-
return 0;
5463+
return false;
54645464
}
54655465

5466-
// Level 1 if we're not applying "self".
5466+
// Would have `self`, if we're not applying it.
54675467
if (auto *call = dyn_cast<CallExpr>(apply)) {
54685468
if (!calleeDecl->isInstanceMember() ||
54695469
!isReferenceToMetatypeMember(cs, call->getDirectCallee())) {
5470-
return 1;
5470+
return true;
54715471
}
5472-
return 0;
5472+
return false;
54735473
}
54745474

5475-
// Level 1 if we have an operator.
5475+
// Operators have curried self.
54765476
if (isa<PrefixUnaryExpr>(apply) || isa<PostfixUnaryExpr>(apply) ||
54775477
isa<BinaryExpr>(apply)) {
5478-
return 1;
5478+
return true;
54795479
}
54805480

54815481
// Otherwise, we have a normal application.
5482-
return 0;
5482+
return false;
54835483
}
54845484

54855485
Expr *ExprRewriter::coerceCallArguments(
@@ -5507,12 +5507,12 @@ Expr *ExprRewriter::coerceCallArguments(
55075507
ConcreteDeclRef callee =
55085508
findCalleeDeclRef(cs, solution, cs.getConstraintLocator(locator));
55095509

5510-
// Determine the level,
5511-
unsigned level = apply ? computeCallLevel(cs, callee, apply) : 0;
5510+
// Determine whether this application has curried self.
5511+
bool skipCurriedSelf = apply ? hasCurriedSelf(cs, callee, apply) : false;
55125512

55135513
// Determine the parameter bindings.
55145514
SmallBitVector defaultMap
5515-
= computeDefaultMap(params, callee.getDecl(), level);
5515+
= computeDefaultMap(params, callee.getDecl(), skipCurriedSelf);
55165516

55175517
SmallVector<AnyFunctionType::Param, 8> args;
55185518
AnyFunctionType::decomposeInput(cs.getType(arg), args);

lib/Sema/CSDiag.cpp

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2856,10 +2856,10 @@ static bool candidatesHaveAnyDefaultValues(
28562856
if (!function) continue;
28572857

28582858
if (function->hasImplicitSelfDecl()) {
2859-
if (cand.level != 1)
2859+
if (!cand.skipCurriedSelf)
28602860
return false;
28612861
} else {
2862-
if (cand.level != 0)
2862+
if (cand.skipCurriedSelf)
28632863
return false;
28642864
}
28652865

@@ -2910,10 +2910,10 @@ static Optional<unsigned> getElementForScalarInitOfArg(
29102910
if (!function) return getElementForScalarInitSimple(tupleTy);
29112911

29122912
if (function->hasImplicitSelfDecl()) {
2913-
if (cand.level != 1)
2913+
if (!cand.skipCurriedSelf)
29142914
return getElementForScalarInitSimple(tupleTy);
29152915
} else {
2916-
if (cand.level != 0)
2916+
if (cand.skipCurriedSelf)
29172917
return getElementForScalarInitSimple(tupleTy);
29182918
}
29192919

@@ -2987,7 +2987,7 @@ typeCheckArgumentChildIndependently(Expr *argExpr, Type argType,
29872987
// diagnostics when we don't force the self type down.
29882988
if (argType && !candidates.empty())
29892989
if (auto decl = candidates[0].getDecl())
2990-
if (decl->isInstanceMember() && candidates[0].level == 0 &&
2990+
if (decl->isInstanceMember() && !candidates[0].skipCurriedSelf &&
29912991
!isa<SubscriptDecl>(decl))
29922992
argType = Type();
29932993

@@ -3052,7 +3052,7 @@ typeCheckArgumentChildIndependently(Expr *argExpr, Type argType,
30523052
SmallBitVector defaultMap(params.size());
30533053
if (!candidates.empty()) {
30543054
defaultMap = computeDefaultMap(params, candidates[0].getDecl(),
3055-
candidates[0].level);
3055+
candidates[0].skipCurriedSelf);
30563056
}
30573057

30583058
// Form a set of call arguments, using a dummy type (Void), because the
@@ -3461,14 +3461,15 @@ diagnoseInstanceMethodAsCurriedMemberOnType(CalleeCandidateInfo &CCI,
34613461
// it might be worth while to check if it's instance method as curried
34623462
// member of type problem.
34633463
if (CCI.closeness == CC_ExactMatch &&
3464-
(decl->isInstanceMember() && candidate.level == 1))
3464+
(decl->isInstanceMember() && candidate.skipCurriedSelf))
34653465
continue;
34663466

34673467
auto params = candidate.getParameters();
34683468
// If one of the candidates is an instance method with a single parameter
34693469
// at the level 0, this might be viable situation for calling instance
34703470
// method as curried member of type problem.
3471-
if (params.size() != 1 || !decl->isInstanceMember() || candidate.level > 0)
3471+
if (params.size() != 1 || !decl->isInstanceMember() ||
3472+
candidate.skipCurriedSelf)
34723473
return false;
34733474
}
34743475

@@ -4020,7 +4021,7 @@ diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI, Expr *fnExpr,
40204021
auto params = candidate.getParameters();
40214022

40224023
SmallBitVector defaultMap =
4023-
computeDefaultMap(params, candidate.getDecl(), candidate.level);
4024+
computeDefaultMap(params, candidate.getDecl(), candidate.skipCurriedSelf);
40244025
auto args = decomposeArgType(CCI.CS.getType(argExpr), argLabels);
40254026

40264027
// Check the case where a raw-representable type is constructed from an
@@ -4034,7 +4035,7 @@ diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI, Expr *fnExpr,
40344035
// MyEnumType.foo
40354036
//
40364037
if (params.size() == 1 && args.size() == 1 && candidate.getDecl() &&
4037-
isa<ConstructorDecl>(candidate.getDecl()) && candidate.level == 1) {
4038+
isa<ConstructorDecl>(candidate.getDecl()) && candidate.skipCurriedSelf) {
40384039
AnyFunctionType::Param &arg = args[0];
40394040
auto resTy =
40404041
candidate.getResultType()->lookThroughAllOptionalTypes();
@@ -4145,7 +4146,7 @@ static bool diagnoseRawRepresentableMismatch(CalleeCandidateInfo &CCI,
41454146
auto arguments = decomposeArgType(argType, argLabels);
41464147

41474148
auto bestMatchKind = RawRepresentableMismatch::NotApplicable;
4148-
const UncurriedCandidate *bestMatchCandidate = nullptr;
4149+
const OverloadCandidate *bestMatchCandidate = nullptr;
41494150
KnownProtocolKind bestMatchProtocol;
41504151
size_t bestMatchIndex;
41514152

@@ -4320,7 +4321,7 @@ bool FailureDiagnosis::diagnoseSubscriptErrors(SubscriptExpr *SE,
43204321
// We're about to typecheck the index list, which needs to be processed with
43214322
// self already applied.
43224323
for (unsigned i = 0, e = calleeInfo.size(); i != e; ++i)
4323-
++calleeInfo.candidates[i].level;
4324+
calleeInfo.candidates[i].skipCurriedSelf = true;
43244325

43254326
auto indexExpr =
43264327
typeCheckArgumentChildIndependently(SE->getIndex(), Type(), calleeInfo);
@@ -4329,7 +4330,7 @@ bool FailureDiagnosis::diagnoseSubscriptErrors(SubscriptExpr *SE,
43294330

43304331
// Back to analyzing the candidate list with self applied.
43314332
for (unsigned i = 0, e = calleeInfo.size(); i != e; ++i)
4332-
--calleeInfo.candidates[i].level;
4333+
calleeInfo.candidates[i].skipCurriedSelf = false;
43334334

43344335
ArrayRef<Identifier> argLabels = SE->getArgumentLabels();
43354336
if (diagnoseParameterErrors(calleeInfo, SE, indexExpr, argLabels))
@@ -4340,7 +4341,7 @@ bool FailureDiagnosis::diagnoseSubscriptErrors(SubscriptExpr *SE,
43404341
auto decomposedBaseType = decomposeArgType(baseType, {Identifier()});
43414342
auto decomposedIndexType = decomposeArgType(indexType, argLabels);
43424343
calleeInfo.filterList(
4343-
[&](UncurriedCandidate cand) -> CalleeCandidateInfo::ClosenessResultTy {
4344+
[&](OverloadCandidate cand) -> CalleeCandidateInfo::ClosenessResultTy {
43444345
// Classify how close this match is. Non-subscript decls don't match.
43454346
auto subscriptDecl = dyn_cast_or_null<SubscriptDecl>(cand.getDecl());
43464347
if (!subscriptDecl ||
@@ -4353,9 +4354,8 @@ bool FailureDiagnosis::diagnoseSubscriptErrors(SubscriptExpr *SE,
43534354
CC_ExactMatch)
43544355
selfConstraint = CC_SelfMismatch;
43554356

4356-
// Increase the uncurry level to look past the self argument to the
4357-
// indices.
4358-
cand.level++;
4357+
// Set a flag to look past the self argument to the indices.
4358+
cand.skipCurriedSelf = true;
43594359

43604360
// Explode out multi-index subscripts to find the best match.
43614361
auto indexResult =
@@ -4378,7 +4378,7 @@ bool FailureDiagnosis::diagnoseSubscriptErrors(SubscriptExpr *SE,
43784378

43794379
// Any other failures relate to the index list.
43804380
for (unsigned i = 0, e = calleeInfo.size(); i != e; ++i)
4381-
++calleeInfo.candidates[i].level;
4381+
calleeInfo.candidates[i].skipCurriedSelf = true;
43824382

43834383
// TODO: Is there any reason to check for CC_NonLValueInOut here?
43844384

@@ -4402,7 +4402,7 @@ bool FailureDiagnosis::diagnoseSubscriptErrors(SubscriptExpr *SE,
44024402
// and more concrete expected type for this subscript decl, in order
44034403
// to diagnose a better error.
44044404
if (baseType && indexType->hasUnresolvedType()) {
4405-
UncurriedCandidate cand = calleeInfo.candidates[0];
4405+
auto cand = calleeInfo.candidates[0];
44064406
auto candType = baseType->getTypeOfMember(CS.DC->getParentModule(),
44074407
cand.getDecl(), nullptr);
44084408
if (auto *candFunc = candType->getAs<FunctionType>()) {
@@ -4668,7 +4668,7 @@ bool FailureDiagnosis::diagnoseArgumentGenericRequirements(
46684668

46694669
auto params = candidate.getParameters();
46704670
SmallBitVector defaultMap =
4671-
computeDefaultMap(params, candidate.getDecl(), candidate.level);
4671+
computeDefaultMap(params, candidate.getDecl(), candidate.skipCurriedSelf);
46724672
auto args = decomposeArgType(CS.getType(argExpr), argLabels);
46734673

46744674
SmallVector<ParamBinding, 4> bindings;
@@ -5125,8 +5125,8 @@ bool FailureDiagnosis::diagnoseSubscriptMisuse(ApplyExpr *callExpr) {
51255125
auto params = decomposeArgType(CS.getType(argExpr), argLabels);
51265126
using ClosenessPair = CalleeCandidateInfo::ClosenessResultTy;
51275127

5128-
candidateInfo.filterList([&](UncurriedCandidate cand) -> ClosenessPair {
5129-
auto candFuncType = cand.getUncurriedFunctionType();
5128+
candidateInfo.filterList([&](OverloadCandidate cand) -> ClosenessPair {
5129+
auto candFuncType = cand.getFunctionType();
51305130
if (!candFuncType)
51315131
return {CC_GeneralMismatch, {}};
51325132

@@ -5232,7 +5232,7 @@ static bool isViableOverloadSet(const CalleeCandidateInfo &CCI,
52325232
return true;
52335233
};
52345234

5235-
auto defaultMap = computeDefaultMap(params, funcDecl, cand.level);
5235+
auto defaultMap = computeDefaultMap(params, funcDecl, cand.skipCurriedSelf);
52365236
InputMatcher IM(params, defaultMap);
52375237
auto result = IM.match(numArgs, pairMatcher);
52385238
if (result == InputMatcher::IM_Succeeded)
@@ -5413,7 +5413,7 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
54135413
if (!calleeInfo.empty()) {
54145414
auto &&cand = calleeInfo[0];
54155415
auto decl = cand.getDecl();
5416-
if (decl && decl->isInstanceMember() && cand.level == 0 &&
5416+
if (decl && decl->isInstanceMember() && !cand.skipCurriedSelf &&
54175417
cand.getParameters().size() == 1)
54185418
isInstanceMethodAsCurriedMemberOnType = true;
54195419
}
@@ -5443,7 +5443,7 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
54435443
if (auto fn = fnType->getAs<AnyFunctionType>()) {
54445444
using Closeness = CalleeCandidateInfo::ClosenessResultTy;
54455445

5446-
calleeInfo.filterList([&](UncurriedCandidate candidate) -> Closeness {
5446+
calleeInfo.filterList([&](OverloadCandidate candidate) -> Closeness {
54475447
auto resultType = candidate.getResultType();
54485448
if (!resultType)
54495449
return {CC_GeneralMismatch, {}};
@@ -5679,7 +5679,7 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
56795679
return false;
56805680

56815681
auto candidate = calleeInfo[0];
5682-
auto *fnType = candidate.getUncurriedFunctionType();
5682+
auto *fnType = candidate.getFunctionType();
56835683
if (!fnType)
56845684
return false;
56855685

@@ -7228,7 +7228,7 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
72287228
// expected result type.
72297229
auto resultTy = candidateInfo[0].getResultType();
72307230
if (!resultTy)
7231-
resultTy = candidateInfo[0].getUncurriedType();
7231+
resultTy = candidateInfo[0].getType();
72327232

72337233
if (resultTy && !CS.getContextualType()->is<UnboundGenericType>() &&
72347234
!CS.TC.isConvertibleTo(resultTy, CS.getContextualType(), CS.DC)) {

0 commit comments

Comments
 (0)