Skip to content

Commit 2acfff0

Browse files
committed
[ConstraintSystem] Unify type var and disjunction choice producers
Introduce a base `BindingProducer` type which can produce bindings for both type variables and disjunctions.
1 parent 2d5d2d1 commit 2acfff0

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,7 @@ bool ConstraintSystem::solveForDisjunctionChoices(
17921792
Optional<Score> bestNonGenericScore;
17931793
Optional<std::pair<Constraint *, Score>> lastSolvedChoice;
17941794

1795-
DisjunctionChoiceProducer producer(choices, disjunctionLocator,
1795+
DisjunctionChoiceProducer producer(*this, choices, disjunctionLocator,
17961796
isExplicitConversion);
17971797

17981798
// Try each of the constraints within the disjunction.

lib/Sema/ConstraintSystem.h

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "llvm/ADT/SetOperations.h"
3838
#include "llvm/ADT/SetVector.h"
3939
#include "llvm/ADT/SmallPtrSet.h"
40+
#include "llvm/ADT/STLExtras.h"
4041
#include "llvm/Support/ErrorHandling.h"
4142
#include "llvm/Support/Timer.h"
4243
#include "llvm/Support/raw_ostream.h"
@@ -3485,13 +3486,35 @@ class TypeVariableBinding : public TypeBinding {
34853486
}
34863487
};
34873488

3488-
class TypeVarBindingProducer {
3489+
template<typename Choice>
3490+
class BindingProducer {
3491+
ConstraintLocator *Locator;
3492+
3493+
protected:
3494+
ConstraintSystem &CS;
3495+
3496+
public:
3497+
BindingProducer(ConstraintSystem &cs, ConstraintLocator *locator)
3498+
: Locator(locator), CS(cs) {}
3499+
3500+
virtual ~BindingProducer() {}
3501+
virtual Optional<Choice> operator()() = 0;
3502+
3503+
ConstraintLocator *getLocator() const { return Locator; }
3504+
3505+
/// Check whether generator would have to compute next
3506+
/// batch of bindings because it freshly ran out of current one.
3507+
/// This is useful to be able to exhaustively attempt bindings
3508+
/// for type variables found at one level, before proceeding to
3509+
/// supertypes or literal defaults etc.
3510+
virtual bool needsToComputeNext() const { return false; }
3511+
};
3512+
3513+
class TypeVarBindingProducer : public BindingProducer<TypeVariableBinding> {
34893514
using BindingKind = ConstraintSystem::AllowedBindingKind;
34903515
using Binding = ConstraintSystem::PotentialBinding;
34913516

3492-
ConstraintSystem &CS;
34933517
TypeVariableType *TypeVar;
3494-
34953518
llvm::SmallVector<Binding, 8> Bindings;
34963519

34973520
// The index pointing to the offset in the bindings
@@ -3505,10 +3528,10 @@ class TypeVarBindingProducer {
35053528
public:
35063529
TypeVarBindingProducer(ConstraintSystem &cs, TypeVariableType *typeVar,
35073530
ArrayRef<Binding> initialBindings)
3508-
: CS(cs), TypeVar(typeVar),
3531+
: BindingProducer(cs, typeVar->getImpl().getLocator()), TypeVar(typeVar),
35093532
Bindings(initialBindings.begin(), initialBindings.end()) {}
35103533

3511-
Optional<TypeVariableBinding> operator()() {
3534+
Optional<TypeVariableBinding> operator()() override {
35123535
// Once we reach the end of the current bindings
35133536
// let's try to compute new ones, e.g. supertypes,
35143537
// literal defaults, if that fails, we are done.
@@ -3519,12 +3542,7 @@ class TypeVarBindingProducer {
35193542
return TypeVariableBinding(currIndex, TypeVar, Bindings[currIndex]);
35203543
}
35213544

3522-
/// Check whether generator would have to compute next
3523-
/// batch of bindings because it freshly ran out of current one.
3524-
/// This is useful to be able to exhaustively attempt bindings
3525-
/// found at one level, before proceeding to supertypes or
3526-
/// literal defaults etc.
3527-
bool needsToComputeNext() const { return Index >= Bindings.size(); }
3545+
bool needsToComputeNext() const override { return Index >= Bindings.size(); }
35283546

35293547
private:
35303548
/// Compute next batch of bindings if possible, this could
@@ -3539,20 +3557,20 @@ class TypeVarBindingProducer {
35393557
/// Iterator over disjunction choices, makes it
35403558
/// easy to work with disjunction and encapsulates
35413559
/// some other important information such as locator.
3542-
class DisjunctionChoiceProducer {
3560+
class DisjunctionChoiceProducer : public BindingProducer<DisjunctionChoice> {
35433561
ArrayRef<Constraint *> Choices;
3544-
ConstraintLocator *Locator;
35453562
bool IsExplicitConversion;
35463563

35473564
unsigned Index = 0;
35483565

35493566
public:
3550-
DisjunctionChoiceProducer(ArrayRef<Constraint *> choices,
3567+
DisjunctionChoiceProducer(ConstraintSystem &cs,
3568+
ArrayRef<Constraint *> choices,
35513569
ConstraintLocator *locator, bool explicitConversion)
3552-
: Choices(choices), Locator(locator),
3570+
: BindingProducer(cs, locator), Choices(choices),
35533571
IsExplicitConversion(explicitConversion) {}
35543572

3555-
Optional<DisjunctionChoice> operator()() {
3573+
Optional<DisjunctionChoice> operator()() override {
35563574
unsigned currIndex = Index;
35573575
if (currIndex >= Choices.size())
35583576
return None;
@@ -3561,8 +3579,6 @@ class DisjunctionChoiceProducer {
35613579
return DisjunctionChoice(currIndex, Choices[currIndex],
35623580
IsExplicitConversion);
35633581
}
3564-
3565-
ConstraintLocator *getLocator() const { return Locator; }
35663582
};
35673583

35683584
/// \brief Constraint System "component" represents

0 commit comments

Comments
 (0)