@@ -206,6 +206,25 @@ bool ConstraintSystem::PotentialBindings::isViable(
206
206
return true ;
207
207
}
208
208
209
+ static bool hasNilLiteralConstraint (TypeVariableType *typeVar,
210
+ ConstraintSystem &CS) {
211
+ // Look for a literal-conformance constraint on the type variable.
212
+ llvm::SetVector<Constraint *> constraints;
213
+ CS.getConstraintGraph ().gatherConstraints (
214
+ typeVar, constraints, ConstraintGraph::GatheringKind::EquivalenceClass,
215
+ [](Constraint *constraint) -> bool {
216
+ return constraint->getKind () == ConstraintKind::LiteralConformsTo &&
217
+ constraint->getProtocol ()->isSpecificProtocol (
218
+ KnownProtocolKind::ExpressibleByNilLiteral);
219
+ });
220
+
221
+ for (auto constraint : constraints)
222
+ if (CS.simplifyType (constraint->getFirstType ())->isEqual (typeVar))
223
+ return true ;
224
+
225
+ return false ;
226
+ }
227
+
209
228
Optional<ConstraintSystem::PotentialBinding>
210
229
ConstraintSystem::getPotentialBindingForRelationalConstraint (
211
230
PotentialBindings &result, Constraint *constraint,
@@ -293,13 +312,22 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
293
312
// FIXME: this has a super-inefficient extraneous simplifyType() in it.
294
313
bool isNilLiteral = false ;
295
314
bool *isNilLiteralPtr = nullptr ;
296
- if (!addOptionalSupertypeBindings && kind == AllowedBindingKind::Supertypes)
297
- isNilLiteralPtr = &isNilLiteral;
298
- if (auto boundType = checkTypeOfBinding (typeVar, type, isNilLiteralPtr)) {
315
+ if (auto boundType = checkTypeOfBinding (typeVar, type)) {
299
316
type = *boundType;
300
317
if (type->hasTypeVariable ())
301
318
result.InvolvesTypeVariables = true ;
302
319
} else {
320
+ if (!addOptionalSupertypeBindings && kind == AllowedBindingKind::Supertypes)
321
+ isNilLiteralPtr = &isNilLiteral;
322
+
323
+ if (isNilLiteralPtr) {
324
+ if (auto *bindingTypeVar =
325
+ type->getRValueType ()->getAs <TypeVariableType>())
326
+ *isNilLiteralPtr = hasNilLiteralConstraint (bindingTypeVar, *this );
327
+ else
328
+ *isNilLiteralPtr = false ;
329
+ }
330
+
303
331
// If the bound is a 'nil' literal type, add optional supertype bindings.
304
332
if (isNilLiteral) {
305
333
addOptionalSupertypeBindings = true ;
@@ -724,39 +752,12 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) {
724
752
return result;
725
753
}
726
754
727
- static bool hasNilLiteralConstraint (TypeVariableType *typeVar,
728
- ConstraintSystem &CS) {
729
- // Look for a literal-conformance constraint on the type variable.
730
- llvm::SetVector<Constraint *> constraints;
731
- CS.getConstraintGraph ().gatherConstraints (
732
- typeVar, constraints,
733
- ConstraintGraph::GatheringKind::EquivalenceClass,
734
- [](Constraint *constraint) -> bool {
735
- return constraint->getKind () == ConstraintKind::LiteralConformsTo &&
736
- constraint->getProtocol ()->isSpecificProtocol (
737
- KnownProtocolKind::ExpressibleByNilLiteral);
738
- });
739
-
740
- for (auto constraint : constraints)
741
- if (CS.simplifyType (constraint->getFirstType ())->isEqual (typeVar))
742
- return true ;
743
-
744
- return false ;
745
- }
746
-
747
755
// / \brief Check whether the given type can be used as a binding for the given
748
756
// / type variable.
749
757
// /
750
758
// / \returns the type to bind to, if the binding is okay.
751
759
Optional<Type> ConstraintSystem::checkTypeOfBinding (TypeVariableType *typeVar,
752
- Type type,
753
- bool *isNilLiteral) {
754
- if (isNilLiteral)
755
- *isNilLiteral = false ;
756
-
757
- if (!type)
758
- return None;
759
-
760
+ Type type) {
760
761
// Simplify the type.
761
762
type = simplifyType (type);
762
763
@@ -778,12 +779,8 @@ Optional<Type> ConstraintSystem::checkTypeOfBinding(TypeVariableType *typeVar,
778
779
}
779
780
780
781
// If the type is a type variable itself, don't permit the binding.
781
- if (auto *bindingTypeVar = type->getRValueType ()->getAs <TypeVariableType>()) {
782
- if (isNilLiteral)
783
- *isNilLiteral = hasNilLiteralConstraint (bindingTypeVar, *this );
784
-
782
+ if (auto *bindingTypeVar = type->getRValueType ()->getAs <TypeVariableType>())
785
783
return None;
786
- }
787
784
788
785
// Don't bind to a dependent member type, even if it's currently
789
786
// wrapped in any number of optionals, because binding producer
0 commit comments