@@ -33,6 +33,31 @@ bool ConstraintSystem::PotentialBinding::isViableForJoin() const {
3333 !isDefaultableBinding ();
3434}
3535
36+ bool ConstraintSystem::PotentialBindings::isDelayed () const {
37+ if (!DelayedBy.empty ())
38+ return true ;
39+
40+ if (isHole ()) {
41+ auto *locator = TypeVar->getImpl ().getLocator ();
42+ assert (locator && " a hole without locator?" );
43+
44+ // Delay resolution of the code completion expression until
45+ // the very end to give it a chance to be bound to some
46+ // contextual type even if it's a hole.
47+ if (locator->directlyAt <CodeCompletionExpr>())
48+ return true ;
49+
50+ // Delay resolution of the `nil` literal to a hole until
51+ // the very end to give it a change to be bound to some
52+ // other type, just like code completion expression which
53+ // relies solely on contextual information.
54+ if (locator->directlyAt <NilLiteralExpr>())
55+ return true ;
56+ }
57+
58+ return false ;
59+ }
60+
3661bool ConstraintSystem::PotentialBindings::isPotentiallyIncomplete () const {
3762 // Generic parameters are always potentially incomplete.
3863 if (isGenericParameter ())
@@ -555,19 +580,6 @@ void ConstraintSystem::PotentialBindings::finalize(
555580 // very last moment possible, just like generic parameters.
556581 auto *locator = TypeVar->getImpl ().getLocator ();
557582
558- // Delay resolution of the code completion expression until
559- // the very end to give it a chance to be bound to some
560- // contextual type even if it's a hole.
561- if (locator->directlyAt <CodeCompletionExpr>())
562- FullyBound = true ;
563-
564- // Delay resolution of the `nil` literal to a hole until
565- // the very end to give it a change to be bound to some
566- // other type, just like code completion expression which
567- // relies solely on contextual information.
568- if (locator->directlyAt <NilLiteralExpr>())
569- FullyBound = true ;
570-
571583 // If this type variable is associated with a code completion token
572584 // and it failed to infer any bindings let's adjust hole's locator
573585 // to point to a code completion token to avoid attempting to "fix"
@@ -776,7 +788,7 @@ bool ConstraintSystem::PotentialBindings::isViable(
776788
777789bool ConstraintSystem::PotentialBindings::favoredOverDisjunction (
778790 Constraint *disjunction) const {
779- if (isHole () || FullyBound )
791+ if (isHole () || isDelayed () )
780792 return false ;
781793
782794 // If this bindings are for a closure and there are no holes,
@@ -871,8 +883,7 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
871883 // of bindings for them until closure's body is opened.
872884 if (auto *typeVar = first->getAs <TypeVariableType>()) {
873885 if (typeVar->getImpl ().isClosureType ()) {
874- result.InvolvesTypeVariables = true ;
875- result.FullyBound = true ;
886+ result.DelayedBy .push_back (constraint);
876887 return None;
877888 }
878889 }
@@ -918,7 +929,7 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
918929 if (type->is <DependentMemberType>()) {
919930 if (!ConstraintSystem::typeVarOccursInType (typeVar, type,
920931 &result.InvolvesTypeVariables )) {
921- result.FullyBound = true ;
932+ result.DelayedBy . push_back (constraint) ;
922933 }
923934
924935 return None;
@@ -1056,7 +1067,7 @@ bool ConstraintSystem::PotentialBindings::infer(
10561067 // delaying bindings for as long as possible.
10571068 if (isExpr<ForceValueExpr>(anchor) && !type->is <LValueType>()) {
10581069 addPotentialBinding (binding->withType (LValueType::get (type)));
1059- FullyBound = true ;
1070+ DelayedBy. push_back (constraint) ;
10601071 }
10611072
10621073 // If this is a type variable representing closure result,
@@ -1076,9 +1087,6 @@ bool ConstraintSystem::PotentialBindings::infer(
10761087 break ;
10771088 }
10781089 case ConstraintKind::KeyPathApplication: {
1079- if (FullyBound)
1080- return false ;
1081-
10821090 // If this variable is in the application projected result type, mark the
10831091 // result as `FullyBound` to ensure we delay binding until we've bound
10841092 // other type variables in the KeyPathApplication constraint. This ensures
@@ -1087,8 +1095,9 @@ bool ConstraintSystem::PotentialBindings::infer(
10871095 SmallPtrSet<TypeVariableType *, 4 > typeVars;
10881096 findInferableTypeVars (cs.simplifyType (constraint->getThirdType ()),
10891097 typeVars);
1090- if (typeVars.count (TypeVar))
1091- FullyBound = true ;
1098+ if (typeVars.count (TypeVar)) {
1099+ DelayedBy.push_back (constraint);
1100+ }
10921101
10931102 break ;
10941103 }
@@ -1130,17 +1139,14 @@ bool ConstraintSystem::PotentialBindings::infer(
11301139 break ;
11311140
11321141 case ConstraintKind::Disjunction:
1133- // FIXME: Recurse into these constraints to see whether this
1134- // type variable is fully bound by any of them.
1135- InvolvesTypeVariables = true ;
1136-
11371142 // If there is additional context available via disjunction
11381143 // associated with closure literal (e.g. coercion to some other
11391144 // type) let's delay resolving the closure until the disjunction
11401145 // is attempted.
11411146 if (TypeVar->getImpl ().isClosureType ())
11421147 return true ;
11431148
1149+ DelayedBy.push_back (constraint);
11441150 break ;
11451151
11461152 case ConstraintKind::ConformsTo:
@@ -1162,50 +1168,46 @@ bool ConstraintSystem::PotentialBindings::infer(
11621168 case ConstraintKind::ApplicableFunction:
11631169 case ConstraintKind::DynamicCallableApplicableFunction:
11641170 case ConstraintKind::BindOverload: {
1165- if (FullyBound && InvolvesTypeVariables)
1166- return false ;
1167-
1168- // If this variable is in the left-hand side, it is fully bound.
1169- SmallPtrSet<TypeVariableType *, 4 > typeVars;
1170- findInferableTypeVars (cs.simplifyType (constraint->getFirstType ()),
1171- typeVars);
1172- if (typeVars.count (TypeVar))
1173- FullyBound = true ;
1174-
1175- if (InvolvesTypeVariables)
1176- return false ;
1177-
1178- // If this and another type variable occur, this result involves
1179- // type variables.
1180- findInferableTypeVars (cs.simplifyType (constraint->getSecondType ()),
1181- typeVars);
1182- if (typeVars.size () > 1 && typeVars.count (TypeVar))
1183- InvolvesTypeVariables = true ;
1171+ // It's possible that type of member couldn't be determined,
1172+ // and if so it would be beneficial to bind member to a hole
1173+ // early to propagate that information down to arguments,
1174+ // result type of a call that references such a member.
1175+ if (cs.shouldAttemptFixes () && TypeVar->getImpl ().canBindToHole ()) {
1176+ if (ConstraintSystem::typeVarOccursInType (
1177+ TypeVar, cs.simplifyType (constraint->getSecondType ())))
1178+ break ;
1179+ }
11841180
1181+ DelayedBy.push_back (constraint);
11851182 break ;
11861183 }
11871184
11881185 case ConstraintKind::ValueMember:
11891186 case ConstraintKind::UnresolvedValueMember:
1190- case ConstraintKind::ValueWitness:
1191- // If our type variable shows up in the base type, there's
1192- // nothing to do.
1193- // FIXME: Can we avoid simplification here?
1194- if (ConstraintSystem::typeVarOccursInType (
1195- TypeVar, cs.simplifyType (constraint->getFirstType ()),
1196- &InvolvesTypeVariables)) {
1197- return false ;
1187+ case ConstraintKind::ValueWitness: {
1188+ // If current type variable represents a member type of some reference,
1189+ // it would be bound once member is resolved either to a actual member
1190+ // type or to a hole if member couldn't be found.
1191+ auto memberTy = constraint->getSecondType ()->castTo <TypeVariableType>();
1192+
1193+ if (memberTy->getImpl ().hasRepresentativeOrFixed ()) {
1194+ if (auto type = memberTy->getImpl ().getFixedType (/* record=*/ nullptr )) {
1195+ // It's possible that member has been bound to some other type variable
1196+ // instead of merged with it because it's wrapped in an l-value type.
1197+ if (type->getWithoutSpecifierType ()->isEqual (TypeVar)) {
1198+ DelayedBy.push_back (constraint);
1199+ break ;
1200+ }
1201+ } else {
1202+ memberTy = memberTy->getImpl ().getRepresentative (/* record=*/ nullptr );
1203+ }
11981204 }
11991205
1200- // If the type variable is in the list of member type
1201- // variables, it is fully bound.
1202- // FIXME: Can we avoid simplification here?
1203- if (ConstraintSystem::typeVarOccursInType (
1204- TypeVar, cs.simplifyType (constraint->getSecondType ()),
1205- &InvolvesTypeVariables)) {
1206- FullyBound = true ;
1207- }
1206+ if (memberTy == TypeVar)
1207+ DelayedBy.push_back (constraint);
1208+
12081209 break ;
1210+ }
12091211
12101212 case ConstraintKind::OneWayEqual:
12111213 case ConstraintKind::OneWayBindParam: {
0 commit comments