Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.

Commit 57a2e11

Browse files
authored
Merge pull request swiftlang#34834 from xedin/replace-last-supertype-index
[CSBinding] Attempt to join any existing and viable bindings with new…
2 parents 951d4f3 + 96415b2 commit 57a2e11

File tree

2 files changed

+37
-24
lines changed

2 files changed

+37
-24
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4706,6 +4706,11 @@ class ConstraintSystem {
47064706
return {type, kind, BindingSource};
47074707
}
47084708

4709+
/// Determine whether this binding could be a viable candidate
4710+
/// to be "joined" with some other binding. It has to be at least
4711+
/// a non-default r-value supertype binding with no type variables.
4712+
bool isViableForJoin() const;
4713+
47094714
static PotentialBinding forHole(TypeVariableType *typeVar,
47104715
ConstraintLocator *locator) {
47114716
return {HoleType::get(typeVar->getASTContext(), typeVar),
@@ -4745,9 +4750,6 @@ class ConstraintSystem {
47454750
/// Whether this type variable has literal bindings.
47464751
LiteralBindingKind LiteralBinding = LiteralBindingKind::None;
47474752

4748-
/// Tracks the position of the last known supertype in the group.
4749-
Optional<unsigned> lastSupertypeIndex;
4750-
47514753
/// A set of all not-yet-resolved type variables this type variable
47524754
/// is a subtype of, supertype of or is equivalent to. This is used
47534755
/// to determine ordering inside of a chain of subtypes to help infer

lib/Sema/CSBindings.cpp

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@
2222
using namespace swift;
2323
using namespace constraints;
2424

25+
bool ConstraintSystem::PotentialBinding::isViableForJoin() const {
26+
return Kind == AllowedBindingKind::Supertypes &&
27+
!BindingType->hasLValueType() &&
28+
!BindingType->hasUnresolvedType() &&
29+
!BindingType->hasTypeVariable() &&
30+
!BindingType->hasHole() &&
31+
!BindingType->hasUnboundGenericType() &&
32+
!hasDefaultedLiteralProtocol() &&
33+
!isDefaultableBinding();
34+
}
35+
2536
bool ConstraintSystem::PotentialBindings::isPotentiallyIncomplete() const {
2637
// Generic parameters are always potentially incomplete.
2738
if (isGenericParameter())
@@ -679,30 +690,30 @@ void ConstraintSystem::PotentialBindings::addPotentialBinding(
679690
// If this is a non-defaulted supertype binding,
680691
// check whether we can combine it with another
681692
// supertype binding by computing the 'join' of the types.
682-
if (binding.Kind == AllowedBindingKind::Supertypes &&
683-
!binding.BindingType->hasUnresolvedType() &&
684-
!binding.BindingType->hasTypeVariable() &&
685-
!binding.BindingType->hasHole() &&
686-
!binding.BindingType->hasUnboundGenericType() &&
687-
!binding.hasDefaultedLiteralProtocol() &&
688-
!binding.isDefaultableBinding() && allowJoinMeet) {
689-
if (lastSupertypeIndex) {
690-
auto &lastBinding = Bindings[*lastSupertypeIndex];
691-
auto lastType = lastBinding.BindingType->getWithoutSpecifierType();
692-
auto bindingType = binding.BindingType->getWithoutSpecifierType();
693-
694-
auto join = Type::join(lastType, bindingType);
695-
if (join && !(*join)->isAny() &&
696-
(!(*join)->getOptionalObjectType()
697-
|| !(*join)->getOptionalObjectType()->isAny())) {
698-
// Replace the last supertype binding with the join. We're done.
699-
lastBinding.BindingType = *join;
700-
return;
693+
if (binding.isViableForJoin() && allowJoinMeet) {
694+
bool joined = false;
695+
696+
auto isAcceptableJoin = [](Type type) {
697+
return !type->isAny() && (!type->getOptionalObjectType() ||
698+
!type->getOptionalObjectType()->isAny());
699+
};
700+
701+
for (auto &existingBinding : Bindings) {
702+
if (!existingBinding.isViableForJoin())
703+
continue;
704+
705+
auto join = Type::join(existingBinding.BindingType, binding.BindingType);
706+
707+
if (join && isAcceptableJoin(*join)) {
708+
existingBinding.BindingType = *join;
709+
joined = true;
701710
}
702711
}
703712

704-
// Record this as the most recent supertype index.
705-
lastSupertypeIndex = Bindings.size();
713+
// If new binding has been joined with at least one of existing
714+
// bindings, there is no reason to include it into the set.
715+
if (joined)
716+
return;
706717
}
707718

708719
if (auto *literalProtocol = binding.getDefaultedLiteralProtocol())

0 commit comments

Comments
 (0)