mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Constraint solver] Start lazily building relational constraints.
Start migrating the main ConstraintSolver::addConstraint() entrypoint for relational constraints over to the model where it simplifies first, then only creates a new constraint if the constraint it built cannot be solved. This covers only the main relational constraints--there are a number of other relational constraint kinds to handle this way.
This commit is contained in:
@@ -4030,7 +4030,8 @@ bool ConstraintSystem::recordFix(Fix fix, ConstraintLocatorBuilder locator) {
|
|||||||
|
|
||||||
ConstraintSystem::SolutionKind
|
ConstraintSystem::SolutionKind
|
||||||
ConstraintSystem::simplifyFixConstraint(Fix fix, Type type1, Type type2,
|
ConstraintSystem::simplifyFixConstraint(Fix fix, Type type1, Type type2,
|
||||||
TypeMatchKind matchKind, TypeMatchOptions flags,
|
TypeMatchKind matchKind,
|
||||||
|
TypeMatchOptions flags,
|
||||||
ConstraintLocatorBuilder locator) {
|
ConstraintLocatorBuilder locator) {
|
||||||
if (recordFix(fix, locator))
|
if (recordFix(fix, locator))
|
||||||
return SolutionKind::Error;
|
return SolutionKind::Error;
|
||||||
@@ -4063,6 +4064,62 @@ ConstraintSystem::simplifyFixConstraint(Fix fix, Type type1, Type type2,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConstraintSystem::addConstraint(ConstraintKind kind, Type first,
|
||||||
|
Type second,
|
||||||
|
ConstraintLocatorBuilder locator,
|
||||||
|
bool isFavored) {
|
||||||
|
assert(first && "Missing first type");
|
||||||
|
assert(second && "Missing second type");
|
||||||
|
|
||||||
|
// Local function to record failures if necessary.
|
||||||
|
auto failed = [&] {
|
||||||
|
// Add a failing constraint, if needed.
|
||||||
|
if (shouldAddNewFailingConstraint()) {
|
||||||
|
auto c = Constraint::create(*this, kind, first, second, DeclName(),
|
||||||
|
FunctionRefKind::Compound,
|
||||||
|
getConstraintLocator(locator));
|
||||||
|
if (isFavored) c->setFavored();
|
||||||
|
addNewFailingConstraint(c);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TypeMatchOptions subflags = TMF_GenerateConstraints;
|
||||||
|
switch (kind) {
|
||||||
|
case ConstraintKind::Equal:
|
||||||
|
case ConstraintKind::BindParam:
|
||||||
|
case ConstraintKind::Subtype:
|
||||||
|
case ConstraintKind::Conversion:
|
||||||
|
case ConstraintKind::ExplicitConversion:
|
||||||
|
case ConstraintKind::ArgumentConversion:
|
||||||
|
case ConstraintKind::ArgumentTupleConversion:
|
||||||
|
case ConstraintKind::OperatorArgumentTupleConversion:
|
||||||
|
case ConstraintKind::OperatorArgumentConversion:
|
||||||
|
switch (matchTypes(first, second, getTypeMatchKind(kind), subflags,
|
||||||
|
locator)) {
|
||||||
|
case SolutionKind::Error:
|
||||||
|
return failed();
|
||||||
|
|
||||||
|
case SolutionKind::Unsolved:
|
||||||
|
llvm_unreachable("should have generated constraints");
|
||||||
|
|
||||||
|
case SolutionKind::Solved:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ConstraintKind::Bind: // FIXME: This should go through matchTypes() above
|
||||||
|
|
||||||
|
default: {
|
||||||
|
// FALLBACK CASE: do the slow thing.
|
||||||
|
auto c = Constraint::create(*this, kind, first, second, DeclName(),
|
||||||
|
FunctionRefKind::Compound,
|
||||||
|
getConstraintLocator(locator));
|
||||||
|
if (isFavored) c->setFavored();
|
||||||
|
addConstraint(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConstraintSystem::SolutionKind
|
ConstraintSystem::SolutionKind
|
||||||
ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
|
ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
|
||||||
switch (constraint.getKind()) {
|
switch (constraint.getKind()) {
|
||||||
@@ -4076,16 +4133,14 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
|
|||||||
case ConstraintKind::ArgumentTupleConversion:
|
case ConstraintKind::ArgumentTupleConversion:
|
||||||
case ConstraintKind::OperatorArgumentTupleConversion:
|
case ConstraintKind::OperatorArgumentTupleConversion:
|
||||||
case ConstraintKind::OperatorArgumentConversion: {
|
case ConstraintKind::OperatorArgumentConversion: {
|
||||||
// For relational constraints, match up the types.
|
// Relational constraints.
|
||||||
auto matchKind = getTypeMatchKind(constraint.getKind());
|
auto matchKind = getTypeMatchKind(constraint.getKind());
|
||||||
|
|
||||||
// If there is a fix associated with this constraint, apply it before
|
// If there is a fix associated with this constraint, apply it.
|
||||||
// we continue.
|
|
||||||
if (auto fix = constraint.getFix()) {
|
if (auto fix = constraint.getFix()) {
|
||||||
return simplifyFixConstraint(*fix, constraint.getFirstType(),
|
return simplifyFixConstraint(*fix, constraint.getFirstType(),
|
||||||
constraint.getSecondType(), matchKind,
|
constraint.getSecondType(), matchKind,
|
||||||
TMF_GenerateConstraints,
|
None, constraint.getLocator());
|
||||||
constraint.getLocator());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a restriction on this constraint, apply it directly rather
|
// If there is a restriction on this constraint, apply it directly rather
|
||||||
|
|||||||
@@ -1384,14 +1384,8 @@ public:
|
|||||||
|
|
||||||
/// \brief Add a constraint to the constraint system.
|
/// \brief Add a constraint to the constraint system.
|
||||||
void addConstraint(ConstraintKind kind, Type first, Type second,
|
void addConstraint(ConstraintKind kind, Type first, Type second,
|
||||||
ConstraintLocator *locator, bool isFavored = false) {
|
ConstraintLocatorBuilder locator,
|
||||||
assert(first && "Missing first type");
|
bool isFavored = false);
|
||||||
assert(second && "Missing second type");
|
|
||||||
auto c = Constraint::create(*this, kind, first, second, DeclName(),
|
|
||||||
FunctionRefKind::Compound, locator);
|
|
||||||
if (isFavored) c->setFavored();
|
|
||||||
addConstraint(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a new constraint with a restriction on its application.
|
/// Add a new constraint with a restriction on its application.
|
||||||
void addRestrictedConstraint(ConstraintKind kind,
|
void addRestrictedConstraint(ConstraintKind kind,
|
||||||
|
|||||||
Reference in New Issue
Block a user