|
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>
|
@@ -466,25 +524,19 @@ void ConstraintSystem::PotentialBindings::finalize(
|
466 | 524 | // couldn't be resolved we'd want to bind it to a hole at the
|
467 | 525 | // very last moment possible, just like generic parameters.
|
468 | 526 | auto *locator = TypeVar->getImpl().getLocator();
|
469 |
| - if (locator->isLastElement<LocatorPathElt::MemberRefBase>()) |
470 |
| - PotentiallyIncomplete = true; |
471 | 527 |
|
472 | 528 | // Delay resolution of the code completion expression until
|
473 | 529 | // the very end to give it a chance to be bound to some
|
474 | 530 | // contextual type even if it's a hole.
|
475 |
| - if (locator->directlyAt<CodeCompletionExpr>()) { |
| 531 | + if (locator->directlyAt<CodeCompletionExpr>()) |
476 | 532 | FullyBound = true;
|
477 |
| - PotentiallyIncomplete = true; |
478 |
| - } |
479 | 533 |
|
480 | 534 | // Delay resolution of the `nil` literal to a hole until
|
481 | 535 | // the very end to give it a change to be bound to some
|
482 | 536 | // other type, just like code completion expression which
|
483 | 537 | // relies solely on contextual information.
|
484 |
| - if (locator->directlyAt<NilLiteralExpr>()) { |
| 538 | + if (locator->directlyAt<NilLiteralExpr>()) |
485 | 539 | FullyBound = true;
|
486 |
| - PotentiallyIncomplete = true; |
487 |
| - } |
488 | 540 |
|
489 | 541 | // If this type variable is associated with a code completion token
|
490 | 542 | // and it failed to infer any bindings let's adjust hole's locator
|
@@ -874,10 +926,8 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
|
874 | 926 | // bindings and use it when forming a hole if there are no other bindings
|
875 | 927 | // available.
|
876 | 928 | if (auto *locator = bindingTypeVar->getImpl().getLocator()) {
|
877 |
| - if (locator->directlyAt<CodeCompletionExpr>()) { |
| 929 | + if (locator->directlyAt<CodeCompletionExpr>()) |
878 | 930 | result.AssociatedCodeCompletionToken = locator->getAnchor();
|
879 |
| - result.PotentiallyIncomplete = true; |
880 |
| - } |
881 | 931 | }
|
882 | 932 |
|
883 | 933 | switch (constraint->getKind()) {
|
@@ -916,24 +966,6 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
|
916 | 966 | return None;
|
917 | 967 | }
|
918 | 968 |
|
919 |
| - // If subtyping is allowed and this is a result of an implicit member chain, |
920 |
| - // let's delay binding it to an optional until its object type resolved too or |
921 |
| - // it has been determined that there is no possibility to resolve it. Otherwise |
922 |
| - // we might end up missing solutions since it's allowed to implicitly unwrap |
923 |
| - // base type of the chain but it can't be done early - type variable |
924 |
| - // representing chain's result type has a different l-valueness comparing |
925 |
| - // to generic parameter of the optional. |
926 |
| - if (kind == AllowedBindingKind::Subtypes) { |
927 |
| - auto *locator = typeVar->getImpl().getLocator(); |
928 |
| - if (locator && |
929 |
| - locator->isLastElement<LocatorPathElt::UnresolvedMemberChainResult>()) { |
930 |
| - auto objectType = type->getOptionalObjectType(); |
931 |
| - if (objectType && objectType->isTypeVariableOrMember()) { |
932 |
| - result.PotentiallyIncomplete = true; |
933 |
| - } |
934 |
| - } |
935 |
| - } |
936 |
| - |
937 | 969 | if (type->is<InOutType>() && !typeVar->getImpl().canBindToInOut())
|
938 | 970 | type = LValueType::get(type->getInOutObjectType());
|
939 | 971 | if (type->is<LValueType>() && !typeVar->getImpl().canBindToLValue())
|
|
0 commit comments