Skip to content

Commit 56a6360

Browse files
committed
[ConstraintSystem] Make checkTypeOfBinding do one job rather than two.
Hoist the call to hasNilLiteralConstraint into the one caller that cares about this.
1 parent 1bcb29d commit 56a6360

File tree

2 files changed

+34
-38
lines changed

2 files changed

+34
-38
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,25 @@ bool ConstraintSystem::PotentialBindings::isViable(
206206
return true;
207207
}
208208

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+
209228
Optional<ConstraintSystem::PotentialBinding>
210229
ConstraintSystem::getPotentialBindingForRelationalConstraint(
211230
PotentialBindings &result, Constraint *constraint,
@@ -293,13 +312,22 @@ ConstraintSystem::getPotentialBindingForRelationalConstraint(
293312
// FIXME: this has a super-inefficient extraneous simplifyType() in it.
294313
bool isNilLiteral = false;
295314
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)) {
299316
type = *boundType;
300317
if (type->hasTypeVariable())
301318
result.InvolvesTypeVariables = true;
302319
} 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+
303331
// If the bound is a 'nil' literal type, add optional supertype bindings.
304332
if (isNilLiteral) {
305333
addOptionalSupertypeBindings = true;
@@ -724,39 +752,12 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) {
724752
return result;
725753
}
726754

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-
747755
/// \brief Check whether the given type can be used as a binding for the given
748756
/// type variable.
749757
///
750758
/// \returns the type to bind to, if the binding is okay.
751759
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) {
760761
// Simplify the type.
761762
type = simplifyType(type);
762763

@@ -778,12 +779,8 @@ Optional<Type> ConstraintSystem::checkTypeOfBinding(TypeVariableType *typeVar,
778779
}
779780

780781
// 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>())
785783
return None;
786-
}
787784

788785
// Don't bind to a dependent member type, even if it's currently
789786
// wrapped in any number of optionals, because binding producer

lib/Sema/ConstraintSystem.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2984,8 +2984,7 @@ class ConstraintSystem {
29842984
}
29852985
};
29862986

2987-
Optional<Type> checkTypeOfBinding(TypeVariableType *typeVar, Type type,
2988-
bool *isNilLiteral = nullptr);
2987+
Optional<Type> checkTypeOfBinding(TypeVariableType *typeVar, Type type);
29892988
Optional<PotentialBindings> determineBestBindings();
29902989
Optional<ConstraintSystem::PotentialBinding>
29912990
getPotentialBindingForRelationalConstraint(

0 commit comments

Comments
 (0)