@@ -4638,13 +4638,13 @@ class ConstraintSystem {
4638
4638
4639
4639
PotentialBinding (Type type, AllowedBindingKind kind,
4640
4640
PointerUnion<Constraint *, ConstraintLocator *> source)
4641
- : BindingType(type->getWithoutParens ()), Kind(kind),
4642
- BindingSource(source) {}
4641
+ : BindingType(type), Kind(kind), BindingSource(source) {}
4643
4642
4644
4643
public:
4645
4644
PotentialBinding (Type type, AllowedBindingKind kind, Constraint *source)
4646
- : BindingType(type->getWithoutParens ()), Kind(kind),
4647
- BindingSource(source) {}
4645
+ : PotentialBinding(
4646
+ type->getWithoutParens (), kind,
4647
+ PointerUnion<Constraint *, ConstraintLocator *>(source)) {}
4648
4648
4649
4649
bool isDefaultableBinding () const {
4650
4650
if (auto *constraint = BindingSource.dyn_cast <Constraint *>())
@@ -4695,6 +4695,11 @@ class ConstraintSystem {
4695
4695
AllowedBindingKind::Exact,
4696
4696
/* source=*/ locator};
4697
4697
}
4698
+
4699
+ static PotentialBinding forPlaceholder (Type placeholderTy) {
4700
+ return {placeholderTy, AllowedBindingKind::Exact,
4701
+ PointerUnion<Constraint *, ConstraintLocator *>()};
4702
+ }
4698
4703
};
4699
4704
4700
4705
struct LiteralRequirement {
@@ -4751,7 +4756,7 @@ class ConstraintSystem {
4751
4756
TypeVariableType *TypeVar;
4752
4757
4753
4758
// / The set of potential bindings.
4754
- SmallVector <PotentialBinding, 4 > Bindings;
4759
+ llvm::SmallSetVector <PotentialBinding, 4 > Bindings;
4755
4760
4756
4761
// / The set of protocol requirements placed on this type variable.
4757
4762
llvm::SmallVector<Constraint *, 4 > Protocols;
@@ -4981,13 +4986,21 @@ class ConstraintSystem {
4981
4986
// / \param canBeNil The flag that determines whether given type
4982
4987
// / variable requires all of its bindings to be optional.
4983
4988
// /
4984
- // / \returns true if binding covers given literal protocol.
4985
- bool isLiteralCoveredBy (const LiteralRequirement &literal,
4986
- PotentialBinding &binding, bool canBeNil) const ;
4989
+ // / \returns a pair of bool and a type:
4990
+ // / - bool, true if binding covers given literal protocol;
4991
+ // / - type, non-null if binding type has to be adjusted
4992
+ // / to cover given literal protocol;
4993
+ std::pair<bool , Type> isLiteralCoveredBy (const LiteralRequirement &literal,
4994
+ const PotentialBinding &binding,
4995
+ bool canBeNil) const ;
4987
4996
4988
4997
// / Add a potential binding to the list of bindings,
4989
4998
// / coalescing supertype bounds when we are able to compute the meet.
4990
- void addPotentialBinding (PotentialBinding binding,
4999
+ // /
5000
+ // / \returns true if this binding has been added to the set,
5001
+ // / false otherwise (e.g. because binding with this type is
5002
+ // / already in the set).
5003
+ bool addPotentialBinding (PotentialBinding binding,
4991
5004
bool allowJoinMeet = true );
4992
5005
4993
5006
// / Check if this binding is viable for inclusion in the set.
@@ -5024,13 +5037,9 @@ class ConstraintSystem {
5024
5037
// /
5025
5038
// / Which gives us a new (superclass A) binding for T2 as well as T1.
5026
5039
// /
5027
- // / \param cs The constraint system this type variable is associated with.
5028
- // /
5029
5040
// / \param inferredBindings The set of all bindings inferred for type
5030
5041
// / variables in the workset.
5031
5042
void inferTransitiveBindings (
5032
- ConstraintSystem &cs,
5033
- llvm::SmallPtrSetImpl<CanType> &existingTypes,
5034
5043
const llvm::SmallDenseMap<TypeVariableType *,
5035
5044
ConstraintSystem::PotentialBindings>
5036
5045
&inferredBindings);
@@ -5039,20 +5048,16 @@ class ConstraintSystem {
5039
5048
// / between two type variables and attempt to propagate protocol
5040
5049
// / requirements down the subtype or equivalence chain.
5041
5050
void inferTransitiveProtocolRequirements (
5042
- const ConstraintSystem &cs,
5043
5051
llvm::SmallDenseMap<TypeVariableType *,
5044
5052
ConstraintSystem::PotentialBindings>
5045
5053
&inferredBindings);
5046
5054
5047
5055
public:
5048
- bool infer (ConstraintSystem &cs,
5049
- llvm::SmallPtrSetImpl<CanType> &exactTypes,
5050
- Constraint *constraint);
5056
+ bool infer (Constraint *constraint);
5051
5057
5052
5058
// / Finalize binding computation for this type variable by
5053
5059
// / inferring bindings from context e.g. transitive bindings.
5054
- void finalize (ConstraintSystem &cs,
5055
- llvm::SmallDenseMap<TypeVariableType *,
5060
+ void finalize (llvm::SmallDenseMap<TypeVariableType *,
5056
5061
ConstraintSystem::PotentialBindings>
5057
5062
&inferredBindings);
5058
5063
@@ -6233,6 +6238,54 @@ struct DenseMapInfo<swift::constraints::SolutionApplicationTargetsKey> {
6233
6238
}
6234
6239
};
6235
6240
6241
+ template <>
6242
+ struct DenseMapInfo <swift::constraints::ConstraintSystem::PotentialBinding> {
6243
+ using Binding = swift::constraints::ConstraintSystem::PotentialBinding;
6244
+
6245
+ static Binding getEmptyKey () {
6246
+ return placeholderKey (llvm::DenseMapInfo<swift::TypeBase *>::getEmptyKey ());
6247
+ }
6248
+
6249
+ static Binding getTombstoneKey () {
6250
+ return placeholderKey (
6251
+ llvm::DenseMapInfo<swift::TypeBase *>::getTombstoneKey ());
6252
+ }
6253
+
6254
+ static unsigned getHashValue (const Binding &Val) {
6255
+ return DenseMapInfo<swift::Type>::getHashValue (
6256
+ Val.BindingType ->getCanonicalType ());
6257
+ }
6258
+
6259
+ static bool isEqual (const Binding &LHS, const Binding &RHS) {
6260
+ auto lhsTy = LHS.BindingType .getPointer ();
6261
+ auto rhsTy = RHS.BindingType .getPointer ();
6262
+
6263
+ // Fast path: pointer equality.
6264
+ if (DenseMapInfo<swift::TypeBase *>::isEqual (lhsTy, rhsTy))
6265
+ return true ;
6266
+
6267
+ // If either side is empty or tombstone, let's use pointer equality.
6268
+ {
6269
+ auto emptyTy = llvm::DenseMapInfo<swift::TypeBase *>::getEmptyKey ();
6270
+ auto tombstoneTy =
6271
+ llvm::DenseMapInfo<swift::TypeBase *>::getTombstoneKey ();
6272
+
6273
+ if (lhsTy == emptyTy || lhsTy == tombstoneTy)
6274
+ return lhsTy == rhsTy;
6275
+
6276
+ if (rhsTy == emptyTy || rhsTy == tombstoneTy)
6277
+ return lhsTy == rhsTy;
6278
+ }
6279
+
6280
+ // Otherwise let's drop the sugar and check.
6281
+ return LHS.BindingType ->isEqual (RHS.BindingType );
6282
+ }
6283
+
6284
+ private:
6285
+ static Binding placeholderKey (swift::Type type) {
6286
+ return Binding::forPlaceholder (type);
6287
+ }
6288
+ };
6236
6289
}
6237
6290
6238
6291
#endif // LLVM_SWIFT_SEMA_CONSTRAINT_SYSTEM_H
0 commit comments