Skip to content

Commit 1265f2e

Browse files
committed
[Diagnostics] Replace curry level with a boolean flag
Since arbitrary currying is no longer allowed `level` could be replaced with the boolean flag which identifies if curried `self` should be skipped or not.
1 parent b5f3829 commit 1265f2e

File tree

2 files changed

+42
-44
lines changed

2 files changed

+42
-44
lines changed

lib/Sema/CalleeCandidateInfo.cpp

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ static bool isSubstitutableFor(Type type, ArchetypeType *archetype,
5656
return true;
5757
}
5858

59-
UncurriedCandidate::UncurriedCandidate(ValueDecl *decl, unsigned level)
60-
: declOrExpr(decl), level(level), substituted(false) {
59+
UncurriedCandidate::UncurriedCandidate(ValueDecl *decl, bool skipCurriedSelf)
60+
: declOrExpr(decl), skipCurriedSelf(skipCurriedSelf), substituted(false) {
6161

6262
if (auto *PD = dyn_cast<ParamDecl>(decl)) {
6363
if (PD->hasValidSignature())
@@ -95,15 +95,15 @@ ArrayRef<Identifier> UncurriedCandidate::getArgumentLabels(
9595
if (auto decl = getDecl()) {
9696
if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
9797
if (func->hasImplicitSelfDecl()) {
98-
if (level == 0) {
98+
if (!skipCurriedSelf) {
9999
scratch.push_back(Identifier());
100100
return scratch;
101101
}
102102

103-
--level;
103+
skipCurriedSelf = false;
104104
}
105105

106-
if (level == 0) {
106+
if (!skipCurriedSelf) {
107107
// Retrieve the argument labels of the corresponding parameter list.
108108
for (auto param : *func->getParameters()) {
109109
scratch.push_back(param->getArgumentName());
@@ -112,20 +112,18 @@ ArrayRef<Identifier> UncurriedCandidate::getArgumentLabels(
112112
}
113113
} else if (auto enumElt = dyn_cast<EnumElementDecl>(decl)) {
114114
// 'self'
115-
if (level == 0) {
115+
if (!skipCurriedSelf) {
116116
scratch.push_back(Identifier());
117117
return scratch;
118118
}
119119

120120
// The associated data of the case.
121-
if (level == 1) {
122-
auto *paramList = enumElt->getParameterList();
123-
if (!paramList) return { };
124-
for (auto param : *paramList) {
125-
scratch.push_back(param->getArgumentName());
126-
}
127-
return scratch;
121+
auto *paramList = enumElt->getParameterList();
122+
if (!paramList) return { };
123+
for (auto param : *paramList) {
124+
scratch.push_back(param->getArgumentName());
128125
}
126+
return scratch;
129127
}
130128
}
131129

@@ -143,7 +141,8 @@ void UncurriedCandidate::dump() const {
143141
decl->dumpRef(llvm::errs());
144142
else
145143
llvm::errs() << "<<EXPR>>";
146-
llvm::errs() << " - uncurry level " << level;
144+
llvm::errs() << " - ignore curried self = " << (skipCurriedSelf ? "yes"
145+
: "no");
147146

148147
if (auto FT = getUncurriedFunctionType())
149148
llvm::errs() << " - type: " << Type(FT) << "\n";
@@ -322,7 +321,7 @@ CalleeCandidateInfo::evaluateCloseness(UncurriedCandidate candidate,
322321

323322
auto candArgs = candidate.getParameters();
324323
SmallBitVector candDefaultMap =
325-
computeDefaultMap(candArgs, candidate.getDecl(), candidate.level);
324+
computeDefaultMap(candArgs, candidate.getDecl(), candidate.skipCurriedSelf);
326325

327326
struct OurListener : public MatchCallArgumentListener {
328327
CandidateCloseness result = CC_ExactMatch;
@@ -589,28 +588,27 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
589588
/*implicitDotSyntax=*/false);
590589
}
591590

592-
// Determine the callee level for a "bare" reference to the given
593-
// declaration.
594-
auto getCalleeLevel = [implicitDotSyntax](ValueDecl *decl) -> unsigned {
591+
// Determine if we need to skip "self" to get to a "bare" reference.
592+
auto skipCurriedSelf = [implicitDotSyntax](ValueDecl *decl) -> bool {
595593
if (auto func = dyn_cast<FuncDecl>(decl)) {
596594
if (func->isOperator() && func->getDeclContext()->isTypeContext() &&
597595
!implicitDotSyntax)
598-
return 1;
596+
return true;
599597
}
600598

601-
return 0;
599+
return false;
602600
};
603601

604602
if (auto declRefExpr = dyn_cast<DeclRefExpr>(fn)) {
605603
auto decl = declRefExpr->getDecl();
606-
candidates.push_back({ decl, getCalleeLevel(decl) });
604+
candidates.push_back({ decl, skipCurriedSelf(decl) });
607605
declName = decl->getBaseName().userFacingName();
608606
return;
609607
}
610608

611609
if (auto declRefExpr = dyn_cast<OtherConstructorDeclRefExpr>(fn)) {
612610
auto decl = declRefExpr->getDecl();
613-
candidates.push_back({ decl, getCalleeLevel(decl) });
611+
candidates.push_back({ decl, skipCurriedSelf(decl) });
614612

615613
if (auto selfTy = decl->getDeclContext()->getSelfInterfaceType())
616614
declName = selfTy.getString() + ".init";
@@ -621,7 +619,7 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
621619

622620
if (auto overloadedDRE = dyn_cast<OverloadedDeclRefExpr>(fn)) {
623621
for (auto cand : overloadedDRE->getDecls()) {
624-
candidates.push_back({ cand, getCalleeLevel(cand) });
622+
candidates.push_back({ cand, skipCurriedSelf(cand) });
625623
}
626624

627625
if (!candidates.empty())
@@ -671,12 +669,13 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
671669
baseType = CS.getType(AE->getArg())->getWithoutSpecifierType();
672670

673671
for (auto &C : candidates) {
674-
C.level += 1;
672+
bool hadCurriedSelf = C.skipCurriedSelf;
675673

674+
C.skipCurriedSelf = true;
676675
baseType = replaceTypeVariablesWithUnresolved(baseType);
677676

678677
// Compute a new substituted type if we have a base type to apply.
679-
if (baseType && C.level == 1 && C.getDecl()) {
678+
if (baseType && !hadCurriedSelf && C.getDecl()) {
680679
baseType = baseType
681680
->getWithoutSpecifierType()
682681
->getMetatypeInstanceType();
@@ -691,7 +690,7 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
691690
}
692691
}
693692
}
694-
693+
695694
return;
696695
}
697696
}
@@ -709,36 +708,35 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
709708

710709
// Otherwise, we couldn't tell structurally what is going on here, so try to
711710
// dig something out of the constraint system.
712-
unsigned uncurryLevel = 0;
711+
bool hasCurriedSelf = false;
713712

714713
// The candidate list of an unresolved_dot_expr is the candidate list of the
715714
// base uncurried by one level, and we refer to the name of the member, not to
716715
// the name of any base.
717716
if (auto UDE = dyn_cast<UnresolvedDotExpr>(fn)) {
718717
declName = UDE->getName().getBaseName().userFacingName();
719-
uncurryLevel = 1;
718+
hasCurriedSelf = true;
720719

721720
// If base is a module or metatype, this is just a simple
722721
// reference so its curry level should be 0.
723722
if (auto *DRE = dyn_cast<DeclRefExpr>(UDE->getBase())) {
724723
if (auto baseType = DRE->getType())
725-
uncurryLevel =
726-
(baseType->is<ModuleType>() || baseType->is<AnyMetatypeType>()) ? 0
727-
: 1;
724+
hasCurriedSelf = !(baseType->is<ModuleType>() ||
725+
baseType->is<AnyMetatypeType>());
728726
}
729727

730728
// If we actually resolved the member to use, return it.
731729
auto loc = CS.getConstraintLocator(UDE, ConstraintLocator::Member);
732730
if (auto *member = CS.findResolvedMemberRef(loc)) {
733-
candidates.push_back({ member, uncurryLevel });
731+
candidates.push_back({ member, hasCurriedSelf });
734732
return;
735733
}
736734

737735
// If we resolved the constructor member, return it.
738736
auto ctorLoc =
739737
CS.getConstraintLocator(UDE, ConstraintLocator::ConstructorMember);
740738
if (auto *member = CS.findResolvedMemberRef(ctorLoc)) {
741-
candidates.push_back({ member, uncurryLevel });
739+
candidates.push_back({ member, hasCurriedSelf });
742740
return;
743741
}
744742

@@ -754,7 +752,7 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
754752
}
755753

756754
if (isa<MemberRefExpr>(fn))
757-
uncurryLevel = 1;
755+
hasCurriedSelf = true;
758756

759757
// Scan to see if we have a disjunction constraint for this callee.
760758
for (auto &constraint : CS.getConstraints()) {
@@ -768,7 +766,7 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
768766
continue;
769767
auto c = bindOverload->getOverloadChoice();
770768
if (c.isDecl())
771-
candidates.push_back({ c.getDecl(), uncurryLevel });
769+
candidates.push_back({ c.getDecl(), hasCurriedSelf });
772770
}
773771

774772
// If we found some candidates, then we're done.
@@ -865,13 +863,13 @@ CalleeCandidateInfo::CalleeCandidateInfo(Type baseType,
865863
auto decl = cand.getDecl();
866864

867865
// If this is a method or enum case member (not a var or subscript), then
868-
// the uncurry level is 1 if self has already been applied.
869-
unsigned uncurryLevel = 0;
866+
// we need to skip `self` if it has already been applied.
867+
bool hasCurriedSelf = false;
870868
if (decl->getDeclContext()->isTypeContext() &&
871869
selfAlreadyApplied && !isa<SubscriptDecl>(decl))
872-
uncurryLevel = 1;
870+
hasCurriedSelf = true;
873871

874-
candidates.push_back({ decl, uncurryLevel });
872+
candidates.push_back({ decl, hasCurriedSelf });
875873

876874
// If we have a base type for this member, try to perform substitutions into
877875
// it to get a simpler and more concrete type.

lib/Sema/CalleeCandidateInfo.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ namespace swift {
5959
///
6060
struct UncurriedCandidate {
6161
PointerUnion<ValueDecl *, Expr*> declOrExpr;
62-
unsigned level;
62+
bool skipCurriedSelf;
6363
Type entityType;
6464

6565
// If true, entityType is written in terms of caller archetypes,
@@ -71,9 +71,10 @@ namespace swift {
7171
// FIXME: Clean this up.
7272
bool substituted;
7373

74-
UncurriedCandidate(ValueDecl *decl, unsigned level);
74+
UncurriedCandidate(ValueDecl *decl, bool skipCurriedSelf);
7575
UncurriedCandidate(Expr *expr, Type type)
76-
: declOrExpr(expr), level(0), entityType(type), substituted(true) {}
76+
: declOrExpr(expr), skipCurriedSelf(false), entityType(type),
77+
substituted(true) {}
7778

7879
ValueDecl *getDecl() const {
7980
return declOrExpr.dyn_cast<ValueDecl*>();
@@ -86,12 +87,11 @@ namespace swift {
8687
Type getUncurriedType() const {
8788
// Start with the known type of the decl.
8889
auto type = entityType;
89-
for (unsigned i = 0, e = level; i != e; ++i) {
90+
if (skipCurriedSelf) {
9091
auto funcTy = type->getAs<AnyFunctionType>();
9192
if (!funcTy) return Type();
9293
type = funcTy->getResult();
9394
}
94-
9595
return type;
9696
}
9797

0 commit comments

Comments
 (0)