mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ConstraintSystem] Split unviable lookup result storage into candidates & reasons
That makes it easy to process unviable choices the same way as viable ones and request rejection reasons only when necessary.
This commit is contained in:
@@ -791,15 +791,19 @@ void FailureDiagnosis::diagnoseUnviableLookupResults(
|
||||
// Otherwise, we have at least one (and potentially many) viable candidates
|
||||
// sort them out. If all of the candidates have the same problem (commonly
|
||||
// because there is exactly one candidate!) diagnose this.
|
||||
bool sameProblem = true;
|
||||
auto firstProblem = result.UnviableCandidates[0].second;
|
||||
auto firstProblem = result.UnviableReasons[0];
|
||||
bool sameProblem = llvm::all_of(
|
||||
result.UnviableReasons,
|
||||
[&firstProblem](const MemberLookupResult::UnviableReason &problem) {
|
||||
return problem == firstProblem;
|
||||
});
|
||||
|
||||
ValueDecl *member = nullptr;
|
||||
for (auto cand : result.UnviableCandidates) {
|
||||
if (member == nullptr)
|
||||
member = cand.first.getDecl();
|
||||
sameProblem &= cand.second == firstProblem;
|
||||
member = cand.getDecl();
|
||||
}
|
||||
|
||||
|
||||
auto instanceTy = baseObjTy;
|
||||
if (auto *MTT = instanceTy->getAs<AnyMetatypeType>())
|
||||
instanceTy = MTT->getInstanceType();
|
||||
@@ -842,7 +846,7 @@ void FailureDiagnosis::diagnoseUnviableLookupResults(
|
||||
}
|
||||
|
||||
case MemberLookupResult::UR_Inaccessible: {
|
||||
auto decl = result.UnviableCandidates[0].first.getDecl();
|
||||
auto decl = result.UnviableCandidates[0].getDecl();
|
||||
// FIXME: What if the unviable candidates have different levels of access?
|
||||
//
|
||||
// If we found an inaccessible member of a protocol extension, it might
|
||||
@@ -853,8 +857,8 @@ void FailureDiagnosis::diagnoseUnviableLookupResults(
|
||||
diagnose(nameLoc, diag::candidate_inaccessible, decl->getBaseName(),
|
||||
decl->getFormalAccessScope().accessLevelForDiagnostics());
|
||||
for (auto cand : result.UnviableCandidates)
|
||||
diagnose(cand.first.getDecl(), diag::decl_declared_here, memberName);
|
||||
|
||||
diagnose(cand.getDecl(), diag::decl_declared_here, memberName);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -4206,7 +4210,7 @@ bool FailureDiagnosis::diagnoseMethodAttributeFailures(
|
||||
|
||||
SmallVector<OverloadChoice, 2> choices;
|
||||
for (auto &unviable : results.UnviableCandidates)
|
||||
choices.push_back(OverloadChoice(baseType, unviable.first.getDecl(),
|
||||
choices.push_back(OverloadChoice(baseType, unviable.getDecl(),
|
||||
UDE->getFunctionRefKind()));
|
||||
|
||||
CalleeCandidateInfo unviableCandidates(baseType, choices, hasTrailingClosure,
|
||||
|
||||
@@ -3719,7 +3719,7 @@ swift::resolveValueMember(DeclContext &DC, Type BaseTy, DeclName Name) {
|
||||
|
||||
// Keep track of all the unviable members.
|
||||
for (auto Can : LookupResult.UnviableCandidates)
|
||||
Result.Impl.AllDecls.push_back(Can.first.getDecl());
|
||||
Result.Impl.AllDecls.push_back(Can.getDecl());
|
||||
|
||||
// Keep track of the start of viable choices.
|
||||
Result.Impl.ViableStartIdx = Result.Impl.AllDecls.size();
|
||||
|
||||
@@ -3933,10 +3933,10 @@ retry_after_fail:
|
||||
result.addViable(
|
||||
OverloadChoice::getDynamicMemberLookup(baseTy, decl, name));
|
||||
}
|
||||
for (auto candidate : subscripts.UnviableCandidates) {
|
||||
auto decl = candidate.first.getDecl();
|
||||
for (auto index : indices(subscripts.UnviableCandidates)) {
|
||||
auto decl = subscripts.UnviableCandidates[index].getDecl();
|
||||
auto choice = OverloadChoice::getDynamicMemberLookup(baseTy, decl,name);
|
||||
result.addUnviable(choice, candidate.second);
|
||||
result.addUnviable(choice, subscripts.UnviableReasons[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4232,21 +4232,15 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
|
||||
}
|
||||
|
||||
if (!result.UnviableCandidates.empty()) {
|
||||
SmallVector<OverloadChoice, 8> choices;
|
||||
llvm::transform(
|
||||
result.UnviableCandidates, std::back_inserter(choices),
|
||||
[](const std::pair<OverloadChoice, MemberLookupResult::UnviableReason>
|
||||
&candidate) { return candidate.first; });
|
||||
|
||||
// Generate constraints for unvailable choices if they have a fix,
|
||||
// and disable them by default, they'd get picked up in the "salvage" mode.
|
||||
generateConstraints(candidates, memberTy, choices, useDC, locator,
|
||||
/*favoredChoice=*/None, /*requiresFix=*/true,
|
||||
[&](unsigned idx, const OverloadChoice &choice) {
|
||||
return fixMemberRef(
|
||||
*this, baseTy, member, choice, locator,
|
||||
result.UnviableCandidates[idx].second);
|
||||
});
|
||||
generateConstraints(
|
||||
candidates, memberTy, result.UnviableCandidates, useDC, locator,
|
||||
/*favoredChoice=*/None, /*requiresFix=*/true,
|
||||
[&](unsigned idx, const OverloadChoice &choice) {
|
||||
return fixMemberRef(*this, baseTy, member, choice, locator,
|
||||
result.UnviableReasons[idx]);
|
||||
});
|
||||
}
|
||||
|
||||
if (!candidates.empty()) {
|
||||
|
||||
@@ -873,11 +873,12 @@ struct MemberLookupResult {
|
||||
/// The member is inaccessible (e.g. a private member in another file).
|
||||
UR_Inaccessible,
|
||||
};
|
||||
|
||||
/// This is a list of considered (but rejected) candidates, along with a
|
||||
/// reason for their rejection.
|
||||
SmallVector<std::pair<OverloadChoice, UnviableReason>, 4> UnviableCandidates;
|
||||
|
||||
/// This is a list of considered (but rejected) candidates, along with a
|
||||
/// reason for their rejection. Split into separate collections to make
|
||||
/// it easier to use in conjunction with viable candidates.
|
||||
SmallVector<OverloadChoice, 4> UnviableCandidates;
|
||||
SmallVector<UnviableReason, 4> UnviableReasons;
|
||||
|
||||
/// Mark this as being an already-diagnosed error and return itself.
|
||||
MemberLookupResult &markErrorAlreadyDiagnosed() {
|
||||
@@ -890,7 +891,8 @@ struct MemberLookupResult {
|
||||
}
|
||||
|
||||
void addUnviable(OverloadChoice candidate, UnviableReason reason) {
|
||||
UnviableCandidates.push_back({candidate, reason});
|
||||
UnviableCandidates.push_back(candidate);
|
||||
UnviableReasons.push_back(reason);
|
||||
}
|
||||
|
||||
Optional<unsigned> getFavoredIndex() const {
|
||||
|
||||
Reference in New Issue
Block a user