@@ -57,9 +57,6 @@ bool PotentialBinding::isViableForJoin() const {
57
57
}
58
58
59
59
bool PotentialBindings::isDelayed () const {
60
- if (!DelayedBy.empty ())
61
- return true ;
62
-
63
60
if (isHole ()) {
64
61
auto *locator = TypeVar->getImpl ().getLocator ();
65
62
assert (locator && " a hole without locator?" );
@@ -76,9 +73,45 @@ bool PotentialBindings::isDelayed() const {
76
73
// relies solely on contextual information.
77
74
if (locator->directlyAt <NilLiteralExpr>())
78
75
return true ;
76
+
77
+ // It's possible that type of member couldn't be determined,
78
+ // and if so it would be beneficial to bind member to a hole
79
+ // early to propagate that information down to arguments,
80
+ // result type of a call that references such a member.
81
+ //
82
+ // Note: This is done here instead of during binding inference,
83
+ // because it's possible that variable is marked as a "hole"
84
+ // (or that status is propagated to it) after constraints
85
+ // mentioned below are recorded.
86
+ return llvm::any_of (DelayedBy, [&](Constraint *constraint) {
87
+ switch (constraint->getKind ()) {
88
+ case ConstraintKind::ApplicableFunction:
89
+ case ConstraintKind::DynamicCallableApplicableFunction:
90
+ case ConstraintKind::BindOverload: {
91
+ return !ConstraintSystem::typeVarOccursInType (
92
+ TypeVar, CS.simplifyType (constraint->getSecondType ()));
93
+ }
94
+
95
+ default :
96
+ return true ;
97
+ }
98
+ });
79
99
}
80
100
81
- return false ;
101
+ if (auto *locator = TypeVar->getImpl ().getLocator ()) {
102
+ // Since force unwrap preserves l-valueness, resulting
103
+ // type variable has to be delayed until either l-value
104
+ // binding becomes available or there are no other
105
+ // variables to attempt.
106
+ if (locator->directlyAt <ForceValueExpr>() &&
107
+ TypeVar->getImpl ().canBindToLValue ()) {
108
+ return llvm::none_of (Bindings, [](const PotentialBinding &binding) {
109
+ return binding.BindingType ->is <LValueType>();
110
+ });
111
+ }
112
+ }
113
+
114
+ return !DelayedBy.empty ();
82
115
}
83
116
84
117
bool PotentialBindings::involvesTypeVariables () const {
@@ -613,12 +646,12 @@ PotentialBindings::isLiteralCoveredBy(const LiteralRequirement &literal,
613
646
} while (true );
614
647
}
615
648
616
- bool PotentialBindings::addPotentialBinding (PotentialBinding binding,
649
+ void PotentialBindings::addPotentialBinding (PotentialBinding binding,
617
650
bool allowJoinMeet) {
618
651
assert (!binding.BindingType ->is <ErrorType>());
619
652
620
653
if (Bindings.count (binding))
621
- return false ;
654
+ return ;
622
655
623
656
// If this is a non-defaulted supertype binding,
624
657
// check whether we can combine it with another
@@ -657,7 +690,7 @@ bool PotentialBindings::addPotentialBinding(PotentialBinding binding,
657
690
// If new binding has been joined with at least one of existing
658
691
// bindings, there is no reason to include it into the set.
659
692
if (!joined.empty ())
660
- return false ;
693
+ return ;
661
694
}
662
695
663
696
// If the type variable can't bind to an lvalue, make sure the
@@ -668,7 +701,7 @@ bool PotentialBindings::addPotentialBinding(PotentialBinding binding,
668
701
}
669
702
670
703
if (!isViable (binding))
671
- return false ;
704
+ return ;
672
705
673
706
// Check whether the given binding covers any of the literal protocols
674
707
// associated with this type variable.
@@ -703,7 +736,7 @@ bool PotentialBindings::addPotentialBinding(PotentialBinding binding,
703
736
}
704
737
}
705
738
706
- return Bindings.insert (std::move (binding));
739
+ Bindings.insert (std::move (binding));
707
740
}
708
741
709
742
void PotentialBindings::addLiteral (Constraint *constraint) {
@@ -1106,38 +1139,7 @@ void PotentialBindings::infer(Constraint *constraint) {
1106
1139
if (!binding)
1107
1140
break ;
1108
1141
1109
- auto type = binding->BindingType ;
1110
- if (addPotentialBinding (*binding)) {
1111
- // Determines whether this type variable represents an object
1112
- // of the optional type extracted by force unwrap.
1113
- if (auto *locator = TypeVar->getImpl ().getLocator ()) {
1114
- auto anchor = locator->getAnchor ();
1115
- // Result of force unwrap is always connected to its base
1116
- // optional type via `OptionalObject` constraint which
1117
- // preserves l-valueness, so in case where object type got
1118
- // inferred before optional type (because it got the
1119
- // type from context e.g. parameter type of a function call),
1120
- // we need to test type with and without l-value after
1121
- // delaying bindings for as long as possible.
1122
- if (isExpr<ForceValueExpr>(anchor) &&
1123
- TypeVar->getImpl ().canBindToLValue () && !type->is <LValueType>()) {
1124
- (void )addPotentialBinding (binding->withType (LValueType::get (type)));
1125
- DelayedBy.push_back (constraint);
1126
- }
1127
-
1128
- // If this is a type variable representing closure result,
1129
- // which is on the right-side of some relational constraint
1130
- // let's have it try `Void` as well because there is an
1131
- // implicit conversion `() -> T` to `() -> Void` and this
1132
- // helps to avoid creating a thunk to support it.
1133
- auto voidType = CS.getASTContext ().TheEmptyTupleType ;
1134
- if (locator->isLastElement <LocatorPathElt::ClosureResult>() &&
1135
- binding->Kind == AllowedBindingKind::Supertypes) {
1136
- (void )addPotentialBinding ({voidType, binding->Kind , constraint},
1137
- /* allowJoinMeet=*/ false );
1138
- }
1139
- }
1140
- }
1142
+ addPotentialBinding (*binding);
1141
1143
break ;
1142
1144
}
1143
1145
case ConstraintKind::KeyPathApplication: {
@@ -1220,16 +1222,6 @@ void PotentialBindings::infer(Constraint *constraint) {
1220
1222
case ConstraintKind::ApplicableFunction:
1221
1223
case ConstraintKind::DynamicCallableApplicableFunction:
1222
1224
case ConstraintKind::BindOverload: {
1223
- // It's possible that type of member couldn't be determined,
1224
- // and if so it would be beneficial to bind member to a hole
1225
- // early to propagate that information down to arguments,
1226
- // result type of a call that references such a member.
1227
- if (CS.shouldAttemptFixes () && TypeVar->getImpl ().canBindToHole ()) {
1228
- if (ConstraintSystem::typeVarOccursInType (
1229
- TypeVar, CS.simplifyType (constraint->getSecondType ())))
1230
- break ;
1231
- }
1232
-
1233
1225
DelayedBy.push_back (constraint);
1234
1226
break ;
1235
1227
}
@@ -1464,6 +1456,19 @@ bool TypeVarBindingProducer::computeNext() {
1464
1456
}
1465
1457
}
1466
1458
1459
+ if (getLocator ()->directlyAt <ForceValueExpr>() &&
1460
+ TypeVar->getImpl ().canBindToLValue () &&
1461
+ !binding.BindingType ->is <LValueType>()) {
1462
+ // Result of force unwrap is always connected to its base
1463
+ // optional type via `OptionalObject` constraint which
1464
+ // preserves l-valueness, so in case where object type got
1465
+ // inferred before optional type (because it got the
1466
+ // type from context e.g. parameter type of a function call),
1467
+ // we need to test type with and without l-value after
1468
+ // delaying bindings for as long as possible.
1469
+ addNewBinding (binding.withType (LValueType::get (binding.BindingType )));
1470
+ }
1471
+
1467
1472
// Allow solving for T even for a binding kind where that's invalid
1468
1473
// if fixes are allowed, because that gives us the opportunity to
1469
1474
// match T? values to the T binding by adding an unwrap fix.
@@ -1504,6 +1509,17 @@ bool TypeVarBindingProducer::computeNext() {
1504
1509
}
1505
1510
1506
1511
if (binding.Kind == BindingKind::Supertypes) {
1512
+ // If this is a type variable representing closure result,
1513
+ // which is on the right-side of some relational constraint
1514
+ // let's have it try `Void` as well because there is an
1515
+ // implicit conversion `() -> T` to `() -> Void` and this
1516
+ // helps to avoid creating a thunk to support it.
1517
+ if (getLocator ()->isLastElement <LocatorPathElt::ClosureResult>() &&
1518
+ binding.Kind == AllowedBindingKind::Supertypes) {
1519
+ auto voidType = CS.getASTContext ().TheEmptyTupleType ;
1520
+ addNewBinding (binding.withSameSource (voidType, BindingKind::Exact));
1521
+ }
1522
+
1507
1523
for (auto supertype : enumerateDirectSupertypes (type)) {
1508
1524
// If we're not allowed to try this binding, skip it.
1509
1525
if (auto simplifiedSuper = checkTypeOfBinding (TypeVar, supertype))
0 commit comments