Skip to content

Commit ad52afa

Browse files
committed
[ConstraintSystem] Add pair-wise differentiation of key path dynamic member overloads
Single type of keypath dynamic member lookup could refer to different member overlaods, we have to do a pair-wise comparison in such cases otherwise ranking would miss some viable information e.g. `_ = arr[0..<3]` could refer to subscript through writable or read-only key path and each of them could also pick overload which returns `Slice<T>` or `ArraySlice<T>` (assuming that `arr` is something like `Box<[Int]>`).
1 parent c3153e0 commit ad52afa

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,35 @@ static Type getUnlabeledType(Type type, ASTContext &ctx) {
708708
});
709709
}
710710

711+
static void addKeyPathDynamicMemberOverloads(
712+
ArrayRef<Solution> solutions, unsigned idx1, unsigned idx2,
713+
SmallVectorImpl<SolutionDiff::OverloadDiff> &overloadDiff) {
714+
const auto &overloads1 = solutions[idx1].overloadChoices;
715+
const auto &overloads2 = solutions[idx2].overloadChoices;
716+
717+
for (auto &entry : overloads1) {
718+
auto *locator = entry.first;
719+
if (!locator->isForKeyPathDynamicMemberLookup())
720+
continue;
721+
722+
auto overload2 = overloads2.find(locator);
723+
if (overload2 == overloads2.end())
724+
continue;
725+
726+
auto &overloadChoice1 = entry.second.choice;
727+
auto &overloadChoice2 = overload2->second.choice;
728+
729+
SmallVector<OverloadChoice, 4> choices;
730+
choices.resize(solutions.size());
731+
732+
choices[idx1] = overloadChoice1;
733+
choices[idx2] = overloadChoice2;
734+
735+
overloadDiff.push_back(
736+
SolutionDiff::OverloadDiff{locator, std::move(choices)});
737+
}
738+
}
739+
711740
SolutionCompareResult ConstraintSystem::compareSolutions(
712741
ConstraintSystem &cs, ArrayRef<Solution> solutions,
713742
const SolutionDiff &diff, unsigned idx1, unsigned idx2) {
@@ -750,8 +779,17 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
750779
return 1;
751780
};
752781

782+
SmallVector<SolutionDiff::OverloadDiff, 4> overloadDiff(diff.overloads);
783+
// Single type of keypath dynamic member lookup could refer to different
784+
// member overlaods, we have to do a pair-wise comparison in such cases
785+
// otherwise ranking would miss some viable information e.g.
786+
// `_ = arr[0..<3]` could refer to subscript through writable or read-only
787+
// key path and each of them could also pick overload which returns `Slice<T>`
788+
// or `ArraySlice<T>` (assuming that `arr` is something like `Box<[Int]>`).
789+
addKeyPathDynamicMemberOverloads(solutions, idx1, idx2, overloadDiff);
790+
753791
// Compare overload sets.
754-
for (auto &overload : diff.overloads) {
792+
for (auto &overload : overloadDiff) {
755793
unsigned weight = getWeight(overload.locator);
756794

757795
auto choice1 = overload.choices[idx1];

0 commit comments

Comments
 (0)