Skip to content

Commit 3f5790f

Browse files
committed
Enhance MemberLookupResult's UnviableCandidates list, NFC.
We now store an entire OverloadChoice in the unviable candidates list (which is used for error recovery), just like we store them for viable candidates. The additional information isn't used, so NFC.
1 parent 0670def commit 3f5790f

File tree

4 files changed

+75
-68
lines changed

4 files changed

+75
-68
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,7 +1431,7 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
14311431
ValueDecl *member = nullptr;
14321432
for (auto cand : result.UnviableCandidates) {
14331433
if (member == nullptr)
1434-
member = cand.first;
1434+
member = cand.first.getDecl();
14351435
sameProblem &= cand.second == firstProblem;
14361436
}
14371437

@@ -1537,12 +1537,12 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
15371537
}
15381538

15391539
case MemberLookupResult::UR_Inaccessible: {
1540-
auto decl = result.UnviableCandidates[0].first;
1540+
auto decl = result.UnviableCandidates[0].first.getDecl();
15411541
// FIXME: What if the unviable candidates have different levels of access?
15421542
diagnose(nameLoc, diag::candidate_inaccessible, decl->getBaseName(),
15431543
decl->getFormalAccess());
15441544
for (auto cand : result.UnviableCandidates)
1545-
diagnose(cand.first, diag::decl_declared_here, memberName);
1545+
diagnose(cand.first.getDecl(), diag::decl_declared_here, memberName);
15461546

15471547
return;
15481548
}
@@ -4810,7 +4810,7 @@ bool FailureDiagnosis::diagnoseMethodAttributeFailures(
48104810

48114811
SmallVector<OverloadChoice, 2> choices;
48124812
for (auto &unviable : results.UnviableCandidates)
4813-
choices.push_back(OverloadChoice(baseType, unviable.first,
4813+
choices.push_back(OverloadChoice(baseType, unviable.first.getDecl(),
48144814
UDE->getFunctionRefKind()));
48154815

48164816
CalleeCandidateInfo unviableCandidates(baseType, choices, hasTrailingClosure,

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3572,7 +3572,7 @@ swift::resolveValueMember(DeclContext &DC, Type BaseTy, DeclName Name) {
35723572

35733573
// Keep track of all the unviable members.
35743574
for (auto Can : LookupResult.UnviableCandidates)
3575-
Result.Impl.AllDecls.push_back(Can.first);
3575+
Result.Impl.AllDecls.push_back(Can.first.getDecl());
35763576

35773577
// Keep track of the start of viable choices.
35783578
Result.Impl.ViableStartIdx = Result.Impl.AllDecls.size();

lib/Sema/CSSimplify.cpp

Lines changed: 66 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3089,34 +3089,35 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
30893089

30903090
// Local function that adds the given declaration if it is a
30913091
// reasonable choice.
3092-
auto addChoice = [&](ValueDecl *cand, bool isBridged,
3093-
bool isUnwrappedOptional) {
3092+
auto addChoice = [&](OverloadChoice candidate) {
3093+
auto decl = candidate.getDecl();
3094+
30943095
// If the result is invalid, skip it.
3095-
TC.validateDecl(cand);
3096-
if (cand->isInvalid()) {
3096+
TC.validateDecl(decl);
3097+
if (decl->isInvalid()) {
30973098
result.markErrorAlreadyDiagnosed();
30983099
return;
30993100
}
31003101

31013102
// FIXME: Deal with broken recursion
3102-
if (!cand->hasInterfaceType())
3103+
if (!decl->hasInterfaceType())
31033104
return;
31043105

31053106
// If the argument labels for this result are incompatible with
31063107
// the call site, skip it.
3107-
if (!hasCompatibleArgumentLabels(cand)) {
3108+
if (!hasCompatibleArgumentLabels(decl)) {
31083109
labelMismatch = true;
3109-
result.addUnviable(cand, MemberLookupResult::UR_LabelMismatch);
3110+
result.addUnviable(candidate, MemberLookupResult::UR_LabelMismatch);
31103111
return;
31113112
}
31123113

31133114
// If our base is an existential type, we can't make use of any
31143115
// member whose signature involves associated types.
31153116
if (isExistential) {
3116-
if (auto *proto = cand->getDeclContext()
3117+
if (auto *proto = decl->getDeclContext()
31173118
->getAsProtocolOrProtocolExtensionContext()) {
3118-
if (!proto->isAvailableInExistential(cand)) {
3119-
result.addUnviable(cand,
3119+
if (!proto->isAvailableInExistential(decl)) {
3120+
result.addUnviable(candidate,
31203121
MemberLookupResult::UR_UnavailableInExistential);
31213122
return;
31223123
}
@@ -3126,117 +3127,121 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
31263127
// If the invocation's argument expression has a favored type,
31273128
// use that information to determine whether a specific overload for
31283129
// the candidate should be favored.
3129-
if (isa<ConstructorDecl>(cand) && favoredType &&
3130+
if (isa<ConstructorDecl>(decl) && favoredType &&
31303131
result.FavoredChoice == ~0U) {
31313132
// Only try and favor monomorphic initializers.
3132-
if (auto fnTypeWithSelf = cand->getInterfaceType()
3133-
->getAs<FunctionType>()) {
3134-
if (auto fnType = fnTypeWithSelf->getResult()
3135-
->getAs<FunctionType>()) {
3133+
if (auto fnTypeWithSelf = decl->getInterfaceType()
3134+
->getAs<FunctionType>()) {
3135+
if (auto fnType = fnTypeWithSelf->getResult()->getAs<FunctionType>()) {
31363136
auto argType = fnType->getInput()->getWithoutParens();
3137-
argType = cand->getInnermostDeclContext()
3137+
argType = decl->getInnermostDeclContext()
31383138
->mapTypeIntoContext(argType);
31393139
if (argType->isEqual(favoredType))
3140-
if (!cand->getAttrs().isUnavailable(getASTContext()))
3140+
if (!decl->getAttrs().isUnavailable(getASTContext()))
31413141
result.FavoredChoice = result.ViableCandidates.size();
31423142
}
31433143
}
31443144
}
31453145

31463146
// See if we have an instance method, instance member or static method,
31473147
// and check if it can be accessed on our base type.
3148-
if (cand->isInstanceMember()) {
3149-
if ((isa<FuncDecl>(cand) && !hasInstanceMethods) ||
3150-
(!isa<FuncDecl>(cand) && !hasInstanceMembers)) {
3151-
result.addUnviable(cand, MemberLookupResult::UR_InstanceMemberOnType);
3148+
if (decl->isInstanceMember()) {
3149+
if ((isa<FuncDecl>(decl) && !hasInstanceMethods) ||
3150+
(!isa<FuncDecl>(decl) && !hasInstanceMembers)) {
3151+
result.addUnviable(candidate,
3152+
MemberLookupResult::UR_InstanceMemberOnType);
31523153
return;
31533154
}
31543155

31553156
// If the underlying type of a typealias is fully concrete, it is legal
31563157
// to access the type with a protocol metatype base.
31573158
} else if (isExistential &&
3158-
isa<TypeAliasDecl>(cand) &&
3159-
!cast<TypeAliasDecl>(cand)->getInterfaceType()->getCanonicalType()
3159+
isa<TypeAliasDecl>(decl) &&
3160+
!cast<TypeAliasDecl>(decl)->getInterfaceType()->getCanonicalType()
31603161
->hasTypeParameter()) {
31613162

31623163
/* We're OK */
31633164

31643165
} else {
31653166
if (!hasStaticMembers) {
3166-
result.addUnviable(cand, MemberLookupResult::UR_TypeMemberOnInstance);
3167+
result.addUnviable(candidate,
3168+
MemberLookupResult::UR_TypeMemberOnInstance);
31673169
return;
31683170
}
31693171
}
31703172

31713173
// If we have an rvalue base, make sure that the result isn't 'mutating'
31723174
// (only valid on lvalues).
31733175
if (!isMetatype &&
3174-
!baseTy->is<LValueType>() && cand->isInstanceMember()) {
3175-
if (auto *FD = dyn_cast<FuncDecl>(cand))
3176+
!baseTy->is<LValueType>() && decl->isInstanceMember()) {
3177+
if (auto *FD = dyn_cast<FuncDecl>(decl))
31763178
if (FD->isMutating()) {
3177-
result.addUnviable(cand,
3179+
result.addUnviable(candidate,
31783180
MemberLookupResult::UR_MutatingMemberOnRValue);
31793181
return;
31803182
}
31813183

31823184
// Subscripts and computed properties are ok on rvalues so long
31833185
// as the getter is nonmutating.
3184-
if (auto storage = dyn_cast<AbstractStorageDecl>(cand)) {
3186+
if (auto storage = dyn_cast<AbstractStorageDecl>(decl)) {
31853187
if (storage->isGetterMutating()) {
3186-
result.addUnviable(cand,
3188+
result.addUnviable(candidate,
31873189
MemberLookupResult::UR_MutatingGetterOnRValue);
31883190
return;
31893191
}
31903192
}
31913193
}
31923194

31933195
// If the result's type contains delayed members, we need to force them now.
3194-
if (auto NT = dyn_cast<NominalType>(cand->getInterfaceType().getPointer())) {
3196+
if (auto NT = dyn_cast<NominalType>(decl->getInterfaceType().getPointer())){
31953197
if (auto *NTD = dyn_cast<NominalTypeDecl>(NT->getDecl())) {
31963198
TC.forceExternalDeclMembers(NTD);
31973199
}
31983200
}
31993201

3202+
// Otherwise, we're good, add the candidate to the list.
3203+
result.addViable(candidate);
3204+
};
3205+
3206+
// Local function that turns a ValueDecl into a properly configured
3207+
// OverloadChoice.
3208+
auto getOverloadChoice = [&](ValueDecl *cand, bool isBridged,
3209+
bool isUnwrappedOptional) -> OverloadChoice {
32003210
// If we're looking into an existential type, check whether this
32013211
// result was found via dynamic lookup.
32023212
if (isDynamicLookup) {
32033213
assert(cand->getDeclContext()->isTypeContext() && "Dynamic lookup bug");
3204-
3214+
32053215
// We found this declaration via dynamic lookup, record it as such.
3206-
result.addViable(OverloadChoice::getDeclViaDynamic(baseTy, cand,
3207-
functionRefKind));
3208-
return;
3216+
return OverloadChoice::getDeclViaDynamic(baseTy, cand, functionRefKind);
32093217
}
3210-
3218+
32113219
// If we have a bridged type, we found this declaration via bridging.
3212-
if (isBridged) {
3213-
result.addViable(OverloadChoice::getDeclViaBridge(bridgedType, cand,
3214-
functionRefKind));
3215-
return;
3216-
}
3217-
3220+
if (isBridged)
3221+
return OverloadChoice::getDeclViaBridge(bridgedType, cand,
3222+
functionRefKind);
3223+
32183224
// If we got the choice by unwrapping an optional type, unwrap the base
32193225
// type.
32203226
Type ovlBaseTy = baseTy;
32213227
if (isUnwrappedOptional) {
32223228
ovlBaseTy = MetatypeType::get(baseTy->castTo<MetatypeType>()
3223-
->getInstanceType()
3224-
->getAnyOptionalObjectType());
3225-
result.addViable(
3226-
OverloadChoice::getDeclViaUnwrappedOptional(ovlBaseTy, cand,
3227-
functionRefKind));
3228-
} else {
3229-
result.addViable(OverloadChoice(ovlBaseTy, cand, functionRefKind));
3229+
->getInstanceType()
3230+
->getAnyOptionalObjectType());
3231+
return OverloadChoice::getDeclViaUnwrappedOptional(ovlBaseTy, cand,
3232+
functionRefKind);
32303233
}
3234+
3235+
return OverloadChoice(ovlBaseTy, cand, functionRefKind);
32313236
};
3232-
3237+
32333238
// Add all results from this lookup.
32343239
retry_after_fail:
32353240
labelMismatch = false;
32363241
for (auto result : lookup)
3237-
addChoice(result.getValueDecl(),
3238-
/*isBridged=*/false,
3239-
/*isUnwrappedOptional=*/false);
3242+
addChoice(getOverloadChoice(result.getValueDecl(),
3243+
/*isBridged=*/false,
3244+
/*isUnwrappedOptional=*/false));
32403245

32413246
// If the instance type is a bridged to an Objective-C type, perform
32423247
// a lookup into that Objective-C type.
@@ -3259,9 +3264,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
32593264
continue;
32603265
}
32613266

3262-
addChoice(result.getValueDecl(),
3263-
/*isBridged=*/true,
3264-
/*isUnwrappedOptional=*/false);
3267+
addChoice(getOverloadChoice(result.getValueDecl(),
3268+
/*isBridged=*/true,
3269+
/*isUnwrappedOptional=*/false));
32653270
}
32663271
}
32673272

@@ -3275,9 +3280,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
32753280
if (objectType->mayHaveMembers()) {
32763281
LookupResult &optionalLookup = lookupMember(objectType, memberName);
32773282
for (auto result : optionalLookup)
3278-
addChoice(result.getValueDecl(),
3279-
/*bridged*/false,
3280-
/*isUnwrappedOptional=*/true);
3283+
addChoice(getOverloadChoice(result.getValueDecl(),
3284+
/*bridged*/false,
3285+
/*isUnwrappedOptional=*/true));
32813286
}
32823287
}
32833288
}
@@ -3319,7 +3324,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
33193324
if (!cand->hasInterfaceType())
33203325
continue;
33213326

3322-
result.addUnviable(cand, MemberLookupResult::UR_Inaccessible);
3327+
result.addUnviable(getOverloadChoice(cand, /*isBridged=*/false,
3328+
/*isUnwrappedOptional=*/false),
3329+
MemberLookupResult::UR_Inaccessible);
33233330
}
33243331
}
33253332

lib/Sema/ConstraintSystem.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -849,9 +849,9 @@ struct MemberLookupResult {
849849
UR_Inaccessible,
850850
};
851851

852-
/// This is a list of considered, but rejected, candidates, along with a
852+
/// This is a list of considered (but rejected) candidates, along with a
853853
/// reason for their rejection.
854-
SmallVector<std::pair<ValueDecl*, UnviableReason>, 4> UnviableCandidates;
854+
SmallVector<std::pair<OverloadChoice, UnviableReason>, 4> UnviableCandidates;
855855

856856

857857
/// Mark this as being an already-diagnosed error and return itself.
@@ -864,8 +864,8 @@ struct MemberLookupResult {
864864
ViableCandidates.push_back(candidate);
865865
}
866866

867-
void addUnviable(ValueDecl *VD, UnviableReason reason) {
868-
UnviableCandidates.push_back({VD, reason});
867+
void addUnviable(OverloadChoice candidate, UnviableReason reason) {
868+
UnviableCandidates.push_back({candidate, reason});
869869
}
870870

871871
OverloadChoice *getFavoredChoice() {

0 commit comments

Comments
 (0)