Skip to content

Commit 9a68d4a

Browse files
committed
Sema: De-duplicate defaults in inferTransitiveSupertypeBindings()
This is necessary now that BindingSet::Defaults is a vector and not a set.
1 parent d795c18 commit 9a68d4a

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,18 @@ void BindingSet::inferTransitiveKeyPathBindings() {
616616
}
617617

618618
void BindingSet::inferTransitiveSupertypeBindings() {
619+
llvm::SmallDenseSet<ProtocolDecl *> seenLiterals;
620+
for (const auto &literal : Literals) {
621+
bool inserted = seenLiterals.insert(literal.getProtocol()).second;
622+
ASSERT(inserted);
623+
}
624+
625+
llvm::SmallDenseSet<Constraint *> seenDefaults;
626+
for (auto *constraint : Defaults) {
627+
bool inserted = seenDefaults.insert(constraint).second;
628+
ASSERT(inserted);
629+
}
630+
619631
for (const auto &entry : Info.SupertypeOf) {
620632
auto &node = CS.getConstraintGraph()[entry.first];
621633
if (!node.hasBindingSet())
@@ -648,11 +660,7 @@ void BindingSet::inferTransitiveSupertypeBindings() {
648660
for (auto literal : bindings.Literals) {
649661
auto *protocol = literal.getProtocol();
650662

651-
bool found = llvm::any_of(Literals,
652-
[&](const auto &literal) -> bool {
653-
return literal.getProtocol() == protocol;
654-
});
655-
if (found)
663+
if (!seenLiterals.insert(protocol).second)
656664
continue;
657665

658666
literal.setDirectRequirement(false);
@@ -664,6 +672,9 @@ void BindingSet::inferTransitiveSupertypeBindings() {
664672
if (def->getKind() == ConstraintKind::FallbackType)
665673
continue;
666674

675+
if (!seenDefaults.insert(def).second)
676+
continue;
677+
667678
addDefault(def);
668679
}
669680

test/Constraints/closures.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,3 +1415,17 @@ func test_implicit_result_conversions() {
14151415
return // Ok
14161416
}
14171417
}
1418+
1419+
// Random example reduced from swift-build which tripped an assert not
1420+
// previously covered by our test suite
1421+
do {
1422+
struct S {
1423+
var x: [Int: [String]] = [:]
1424+
}
1425+
1426+
let s = [S]()
1427+
1428+
let _: [Int: Set<String>] = s.map(\.x)
1429+
.reduce([:], { x, y in x.merging(y, uniquingKeysWith: +) })
1430+
.mapValues { Set($0) }
1431+
}

0 commit comments

Comments
 (0)