@@ -717,6 +717,14 @@ namespace {
717
717
718
718
UncurriedCandidate (ValueDecl *decl, unsigned level)
719
719
: declOrExpr(decl), level(level), entityType(decl->getType ()) {
720
+ // For some reason, subscripts and properties don't include their self
721
+ // type. Tack it on for consistency with other members.
722
+ if (isa<AbstractStorageDecl>(decl)) {
723
+ if (decl->getDeclContext ()->isTypeContext ()) {
724
+ auto instanceTy = decl->getDeclContext ()->getSelfTypeInContext ();
725
+ entityType = FunctionType::get (instanceTy, entityType);
726
+ }
727
+ }
720
728
}
721
729
UncurriedCandidate (Expr *expr)
722
730
: declOrExpr(expr), level(0 ), entityType(expr->getType ()) {
@@ -843,7 +851,8 @@ namespace {
843
851
}
844
852
845
853
CalleeCandidateInfo (Type baseType, ArrayRef<OverloadChoice> candidates,
846
- bool hasTrailingClosure, ConstraintSystem *CS);
854
+ bool hasTrailingClosure, ConstraintSystem *CS,
855
+ bool selfAlreadyApplied = true );
847
856
848
857
typedef std::pair<CandidateCloseness, FailedArgumentInfo> ClosenessResultTy;
849
858
typedef const std::function<ClosenessResultTy(UncurriedCandidate)>
@@ -852,8 +861,9 @@ namespace {
852
861
// / After the candidate list is formed, it can be filtered down to discard
853
862
// / obviously mismatching candidates and compute a "closeness" for the
854
863
// / resultant set.
855
- std::pair<CandidateCloseness, CalleeCandidateInfo::FailedArgumentInfo>
856
- evaluateCloseness (DeclContext *dc, Type candArgListType, ArrayRef<CallArgParam> actualArgs);
864
+ ClosenessResultTy
865
+ evaluateCloseness (DeclContext *dc, Type candArgListType,
866
+ ArrayRef<CallArgParam> actualArgs);
857
867
858
868
void filterList (ArrayRef<CallArgParam> actualArgs);
859
869
void filterList (Type actualArgsType) {
@@ -1063,9 +1073,9 @@ static bool findGenericSubstitutions(DeclContext *dc, Type paramType,
1063
1073
// / Determine how close an argument list is to an already decomposed argument
1064
1074
// / list. If the closeness is a miss by a single argument, then this returns
1065
1075
// / information about that failure.
1066
- std::pair<CandidateCloseness, CalleeCandidateInfo::FailedArgumentInfo>
1076
+ CalleeCandidateInfo::ClosenessResultTy
1067
1077
CalleeCandidateInfo::evaluateCloseness (DeclContext *dc, Type candArgListType,
1068
- ArrayRef<CallArgParam> actualArgs) {
1078
+ ArrayRef<CallArgParam> actualArgs) {
1069
1079
auto candArgs = decomposeArgParamType (candArgListType);
1070
1080
1071
1081
struct OurListener : public MatchCallArgumentListener {
@@ -1156,7 +1166,7 @@ CalleeCandidateInfo::evaluateCloseness(DeclContext *dc, Type candArgListType,
1156
1166
// against the type contained therein.
1157
1167
if (paramType->is <InOutType>() && argType->is <LValueType>())
1158
1168
matchType = matchType->getInOutObjectType ();
1159
- matched = findGenericSubstitutions (dc, matchType , rArgType,
1169
+ matched = findGenericSubstitutions (dc, matchType, rArgType,
1160
1170
archetypesMap);
1161
1171
}
1162
1172
@@ -1513,12 +1523,13 @@ void CalleeCandidateInfo::filterContextualMemberList(Expr *argExpr) {
1513
1523
CalleeCandidateInfo::CalleeCandidateInfo (Type baseType,
1514
1524
ArrayRef<OverloadChoice> overloads,
1515
1525
bool hasTrailingClosure,
1516
- ConstraintSystem *CS)
1526
+ ConstraintSystem *CS,
1527
+ bool selfAlreadyApplied)
1517
1528
: CS(CS), hasTrailingClosure(hasTrailingClosure) {
1518
1529
1519
1530
// If we have a useful base type for the candidate set, we'll want to
1520
1531
// substitute it into each member. If not, ignore it.
1521
- if (isUnresolvedOrTypeVarType (baseType))
1532
+ if (baseType && isUnresolvedOrTypeVarType (baseType))
1522
1533
baseType = Type ();
1523
1534
1524
1535
for (auto cand : overloads) {
@@ -1527,10 +1538,10 @@ CalleeCandidateInfo::CalleeCandidateInfo(Type baseType,
1527
1538
auto decl = cand.getDecl ();
1528
1539
1529
1540
// If this is a method or enum case member (not a var or subscript), then
1530
- // the uncurry level is 1.
1541
+ // the uncurry level is 1 if self has already been applied .
1531
1542
unsigned uncurryLevel = 0 ;
1532
- if (!isa<AbstractStorageDecl>(decl ) &&
1533
- decl-> getDeclContext ()-> isTypeContext () )
1543
+ if (decl-> getDeclContext ()-> isTypeContext ( ) &&
1544
+ selfAlreadyApplied )
1534
1545
uncurryLevel = 1 ;
1535
1546
1536
1547
candidates.push_back ({ decl, uncurryLevel });
@@ -1561,7 +1572,7 @@ CalleeCandidateInfo::CalleeCandidateInfo(Type baseType,
1561
1572
substType = Type ();
1562
1573
}
1563
1574
1564
- if (substType)
1575
+ if (substType && selfAlreadyApplied )
1565
1576
substType = substType->getTypeOfMember (CS->DC ->getParentModule (),
1566
1577
decl, nullptr );
1567
1578
if (substType)
@@ -3913,8 +3924,6 @@ bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI,
3913
3924
3914
3925
3915
3926
bool FailureDiagnosis::visitSubscriptExpr (SubscriptExpr *SE) {
3916
- // FIXME: Why isn't this passing TCC_AllowLValue? It seems that this could
3917
- // cause problems with subscripts that have mutating getters.
3918
3927
auto baseExpr = typeCheckChildIndependently (SE->getBase ());
3919
3928
if (!baseExpr) return true ;
3920
3929
auto baseType = baseExpr->getType ();
@@ -3951,19 +3960,30 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) {
3951
3960
3952
3961
3953
3962
3954
- CalleeCandidateInfo calleeInfo (baseType , result.ViableCandidates ,
3963
+ CalleeCandidateInfo calleeInfo (Type () , result.ViableCandidates ,
3955
3964
/* FIXME: Subscript trailing closures*/
3956
- /* hasTrailingClosure*/ false , CS);
3965
+ /* hasTrailingClosure*/ false , CS,
3966
+ /* selfAlreadyApplied*/ false );
3957
3967
3968
+ // We're about to typecheck the index list, which needs to be processed with
3969
+ // self already applied.
3970
+ for (unsigned i = 0 , e = calleeInfo.size (); i != e; ++i)
3971
+ ++calleeInfo.candidates [i].level ;
3972
+
3958
3973
auto indexExpr = typeCheckArgumentChildIndependently (SE->getIndex (),
3959
3974
Type (), calleeInfo);
3960
3975
if (!indexExpr) return true ;
3961
3976
3977
+ // Back to analyzing the candidate list with self applied.
3978
+ for (unsigned i = 0 , e = calleeInfo.size (); i != e; ++i)
3979
+ --calleeInfo.candidates [i].level ;
3980
+
3962
3981
if (diagnoseParameterErrors (calleeInfo, SE, indexExpr))
3963
3982
return true ;
3964
3983
3965
3984
auto indexType = indexExpr->getType ();
3966
3985
3986
+ auto decomposedBaseType = decomposeArgParamType (baseType);
3967
3987
auto decomposedIndexType = decomposeArgParamType (indexType);
3968
3988
calleeInfo.filterList ([&](UncurriedCandidate cand) ->
3969
3989
CalleeCandidateInfo::ClosenessResultTy
@@ -3972,31 +3992,40 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) {
3972
3992
auto *SD = dyn_cast_or_null<SubscriptDecl>(cand.getDecl ());
3973
3993
if (!SD) return { CC_GeneralMismatch, {}};
3974
3994
3975
- // Check to make sure the base expr type is convertible to the expected base
3976
- // type. We check either the getter, or if it isn't present, the addressor.
3995
+ // Check whether the self type matches.
3977
3996
auto selfConstraint = CC_ExactMatch;
3978
- auto getter = SD->getGetter ();
3979
- if (!getter) getter = SD->getAddressor ();
3980
-
3981
- auto instanceTy =
3982
- getter->getImplicitSelfDecl ()->getType ()->getInOutObjectType ();
3983
- if (!isUnresolvedOrTypeVarType (baseType) &&
3984
- // TODO: We're not handling archetypes well here.
3985
- !instanceTy->hasArchetype () &&
3986
- !CS->TC .isConvertibleTo (baseType, instanceTy, CS->DC )) {
3997
+ if (calleeInfo.evaluateCloseness (SD->getInnermostDeclContext (),
3998
+ cand.getArgumentType (), decomposedBaseType)
3999
+ .first != CC_ExactMatch)
3987
4000
selfConstraint = CC_SelfMismatch;
3988
- }
4001
+
4002
+ // Increase the uncurry level to look past the self argument to the indices.
4003
+ cand.level ++;
3989
4004
3990
4005
// Explode out multi-index subscripts to find the best match.
3991
- Decl *decl = cand.getDecl ();
3992
4006
auto indexResult =
3993
- calleeInfo.evaluateCloseness (decl ? decl ->getInnermostDeclContext () : nullptr ,
4007
+ calleeInfo.evaluateCloseness (SD ->getInnermostDeclContext (),
3994
4008
cand.getArgumentType (), decomposedIndexType);
3995
4009
if (selfConstraint > indexResult.first )
3996
4010
return {selfConstraint, {}};
3997
4011
return indexResult;
3998
4012
});
3999
4013
4014
+ // If the closest matches all mismatch on self, we either have something that
4015
+ // cannot be subscripted, or an ambiguity.
4016
+ if (calleeInfo.closeness == CC_SelfMismatch) {
4017
+ diagnose (SE->getLoc (), diag::cannot_subscript_base, baseType)
4018
+ .highlight (SE->getBase ()->getSourceRange ());
4019
+ // FIXME: Should suggest overload set, but we're not ready for that until
4020
+ // it points to candidates and identifies the self type in the diagnostic.
4021
+ // calleeInfo.suggestPotentialOverloads(SE->getLoc());
4022
+ return true ;
4023
+ }
4024
+
4025
+ // Any other failures relate to the index list.
4026
+ for (unsigned i = 0 , e = calleeInfo.size (); i != e; ++i)
4027
+ ++calleeInfo.candidates [i].level ;
4028
+
4000
4029
// TODO: Is there any reason to check for CC_NonLValueInOut here?
4001
4030
4002
4031
if (calleeInfo.closeness == CC_ExactMatch) {
@@ -4028,16 +4057,6 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) {
4028
4057
if (calleeInfo.diagnoseSimpleErrors (SE->getLoc ()))
4029
4058
return true ;
4030
4059
4031
- // If the closest matches all mismatch on self, we either have something that
4032
- // cannot be subscripted, or an ambiguity.
4033
- if (calleeInfo.closeness == CC_SelfMismatch) {
4034
- diagnose (SE->getLoc (), diag::cannot_subscript_base, baseType)
4035
- .highlight (SE->getBase ()->getSourceRange ());
4036
- // FIXME: Should suggest overload set, but we're not ready for that until
4037
- // it points to candidates and identifies the self type in the diagnostic.
4038
- // calleeInfo.suggestPotentialOverloads(SE->getLoc());
4039
- return true ;
4040
- }
4041
4060
4042
4061
diagnose (SE->getLoc (), diag::cannot_subscript_with_index,
4043
4062
baseType, indexType);
@@ -5067,7 +5086,7 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
5067
5086
bool hasTrailingClosure = callArgHasTrailingClosure (E->getArgument ());
5068
5087
5069
5088
// Dump all of our viable candidates into a CalleeCandidateInfo & sort it out.
5070
- CalleeCandidateInfo candidateInfo (baseObjTy , result.ViableCandidates ,
5089
+ CalleeCandidateInfo candidateInfo (Type () , result.ViableCandidates ,
5071
5090
hasTrailingClosure, CS);
5072
5091
5073
5092
// Filter the candidate list based on the argument we may or may not have.
@@ -5189,6 +5208,7 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
5189
5208
llvm_unreachable (" all cases should be handled" );
5190
5209
}
5191
5210
5211
+
5192
5212
// / A TupleExpr propagate contextual type information down to its children and
5193
5213
// / can be erroneous when there is a label mismatch etc.
5194
5214
bool FailureDiagnosis::visitTupleExpr (TupleExpr *TE) {
0 commit comments