@@ -3381,31 +3381,66 @@ void simplifyLocator(Expr *&anchor,
3381
3381
// / null otherwise.
3382
3382
Expr *simplifyLocatorToAnchor (ConstraintSystem &cs, ConstraintLocator *locator);
3383
3383
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
+
3384
3403
// / Common interface to encapsulate attempting choices of
3385
3404
// / different entities, such as type variables (types)
3386
3405
// / or disjunctions (their choices).
3387
3406
class TypeBinding {
3388
3407
unsigned Index;
3408
+ TypeBindingFlags Flags;
3389
3409
3390
3410
public:
3391
- TypeBinding (unsigned index) : Index(index) {}
3411
+ TypeBinding (unsigned index, TypeBindingFlags flags)
3412
+ : Index(index), Flags(flags) {}
3392
3413
3393
3414
virtual ~TypeBinding () {}
3394
3415
virtual void attempt (ConstraintSystem &cs) const = 0;
3395
3416
3396
3417
// / Position of this binding in the chain.
3397
3418
unsigned getIndex () const { return Index; }
3398
3419
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
+ }
3403
3433
3404
3434
// FIXME: Both of the accessors below are required to support
3405
3435
// performance optimization hacks in constraint solver.
3406
3436
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
+ }
3409
3444
3410
3445
virtual void print (llvm::raw_ostream &Out, SourceManager *SM) const = 0;
3411
3446
};
@@ -3416,23 +3451,9 @@ class DisjunctionChoice : public TypeBinding {
3416
3451
3417
3452
public:
3418
3453
DisjunctionChoice (unsigned index, Constraint *choice, bool explicitConversion)
3419
- : TypeBinding(index), Choice(choice),
3454
+ : TypeBinding(index, computeFlags(choice) ), Choice(choice),
3420
3455
ExplicitConversion (explicitConversion) {}
3421
3456
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
-
3436
3457
void attempt (ConstraintSystem &cs) const override ;
3437
3458
3438
3459
void print (llvm::raw_ostream &Out, SourceManager *SM) const override {
@@ -3444,8 +3465,17 @@ class DisjunctionChoice : public TypeBinding {
3444
3465
// / let's try to propagate its type early to prune search space.
3445
3466
void propagateConversionInfo (ConstraintSystem &cs) const ;
3446
3467
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);
3449
3479
if (!decl)
3450
3480
return nullptr ;
3451
3481
@@ -3462,6 +3492,19 @@ class DisjunctionChoice : public TypeBinding {
3462
3492
3463
3493
return choice.getDecl ();
3464
3494
}
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
+ }
3465
3508
};
3466
3509
3467
3510
class TypeVariableBinding : public TypeBinding {
@@ -3471,19 +3514,25 @@ class TypeVariableBinding : public TypeBinding {
3471
3514
public:
3472
3515
TypeVariableBinding (unsigned index, TypeVariableType *typeVar,
3473
3516
ConstraintSystem::PotentialBinding &binding)
3474
- : TypeBinding(index), TypeVar(typeVar), Binding(binding) {}
3517
+ : TypeBinding(index, computeFlags(binding)), TypeVar(typeVar),
3518
+ Binding (binding) {}
3475
3519
3476
3520
void attempt (ConstraintSystem &cs) const override ;
3477
3521
3478
- bool isDefaultable () const override { return Binding.isDefaultableBinding (); }
3479
-
3480
- bool hasDefaultedProtocol () const override {
3481
- return Binding.DefaultedProtocol ;
3482
- }
3483
-
3484
3522
void print (llvm::raw_ostream &Out, SourceManager *) const override {
3485
3523
Out << TypeVar->getString () << " := " << Binding.BindingType ->getString ();
3486
3524
}
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
+ }
3487
3536
};
3488
3537
3489
3538
template <typename Choice>
0 commit comments