Skip to content

Commit c603ce3

Browse files
authored
Merge pull request #25170 from hamishknight/a-couple-of-tangents
2 parents 1ab0008 + e1f8af2 commit c603ce3

17 files changed

+170
-251
lines changed

include/swift/AST/Decl.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2705,6 +2705,15 @@ class ValueDecl : public Decl {
27052705
/// curried self parameter.
27062706
bool hasCurriedSelf() const;
27072707

2708+
/// Returns true if the declaration has a parameter list associated with it.
2709+
///
2710+
/// Note that not all declarations with function interface types have
2711+
/// parameter lists, for example an enum element without associated values.
2712+
bool hasParameterList() const;
2713+
2714+
/// Returns the number of curry levels in the declaration's interface type.
2715+
unsigned getNumCurryLevels() const;
2716+
27082717
/// Get the decl for this value's opaque result type, if it has one.
27092718
OpaqueTypeDecl *getOpaqueResultTypeDecl() const;
27102719

@@ -7201,6 +7210,21 @@ inline bool ValueDecl::hasCurriedSelf() const {
72017210
return false;
72027211
}
72037212

7213+
inline bool ValueDecl::hasParameterList() const {
7214+
if (auto *eed = dyn_cast<EnumElementDecl>(this))
7215+
return eed->hasAssociatedValues();
7216+
return isa<AbstractFunctionDecl>(this) || isa<SubscriptDecl>(this);
7217+
}
7218+
7219+
inline unsigned ValueDecl::getNumCurryLevels() const {
7220+
unsigned curryLevels = 0;
7221+
if (hasParameterList())
7222+
curryLevels++;
7223+
if (hasCurriedSelf())
7224+
curryLevels++;
7225+
return curryLevels;
7226+
}
7227+
72047228
inline bool Decl::isPotentiallyOverridable() const {
72057229
if (isa<VarDecl>(this) ||
72067230
isa<SubscriptDecl>(this) ||
@@ -7265,7 +7289,7 @@ inline EnumElementDecl *EnumDecl::getUniqueElement(bool hasValue) const {
72657289
}
72667290

72677291
/// Retrieve parameter declaration from the given source at given index.
7268-
const ParamDecl *getParameterAt(ValueDecl *source, unsigned index);
7292+
const ParamDecl *getParameterAt(const ValueDecl *source, unsigned index);
72697293

72707294
/// Display Decl subclasses.
72717295
void simple_display(llvm::raw_ostream &out, const Decl *decl);

lib/AST/Decl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2400,7 +2400,7 @@ CanType ValueDecl::getOverloadSignatureType() const {
24002400
/*topLevelFunction=*/true,
24012401
isMethod,
24022402
/*isInitializer=*/isa<ConstructorDecl>(afd),
2403-
isMethod ? 2 : 1)->getCanonicalType();
2403+
getNumCurryLevels())->getCanonicalType();
24042404
}
24052405

24062406
if (isa<AbstractStorageDecl>(this)) {
@@ -2416,7 +2416,7 @@ CanType ValueDecl::getOverloadSignatureType() const {
24162416
/*topLevelFunction=*/true,
24172417
/*isMethod=*/false,
24182418
/*isInitializer=*/false,
2419-
1)->getCanonicalType();
2419+
getNumCurryLevels())->getCanonicalType();
24202420
}
24212421

24222422
// We want to curry the default signature type with the 'self' type of the
@@ -2430,7 +2430,7 @@ CanType ValueDecl::getOverloadSignatureType() const {
24302430
if (isa<EnumElementDecl>(this)) {
24312431
auto mappedType = mapSignatureFunctionType(
24322432
getASTContext(), getInterfaceType(), /*topLevelFunction=*/false,
2433-
/*isMethod=*/false, /*isInitializer=*/false, /*curryLevels=*/0);
2433+
/*isMethod=*/false, /*isInitializer=*/false, getNumCurryLevels());
24342434
return mappedType->getCanonicalType();
24352435
}
24362436

@@ -6108,7 +6108,7 @@ DeclName AbstractFunctionDecl::getEffectiveFullName() const {
61086108
return DeclName();
61096109
}
61106110

6111-
const ParamDecl *swift::getParameterAt(ValueDecl *source, unsigned index) {
6111+
const ParamDecl *swift::getParameterAt(const ValueDecl *source, unsigned index) {
61126112
const ParameterList *paramList;
61136113
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(source)) {
61146114
paramList = AFD->getParameters();

lib/AST/DeclContext.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -317,14 +317,8 @@ ResilienceExpansion DeclContext::getResilienceExpansion() const {
317317
if (isa<DefaultArgumentInitializer>(dc)) {
318318
dc = dc->getParent();
319319

320-
const ValueDecl *VD;
321-
if (auto *FD = dyn_cast<AbstractFunctionDecl>(dc)) {
322-
VD = FD;
323-
} else if (auto *EED = dyn_cast<EnumElementDecl>(dc)) {
324-
VD = EED;
325-
} else {
326-
VD = cast<SubscriptDecl>(dc);
327-
}
320+
auto *VD = cast<ValueDecl>(dc->getAsDecl());
321+
assert(VD->hasParameterList());
328322

329323
auto access =
330324
VD->getFormalAccessScope(/*useDC=*/nullptr,

lib/AST/Type.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -743,26 +743,26 @@ ParameterListInfo::ParameterListInfo(
743743
if (!paramOwner)
744744
return;
745745

746+
// If the decl has a curried self, but we're not allowed to skip it, return.
747+
if (paramOwner->hasCurriedSelf() && !skipCurriedSelf)
748+
return;
749+
746750
// Find the corresponding parameter list.
747751
const ParameterList *paramList = nullptr;
748752
if (auto *func = dyn_cast<AbstractFunctionDecl>(paramOwner)) {
749-
if (func->hasImplicitSelfDecl()) {
750-
if (skipCurriedSelf)
751-
paramList = func->getParameters();
752-
} else if (!skipCurriedSelf)
753-
paramList = func->getParameters();
753+
paramList = func->getParameters();
754754
} else if (auto *subscript = dyn_cast<SubscriptDecl>(paramOwner)) {
755-
if (skipCurriedSelf)
756-
paramList = subscript->getIndices();
755+
paramList = subscript->getIndices();
757756
} else if (auto *enumElement = dyn_cast<EnumElementDecl>(paramOwner)) {
758-
if (skipCurriedSelf)
759-
paramList = enumElement->getParameterList();
757+
paramList = enumElement->getParameterList();
760758
}
761759

762760
// No parameter list means no default arguments - hand back the zeroed
763761
// bitvector.
764-
if (!paramList)
762+
if (!paramList) {
763+
assert(!paramOwner->hasParameterList());
765764
return;
765+
}
766766

767767
switch (params.size()) {
768768
case 0:

lib/IDE/CodeCompletion.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,7 @@ protocolForLiteralKind(CodeCompletionLiteralKind kind) {
14641464
static bool hasTrivialTrailingClosure(const FuncDecl *FD,
14651465
AnyFunctionType *funcType) {
14661466
ParameterListInfo paramInfo(funcType->getParams(), FD,
1467-
/*level*/ FD->isInstanceMember() ? 1 : 0);
1467+
/*skipCurriedSelf*/ FD->hasCurriedSelf());
14681468

14691469
if (paramInfo.size() - paramInfo.numNonDefaultedParameters() == 1) {
14701470
auto param = funcType->getParams().back();

lib/ParseSIL/ParseSIL.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,18 +2028,9 @@ bool SILParser::parseSILDeclRef(SILDeclRef &Member, bool FnTypeRequired) {
20282028
for (unsigned I = 0, E = values.size(); I < E; I++) {
20292029
auto *decl = values[I];
20302030

2031-
unsigned numArgumentLabels = 0;
2032-
if (auto *eed = dyn_cast<EnumElementDecl>(decl)) {
2033-
numArgumentLabels =
2034-
(eed->hasAssociatedValues() ? 2 : 1);
2035-
} else if (auto *afd = dyn_cast<AbstractFunctionDecl>(decl)) {
2036-
numArgumentLabels =
2037-
(decl->getDeclContext()->isTypeContext() ? 2 : 1);
2038-
}
2039-
20402031
auto lookupTy =
20412032
decl->getInterfaceType()
2042-
->removeArgumentLabels(numArgumentLabels);
2033+
->removeArgumentLabels(decl->getNumCurryLevels());
20432034
if (declTy == lookupTy->getCanonicalType()) {
20442035
TheDecl = decl;
20452036
// Update SILDeclRef to point to the right Decl.

lib/SIL/SILDeclRef.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,10 +1018,10 @@ unsigned SILDeclRef::getParameterListCount() const {
10181018

10191019
auto *vd = getDecl();
10201020

1021-
if (auto *func = dyn_cast<AbstractFunctionDecl>(vd)) {
1022-
return func->hasImplicitSelfDecl() ? 2 : 1;
1023-
} else if (auto *ed = dyn_cast<EnumElementDecl>(vd)) {
1024-
return ed->hasAssociatedValues() ? 2 : 1;
1021+
if (isa<AbstractFunctionDecl>(vd) || isa<EnumElementDecl>(vd)) {
1022+
// For functions and enum elements, the number of parameter lists is the
1023+
// same as in their interface type.
1024+
return vd->getNumCurryLevels();
10251025
} else if (isa<ClassDecl>(vd)) {
10261026
return 2;
10271027
} else if (isa<VarDecl>(vd)) {

lib/Sema/CSDiag.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,8 +2663,7 @@ typeCheckArgumentChildIndependently(Expr *argExpr, Type argType,
26632663
// default arguments.
26642664
ParameterListInfo paramInfo;
26652665
if (!candidates.empty()) {
2666-
paramInfo = ParameterListInfo(params, candidates[0].getDecl(),
2667-
candidates[0].skipCurriedSelf);
2666+
paramInfo = candidates[0].getParameterListInfo(params);
26682667
} else {
26692668
paramInfo = ParameterListInfo(params, nullptr, /*skipCurriedSelf=*/false);
26702669
}
@@ -3550,8 +3549,7 @@ diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI, Expr *fnExpr,
35503549
return false;
35513550

35523551
auto params = candidate.getParameters();
3553-
ParameterListInfo paramInfo(params, candidate.getDecl(),
3554-
candidate.skipCurriedSelf);
3552+
auto paramInfo = candidate.getParameterListInfo(params);
35553553
auto args = decomposeArgType(CCI.CS.getType(argExpr), argLabels);
35563554

35573555
// Check the case where a raw-representable type is constructed from an
@@ -4198,8 +4196,7 @@ bool FailureDiagnosis::diagnoseArgumentGenericRequirements(
41984196
return false;
41994197

42004198
auto params = candidate.getParameters();
4201-
ParameterListInfo paramInfo(params, candidate.getDecl(),
4202-
candidate.skipCurriedSelf);
4199+
auto paramInfo = candidate.getParameterListInfo(params);
42034200
auto args = decomposeArgType(CS.getType(argExpr), argLabels);
42044201

42054202
SmallVector<ParamBinding, 4> bindings;
@@ -4672,7 +4669,7 @@ static bool isViableOverloadSet(const CalleeCandidateInfo &CCI,
46724669
return true;
46734670
};
46744671

4675-
ParameterListInfo paramInfo(params, funcDecl, cand.skipCurriedSelf);
4672+
auto paramInfo = cand.getParameterListInfo(params);
46764673
InputMatcher IM(params, paramInfo);
46774674
auto result = IM.match(numArgs, pairMatcher);
46784675
if (result == InputMatcher::IM_Succeeded)

lib/Sema/CSRanking.cpp

Lines changed: 14 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -367,20 +367,9 @@ static Type getAdjustedParamType(const AnyFunctionType::Param &param) {
367367

368368
// Is a particular parameter of a function or subscript declaration
369369
// declared to be an IUO?
370-
static bool paramIsIUO(Decl *decl, int paramNum) {
371-
if (auto *fn = dyn_cast<AbstractFunctionDecl>(decl)) {
372-
auto *paramList = fn->getParameters();
373-
auto *param = paramList->get(paramNum);
374-
return param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
375-
}
376-
if (auto *ee = dyn_cast<EnumElementDecl>(decl)) {
377-
auto *param = ee->getParameterList()->get(paramNum);
378-
return param->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
379-
}
380-
381-
auto *subscript = cast<SubscriptDecl>(decl);
382-
auto *index = subscript->getIndices()->get(paramNum);
383-
return index->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
370+
static bool paramIsIUO(const ValueDecl *decl, int paramNum) {
371+
return swift::getParameterAt(decl, paramNum)->getAttrs()
372+
.hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
384373
}
385374

386375
/// Determine whether the first declaration is as "specialized" as
@@ -479,30 +468,12 @@ static bool isDeclAsSpecializedAs(TypeChecker &tc, DeclContext *dc,
479468
Type type1 = decl1->getInterfaceType();
480469
Type type2 = decl2->getInterfaceType();
481470

482-
/// What part of the type should we check?
483-
enum {
484-
CheckAll,
485-
CheckInput,
486-
} checkKind;
487-
if (isa<AbstractFunctionDecl>(decl1) || isa<EnumElementDecl>(decl1)) {
488-
// Nothing to do: these have the curried 'self' already.
489-
if (auto elt = dyn_cast<EnumElementDecl>(decl1)) {
490-
checkKind = elt->hasAssociatedValues() ? CheckInput : CheckAll;
491-
} else {
492-
checkKind = CheckInput;
493-
}
494-
} else {
495-
// Add a curried 'self' type.
471+
// Add curried 'self' types if necessary.
472+
if (!decl1->hasCurriedSelf())
496473
type1 = type1->addCurriedSelfType(outerDC1);
497-
type2 = type2->addCurriedSelfType(outerDC2);
498474

499-
// For a subscript declaration, only look at the input type (i.e., the
500-
// indices).
501-
if (isa<SubscriptDecl>(decl1))
502-
checkKind = CheckInput;
503-
else
504-
checkKind = CheckAll;
505-
}
475+
if (!decl2->hasCurriedSelf())
476+
type2 = type2->addCurriedSelfType(outerDC2);
506477

507478
auto openType = [&](ConstraintSystem &cs, DeclContext *innerDC,
508479
DeclContext *outerDC, Type type,
@@ -600,18 +571,16 @@ static bool isDeclAsSpecializedAs(TypeChecker &tc, DeclContext *dc,
600571
}
601572

602573
bool fewerEffectiveParameters = false;
603-
switch (checkKind) {
604-
case CheckAll:
605-
// Check whether the first type is a subtype of the second.
574+
if (!decl1->hasParameterList() && !decl2->hasParameterList()) {
575+
// If neither decl has a parameter list, simply check whether the first
576+
// type is a subtype of the second.
606577
cs.addConstraint(ConstraintKind::Subtype,
607578
openedType1,
608579
openedType2,
609580
locator);
610-
break;
611-
612-
case CheckInput: {
613-
// Check whether the first function type's input is a subtype of the
614-
// second type's inputs, i.e., can we forward the arguments?
581+
} else if (decl1->hasParameterList() && decl2->hasParameterList()) {
582+
// Otherwise, check whether the first function type's input is a subtype
583+
// of the second type's inputs, i.e., can we forward the arguments?
615584
auto funcTy1 = openedType1->castTo<FunctionType>();
616585
auto funcTy2 = openedType2->castTo<FunctionType>();
617586
auto params1 = funcTy1->getParams();
@@ -669,7 +638,7 @@ static bool isDeclAsSpecializedAs(TypeChecker &tc, DeclContext *dc,
669638
};
670639

671640
ParameterListInfo paramInfo(
672-
params2, decl2, decl2->getDeclContext()->isTypeContext());
641+
params2, decl2, decl2->hasCurriedSelf());
673642
auto params2ForMatching = params2;
674643
if (compareTrailingClosureParamsSeparately) {
675644
--numParams1;
@@ -685,9 +654,6 @@ static bool isDeclAsSpecializedAs(TypeChecker &tc, DeclContext *dc,
685654
if (compareTrailingClosureParamsSeparately)
686655
if (!maybeAddSubtypeConstraint(params1.back(), params2.back()))
687656
knownNonSubtype = true;
688-
689-
break;
690-
}
691657
}
692658

693659
if (!knownNonSubtype) {

0 commit comments

Comments
 (0)