@@ -33,6 +33,31 @@ bool ConstraintSystem::PotentialBinding::isViableForJoin() const {
33
33
!isDefaultableBinding ();
34
34
}
35
35
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
+
36
61
bool ConstraintSystem::PotentialBindings::isPotentiallyIncomplete () const {
37
62
// Generic parameters are always potentially incomplete.
38
63
if (isGenericParameter ())
@@ -555,19 +580,6 @@ void ConstraintSystem::PotentialBindings::finalize(
555
580
// very last moment possible, just like generic parameters.
556
581
auto *locator = TypeVar->getImpl ().getLocator ();
557
582
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
-
571
583
// If this type variable is associated with a code completion token
572
584
// and it failed to infer any bindings let's adjust hole's locator
573
585
// to point to a code completion token to avoid attempting to "fix"
@@ -776,7 +788,7 @@ bool ConstraintSystem::PotentialBindings::isViable(
776
788
777
789
bool ConstraintSystem::PotentialBindings::favoredOverDisjunction (
778
790
Constraint *disjunction) const {
779
- if (isHole () || FullyBound )
791
+ if (isHole () || isDelayed () )
780
792
return false ;
781
793
782
794
// If this bindings are for a closure and there are no holes,
@@ -871,8 +883,7 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
871
883
// of bindings for them until closure's body is opened.
872
884
if (auto *typeVar = first->getAs <TypeVariableType>()) {
873
885
if (typeVar->getImpl ().isClosureType ()) {
874
- result.InvolvesTypeVariables = true ;
875
- result.FullyBound = true ;
886
+ result.DelayedBy .push_back (constraint);
876
887
return None;
877
888
}
878
889
}
@@ -918,7 +929,7 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
918
929
if (type->is <DependentMemberType>()) {
919
930
if (!ConstraintSystem::typeVarOccursInType (typeVar, type,
920
931
&result.InvolvesTypeVariables )) {
921
- result.FullyBound = true ;
932
+ result.DelayedBy . push_back (constraint) ;
922
933
}
923
934
924
935
return None;
@@ -1056,7 +1067,7 @@ bool ConstraintSystem::PotentialBindings::infer(
1056
1067
// delaying bindings for as long as possible.
1057
1068
if (isExpr<ForceValueExpr>(anchor) && !type->is <LValueType>()) {
1058
1069
addPotentialBinding (binding->withType (LValueType::get (type)));
1059
- FullyBound = true ;
1070
+ DelayedBy. push_back (constraint) ;
1060
1071
}
1061
1072
1062
1073
// If this is a type variable representing closure result,
@@ -1076,9 +1087,6 @@ bool ConstraintSystem::PotentialBindings::infer(
1076
1087
break ;
1077
1088
}
1078
1089
case ConstraintKind::KeyPathApplication: {
1079
- if (FullyBound)
1080
- return false ;
1081
-
1082
1090
// If this variable is in the application projected result type, mark the
1083
1091
// result as `FullyBound` to ensure we delay binding until we've bound
1084
1092
// other type variables in the KeyPathApplication constraint. This ensures
@@ -1087,8 +1095,9 @@ bool ConstraintSystem::PotentialBindings::infer(
1087
1095
SmallPtrSet<TypeVariableType *, 4 > typeVars;
1088
1096
findInferableTypeVars (cs.simplifyType (constraint->getThirdType ()),
1089
1097
typeVars);
1090
- if (typeVars.count (TypeVar))
1091
- FullyBound = true ;
1098
+ if (typeVars.count (TypeVar)) {
1099
+ DelayedBy.push_back (constraint);
1100
+ }
1092
1101
1093
1102
break ;
1094
1103
}
@@ -1130,17 +1139,14 @@ bool ConstraintSystem::PotentialBindings::infer(
1130
1139
break ;
1131
1140
1132
1141
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
-
1137
1142
// If there is additional context available via disjunction
1138
1143
// associated with closure literal (e.g. coercion to some other
1139
1144
// type) let's delay resolving the closure until the disjunction
1140
1145
// is attempted.
1141
1146
if (TypeVar->getImpl ().isClosureType ())
1142
1147
return true ;
1143
1148
1149
+ DelayedBy.push_back (constraint);
1144
1150
break ;
1145
1151
1146
1152
case ConstraintKind::ConformsTo:
@@ -1162,50 +1168,46 @@ bool ConstraintSystem::PotentialBindings::infer(
1162
1168
case ConstraintKind::ApplicableFunction:
1163
1169
case ConstraintKind::DynamicCallableApplicableFunction:
1164
1170
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
+ }
1184
1180
1181
+ DelayedBy.push_back (constraint);
1185
1182
break ;
1186
1183
}
1187
1184
1188
1185
case ConstraintKind::ValueMember:
1189
1186
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
+ }
1198
1204
}
1199
1205
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
+
1208
1209
break ;
1210
+ }
1209
1211
1210
1212
case ConstraintKind::OneWayEqual:
1211
1213
case ConstraintKind::OneWayBindParam: {
0 commit comments