|
22 | 22 | using namespace swift;
|
23 | 23 | using namespace constraints;
|
24 | 24 |
|
| 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 | + |
25 | 36 | bool ConstraintSystem::PotentialBindings::isPotentiallyIncomplete() const {
|
26 | 37 | // Generic parameters are always potentially incomplete.
|
27 | 38 | if (isGenericParameter())
|
@@ -679,30 +690,30 @@ void ConstraintSystem::PotentialBindings::addPotentialBinding(
|
679 | 690 | // If this is a non-defaulted supertype binding,
|
680 | 691 | // check whether we can combine it with another
|
681 | 692 | // 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; |
701 | 710 | }
|
702 | 711 | }
|
703 | 712 |
|
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; |
706 | 717 | }
|
707 | 718 |
|
708 | 719 | if (auto *literalProtocol = binding.getDefaultedLiteralProtocol())
|
|
0 commit comments