|
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