|
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