Skip to content

Commit e4252a5

Browse files
committed
[ConstraintSystem] Add flags to TypeBinding
1 parent 2acfff0 commit e4252a5

File tree

2 files changed

+84
-35
lines changed

2 files changed

+84
-35
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,17 +1982,17 @@ void DisjunctionChoice::attempt(ConstraintSystem &cs) const {
19821982
propagateConversionInfo(cs);
19831983
}
19841984

1985-
bool DisjunctionChoice::isGenericOperator() const {
1986-
auto *decl = getOperatorDecl();
1985+
bool DisjunctionChoice::isGenericOp(Constraint *choice) {
1986+
auto *decl = getOperatorDecl(choice);
19871987
if (!decl)
19881988
return false;
19891989

19901990
auto interfaceType = decl->getInterfaceType();
19911991
return interfaceType->is<GenericFunctionType>();
19921992
}
19931993

1994-
bool DisjunctionChoice::isSymmetricOperator() const {
1995-
auto *decl = getOperatorDecl();
1994+
bool DisjunctionChoice::isSymmetricOp(Constraint *choice) {
1995+
auto *decl = getOperatorDecl(choice);
19961996
if (!decl)
19971997
return false;
19981998

lib/Sema/ConstraintSystem.h

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3381,31 +3381,66 @@ void simplifyLocator(Expr *&anchor,
33813381
/// null otherwise.
33823382
Expr *simplifyLocatorToAnchor(ConstraintSystem &cs, ConstraintLocator *locator);
33833383

3384+
enum class TypeBindingFlag {
3385+
/// The constraint represented by this choice has been
3386+
/// marked as disabled by the solver.
3387+
Disabled = 0x01,
3388+
/// The declaration behind this binding is marked as `@unavailable`
3389+
Unavailable = 0x02,
3390+
/// This binding comes from the "defaults to" constraint.
3391+
Defaultable = 0x04,
3392+
/// This binding comes from the "defaults to" constraint
3393+
/// which has associated protocol.
3394+
HasDefaultedProtocol = 0x08,
3395+
/// Type of the binding comes from generic operator declaration.
3396+
GenericOperator = 0x10,
3397+
/// Type of the binding comes from symmetric operator declaration.
3398+
SymmetricOperator = 0x20,
3399+
};
3400+
3401+
using TypeBindingFlags = OptionSet<TypeBindingFlag>;
3402+
33843403
/// Common interface to encapsulate attempting choices of
33853404
/// different entities, such as type variables (types)
33863405
/// or disjunctions (their choices).
33873406
class TypeBinding {
33883407
unsigned Index;
3408+
TypeBindingFlags Flags;
33893409

33903410
public:
3391-
TypeBinding(unsigned index) : Index(index) {}
3411+
TypeBinding(unsigned index, TypeBindingFlags flags)
3412+
: Index(index), Flags(flags) {}
33923413

33933414
virtual ~TypeBinding() {}
33943415
virtual void attempt(ConstraintSystem &cs) const = 0;
33953416

33963417
/// Position of this binding in the chain.
33973418
unsigned getIndex() const { return Index; }
33983419

3399-
virtual bool isDisabled() const { return false; }
3400-
virtual bool isUnavailable() const { return false; }
3401-
virtual bool isDefaultable() const { return false; }
3402-
virtual bool hasDefaultedProtocol() const { return false; }
3420+
bool isDisabled() const { return Flags.contains(TypeBindingFlag::Disabled); }
3421+
3422+
bool isUnavailable() const {
3423+
return Flags.contains(TypeBindingFlag::Unavailable);
3424+
}
3425+
3426+
bool isDefaultable() const {
3427+
return Flags.contains(TypeBindingFlag::Defaultable);
3428+
}
3429+
3430+
bool hasDefaultedProtocol() const {
3431+
return Flags.contains(TypeBindingFlag::HasDefaultedProtocol);
3432+
}
34033433

34043434
// FIXME: Both of the accessors below are required to support
34053435
// performance optimization hacks in constraint solver.
34063436

3407-
virtual bool isGenericOperator() const { return false; }
3408-
virtual bool isSymmetricOperator() const { return false; }
3437+
bool isGenericOperator() const {
3438+
return Flags.contains(TypeBindingFlag::GenericOperator);
3439+
}
3440+
3441+
bool isSymmetricOperator() const {
3442+
return Flags.contains(TypeBindingFlag::SymmetricOperator);
3443+
}
34093444

34103445
virtual void print(llvm::raw_ostream &Out, SourceManager *SM) const = 0;
34113446
};
@@ -3416,23 +3451,9 @@ class DisjunctionChoice : public TypeBinding {
34163451

34173452
public:
34183453
DisjunctionChoice(unsigned index, Constraint *choice, bool explicitConversion)
3419-
: TypeBinding(index), Choice(choice),
3454+
: TypeBinding(index, computeFlags(choice)), Choice(choice),
34203455
ExplicitConversion(explicitConversion) {}
34213456

3422-
bool isDisabled() const override { return Choice->isDisabled(); }
3423-
3424-
bool isUnavailable() const override {
3425-
if (auto *decl = getDecl(Choice))
3426-
return decl->getAttrs().isUnavailable(decl->getASTContext());
3427-
return false;
3428-
}
3429-
3430-
// FIXME: Both of the accessors below are required to support
3431-
// performance optimization hacks in constraint solver.
3432-
3433-
bool isGenericOperator() const override;
3434-
bool isSymmetricOperator() const override;
3435-
34363457
void attempt(ConstraintSystem &cs) const override;
34373458

34383459
void print(llvm::raw_ostream &Out, SourceManager *SM) const override {
@@ -3444,8 +3465,17 @@ class DisjunctionChoice : public TypeBinding {
34443465
/// let's try to propagate its type early to prune search space.
34453466
void propagateConversionInfo(ConstraintSystem &cs) const;
34463467

3447-
ValueDecl *getOperatorDecl() const {
3448-
auto *decl = getDecl(Choice);
3468+
static bool isUnavailable(Constraint *choice) {
3469+
if (auto *decl = getDecl(choice))
3470+
return decl->getAttrs().isUnavailable(decl->getASTContext());
3471+
return false;
3472+
}
3473+
3474+
static bool isGenericOp(Constraint *choice);
3475+
static bool isSymmetricOp(Constraint *choice);
3476+
3477+
static ValueDecl *getOperatorDecl(Constraint *choice) {
3478+
auto *decl = getDecl(choice);
34493479
if (!decl)
34503480
return nullptr;
34513481

@@ -3462,6 +3492,19 @@ class DisjunctionChoice : public TypeBinding {
34623492

34633493
return choice.getDecl();
34643494
}
3495+
3496+
static TypeBindingFlags computeFlags(Constraint *choice) {
3497+
TypeBindingFlags flags;
3498+
if (choice->isDisabled())
3499+
flags |= TypeBindingFlag::Disabled;
3500+
if (isUnavailable(choice))
3501+
flags |= TypeBindingFlag::Unavailable;
3502+
if (isGenericOp(choice))
3503+
flags |= TypeBindingFlag::GenericOperator;
3504+
if (isSymmetricOp(choice))
3505+
flags |= TypeBindingFlag::SymmetricOperator;
3506+
return flags;
3507+
}
34653508
};
34663509

34673510
class TypeVariableBinding : public TypeBinding {
@@ -3471,19 +3514,25 @@ class TypeVariableBinding : public TypeBinding {
34713514
public:
34723515
TypeVariableBinding(unsigned index, TypeVariableType *typeVar,
34733516
ConstraintSystem::PotentialBinding &binding)
3474-
: TypeBinding(index), TypeVar(typeVar), Binding(binding) {}
3517+
: TypeBinding(index, computeFlags(binding)), TypeVar(typeVar),
3518+
Binding(binding) {}
34753519

34763520
void attempt(ConstraintSystem &cs) const override;
34773521

3478-
bool isDefaultable() const override { return Binding.isDefaultableBinding(); }
3479-
3480-
bool hasDefaultedProtocol() const override {
3481-
return Binding.DefaultedProtocol;
3482-
}
3483-
34843522
void print(llvm::raw_ostream &Out, SourceManager *) const override {
34853523
Out << TypeVar->getString() << " := " << Binding.BindingType->getString();
34863524
}
3525+
3526+
private:
3527+
static TypeBindingFlags
3528+
computeFlags(ConstraintSystem::PotentialBinding &binding) {
3529+
TypeBindingFlags flags;
3530+
if (binding.isDefaultableBinding())
3531+
flags |= TypeBindingFlag::Defaultable;
3532+
if (binding.DefaultedProtocol)
3533+
flags |= TypeBindingFlag::HasDefaultedProtocol;
3534+
return flags;
3535+
}
34873536
};
34883537

34893538
template<typename Choice>

0 commit comments

Comments
 (0)