Skip to content

Commit 7617b74

Browse files
committed
[CSBindings] Re-introduce joined bindings instead of updating in place
Make `PotentialBinding` immutable and re-introduce products of type join instead.
1 parent 03b6b41 commit 7617b74

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4623,10 +4623,7 @@ class ConstraintSystem {
46234623
/// bindings, e.g., the supertypes of a given type.
46244624
struct PotentialBinding {
46254625
/// The type to which the type variable can be bound.
4626-
///
4627-
/// Note that the type is mutable since it could be
4628-
/// adjusted as a result of type-join operation.
4629-
mutable Type BindingType;
4626+
Type BindingType;
46304627

46314628
/// The kind of bindings permitted.
46324629
AllowedBindingKind Kind;

lib/Sema/CSBindings.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -549,28 +549,36 @@ bool ConstraintSystem::PotentialBindings::addPotentialBinding(
549549
// check whether we can combine it with another
550550
// supertype binding by computing the 'join' of the types.
551551
if (binding.isViableForJoin() && allowJoinMeet) {
552-
bool joined = false;
553-
554552
auto isAcceptableJoin = [](Type type) {
555553
return !type->isAny() && (!type->getOptionalObjectType() ||
556554
!type->getOptionalObjectType()->isAny());
557555
};
558556

559-
for (auto &existingBinding : Bindings) {
560-
if (!existingBinding.isViableForJoin())
561-
continue;
562-
563-
auto join = Type::join(existingBinding.BindingType, binding.BindingType);
564-
565-
if (join && isAcceptableJoin(*join)) {
566-
existingBinding.BindingType = *join;
567-
joined = true;
557+
SmallVector<PotentialBinding, 4> joined;
558+
for (auto existingBinding = Bindings.begin();
559+
existingBinding != Bindings.end();) {
560+
if (existingBinding->isViableForJoin()) {
561+
auto join =
562+
Type::join(existingBinding->BindingType, binding.BindingType);
563+
564+
if (join && isAcceptableJoin(*join)) {
565+
joined.push_back(existingBinding->withType(*join));
566+
// Remove existing binding from the set.
567+
// It has to be re-introduced later, since its type has been changed.
568+
existingBinding = Bindings.erase(existingBinding);
569+
continue;
570+
}
568571
}
572+
573+
++existingBinding;
569574
}
570575

576+
for (const auto &binding : joined)
577+
(void)Bindings.insert(binding);
578+
571579
// If new binding has been joined with at least one of existing
572580
// bindings, there is no reason to include it into the set.
573-
if (joined)
581+
if (!joined.empty())
574582
return false;
575583
}
576584

0 commit comments

Comments
 (0)