|
22 | 22 | using namespace swift;
|
23 | 23 | using namespace constraints;
|
24 | 24 |
|
| 25 | +bool ConstraintSystem::PotentialBindings::isPotentiallyIncomplete() const { |
| 26 | + // Generic parameters are always potentially incomplete. |
| 27 | + if (isGenericParameter()) |
| 28 | + return true; |
| 29 | + |
| 30 | + // If current type variable is associated with a code completion token |
| 31 | + // it's possible that it doesn't have enough contextual information |
| 32 | + // to be resolved to anything so let's delay considering it until everything |
| 33 | + // else is resolved. |
| 34 | + if (AssociatedCodeCompletionToken) |
| 35 | + return true; |
| 36 | + |
| 37 | + auto *locator = TypeVar->getImpl().getLocator(); |
| 38 | + if (!locator) |
| 39 | + return false; |
| 40 | + |
| 41 | + if (locator->isLastElement<LocatorPathElt::UnresolvedMemberChainResult>()) { |
| 42 | + // If subtyping is allowed and this is a result of an implicit member chain, |
| 43 | + // let's delay binding it to an optional until its object type resolved too or |
| 44 | + // it has been determined that there is no possibility to resolve it. Otherwise |
| 45 | + // we might end up missing solutions since it's allowed to implicitly unwrap |
| 46 | + // base type of the chain but it can't be done early - type variable |
| 47 | + // representing chain's result type has a different l-valueness comparing |
| 48 | + // to generic parameter of the optional. |
| 49 | + if (llvm::any_of(Bindings, [&](const PotentialBinding &binding) { |
| 50 | + if (binding.Kind != AllowedBindingKind::Subtypes) |
| 51 | + return false; |
| 52 | + |
| 53 | + auto objectType = binding.BindingType->getOptionalObjectType(); |
| 54 | + return objectType && objectType->isTypeVariableOrMember(); |
| 55 | + })) |
| 56 | + return true; |
| 57 | + } |
| 58 | + |
| 59 | + if (isHole()) { |
| 60 | + // If the base of the unresolved member reference like `.foo` |
| 61 | + // couldn't be resolved we'd want to bind it to a hole at the |
| 62 | + // very last moment possible, just like generic parameters. |
| 63 | + if (locator->isLastElement<LocatorPathElt::MemberRefBase>()) |
| 64 | + return true; |
| 65 | + |
| 66 | + // Delay resolution of the code completion expression until |
| 67 | + // the very end to give it a chance to be bound to some |
| 68 | + // contextual type even if it's a hole. |
| 69 | + if (locator->directlyAt<CodeCompletionExpr>()) |
| 70 | + return true; |
| 71 | + |
| 72 | + // Delay resolution of the `nil` literal to a hole until |
| 73 | + // the very end to give it a change to be bound to some |
| 74 | + // other type, just like code completion expression which |
| 75 | + // relies solely on contextual information. |
| 76 | + if (locator->directlyAt<NilLiteralExpr>()) |
| 77 | + return true; |
| 78 | + } |
| 79 | + |
| 80 | + return false; |
| 81 | +} |
| 82 | + |
25 | 83 | void ConstraintSystem::PotentialBindings::inferTransitiveProtocolRequirements(
|
26 | 84 | const ConstraintSystem &cs,
|
27 | 85 | llvm::SmallDenseMap<TypeVariableType *, ConstraintSystem::PotentialBindings>
|
@@ -462,30 +520,23 @@ void ConstraintSystem::PotentialBindings::finalize(
|
462 | 520 | // If there are no bindings, typeVar may be a hole.
|
463 | 521 | if (cs.shouldAttemptFixes() && Bindings.empty() &&
|
464 | 522 | TypeVar->getImpl().canBindToHole()) {
|
465 |
| - IsHole = true; |
466 | 523 | // If the base of the unresolved member reference like `.foo`
|
467 | 524 | // couldn't be resolved we'd want to bind it to a hole at the
|
468 | 525 | // very last moment possible, just like generic parameters.
|
469 | 526 | auto *locator = TypeVar->getImpl().getLocator();
|
470 |
| - if (locator->isLastElement<LocatorPathElt::MemberRefBase>()) |
471 |
| - PotentiallyIncomplete = true; |
472 | 527 |
|
473 | 528 | // Delay resolution of the code completion expression until
|
474 | 529 | // the very end to give it a chance to be bound to some
|
475 | 530 | // contextual type even if it's a hole.
|
476 |
| - if (locator->directlyAt<CodeCompletionExpr>()) { |
| 531 | + if (locator->directlyAt<CodeCompletionExpr>()) |
477 | 532 | FullyBound = true;
|
478 |
| - PotentiallyIncomplete = true; |
479 |
| - } |
480 | 533 |
|
481 | 534 | // Delay resolution of the `nil` literal to a hole until
|
482 | 535 | // the very end to give it a change to be bound to some
|
483 | 536 | // other type, just like code completion expression which
|
484 | 537 | // relies solely on contextual information.
|
485 |
| - if (locator->directlyAt<NilLiteralExpr>()) { |
| 538 | + if (locator->directlyAt<NilLiteralExpr>()) |
486 | 539 | FullyBound = true;
|
487 |
| - PotentiallyIncomplete = true; |
488 |
| - } |
489 | 540 |
|
490 | 541 | // If this type variable is associated with a code completion token
|
491 | 542 | // and it failed to infer any bindings let's adjust hole's locator
|
@@ -513,17 +564,6 @@ void ConstraintSystem::PotentialBindings::finalize(
|
513 | 564 | std::rotate(AnyTypePos, AnyTypePos + 1, Bindings.end());
|
514 | 565 | }
|
515 | 566 | }
|
516 |
| - |
517 |
| - // Determine if the bindings only constrain the type variable from above with |
518 |
| - // an existential type; such a binding is not very helpful because it's |
519 |
| - // impossible to enumerate the existential type's subtypes. |
520 |
| - if (!Bindings.empty()) { |
521 |
| - SubtypeOfExistentialType = |
522 |
| - llvm::all_of(Bindings, [](const PotentialBinding &binding) { |
523 |
| - return binding.BindingType->isExistentialType() && |
524 |
| - binding.Kind == AllowedBindingKind::Subtypes; |
525 |
| - }); |
526 |
| - } |
527 | 567 | }
|
528 | 568 |
|
529 | 569 | Optional<ConstraintSystem::PotentialBindings>
|
@@ -678,9 +718,6 @@ void ConstraintSystem::PotentialBindings::addPotentialBinding(
|
678 | 718 | if (!isViable(binding))
|
679 | 719 | return;
|
680 | 720 |
|
681 |
| - if (binding.isDefaultableBinding()) |
682 |
| - ++NumDefaultableBindings; |
683 |
| - |
684 | 721 | Bindings.push_back(std::move(binding));
|
685 | 722 | }
|
686 | 723 |
|
@@ -709,7 +746,7 @@ bool ConstraintSystem::PotentialBindings::isViable(
|
709 | 746 |
|
710 | 747 | bool ConstraintSystem::PotentialBindings::favoredOverDisjunction(
|
711 | 748 | Constraint *disjunction) const {
|
712 |
| - if (IsHole || FullyBound) |
| 749 | + if (isHole() || FullyBound) |
713 | 750 | return false;
|
714 | 751 |
|
715 | 752 | // If this bindings are for a closure and there are no holes,
|
@@ -889,10 +926,8 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
|
889 | 926 | // bindings and use it when forming a hole if there are no other bindings
|
890 | 927 | // available.
|
891 | 928 | if (auto *locator = bindingTypeVar->getImpl().getLocator()) {
|
892 |
| - if (locator->directlyAt<CodeCompletionExpr>()) { |
| 929 | + if (locator->directlyAt<CodeCompletionExpr>()) |
893 | 930 | result.AssociatedCodeCompletionToken = locator->getAnchor();
|
894 |
| - result.PotentiallyIncomplete = true; |
895 |
| - } |
896 | 931 | }
|
897 | 932 |
|
898 | 933 | switch (constraint->getKind()) {
|
@@ -931,24 +966,6 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
|
931 | 966 | return None;
|
932 | 967 | }
|
933 | 968 |
|
934 |
| - // If subtyping is allowed and this is a result of an implicit member chain, |
935 |
| - // let's delay binding it to an optional until its object type resolved too or |
936 |
| - // it has been determined that there is no possibility to resolve it. Otherwise |
937 |
| - // we might end up missing solutions since it's allowed to implicitly unwrap |
938 |
| - // base type of the chain but it can't be done early - type variable |
939 |
| - // representing chain's result type has a different l-valueness comparing |
940 |
| - // to generic parameter of the optional. |
941 |
| - if (kind == AllowedBindingKind::Subtypes) { |
942 |
| - auto *locator = typeVar->getImpl().getLocator(); |
943 |
| - if (locator && |
944 |
| - locator->isLastElement<LocatorPathElt::UnresolvedMemberChainResult>()) { |
945 |
| - auto objectType = type->getOptionalObjectType(); |
946 |
| - if (objectType && objectType->isTypeVariableOrMember()) { |
947 |
| - result.PotentiallyIncomplete = true; |
948 |
| - } |
949 |
| - } |
950 |
| - } |
951 |
| - |
952 | 969 | if (type->is<InOutType>() && !typeVar->getImpl().canBindToInOut())
|
953 | 970 | type = LValueType::get(type->getInOutObjectType());
|
954 | 971 | if (type->is<LValueType>() && !typeVar->getImpl().canBindToLValue())
|
@@ -987,20 +1004,6 @@ bool ConstraintSystem::PotentialBindings::infer(
|
987 | 1004 | case ConstraintKind::ArgumentConversion:
|
988 | 1005 | case ConstraintKind::OperatorArgumentConversion:
|
989 | 1006 | case ConstraintKind::OptionalObject: {
|
990 |
| - // If there is a `bind param` constraint associated with |
991 |
| - // current type variable, result should be aware of that |
992 |
| - // fact. Binding set might be incomplete until |
993 |
| - // this constraint is resolved, because we currently don't |
994 |
| - // look-through constraints expect to `subtype` to try and |
995 |
| - // find related bindings. |
996 |
| - // This only affects type variable that appears one the |
997 |
| - // right-hand side of the `bind param` constraint and |
998 |
| - // represents result type of the closure body, because |
999 |
| - // left-hand side gets types from overload choices. |
1000 |
| - if (constraint->getKind() == ConstraintKind::BindParam && |
1001 |
| - constraint->getSecondType()->isEqual(TypeVar)) |
1002 |
| - PotentiallyIncomplete = true; |
1003 |
| - |
1004 | 1007 | auto binding =
|
1005 | 1008 | cs.getPotentialBindingForRelationalConstraint(*this, constraint);
|
1006 | 1009 | if (!binding)
|
|
0 commit comments