@@ -4638,13 +4638,13 @@ class ConstraintSystem {
46384638
46394639 PotentialBinding (Type type, AllowedBindingKind kind,
46404640 PointerUnion<Constraint *, ConstraintLocator *> source)
4641- : BindingType(type->getWithoutParens ()), Kind(kind),
4642- BindingSource(source) {}
4641+ : BindingType(type), Kind(kind), BindingSource(source) {}
46434642
46444643 public:
46454644 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)) {}
46484648
46494649 bool isDefaultableBinding () const {
46504650 if (auto *constraint = BindingSource.dyn_cast <Constraint *>())
@@ -4695,6 +4695,11 @@ class ConstraintSystem {
46954695 AllowedBindingKind::Exact,
46964696 /* source=*/ locator};
46974697 }
4698+
4699+ static PotentialBinding forPlaceholder (Type placeholderTy) {
4700+ return {placeholderTy, AllowedBindingKind::Exact,
4701+ PointerUnion<Constraint *, ConstraintLocator *>()};
4702+ }
46984703 };
46994704
47004705 struct LiteralRequirement {
@@ -4751,7 +4756,7 @@ class ConstraintSystem {
47514756 TypeVariableType *TypeVar;
47524757
47534758 // / The set of potential bindings.
4754- SmallVector <PotentialBinding, 4 > Bindings;
4759+ llvm::SmallSetVector <PotentialBinding, 4 > Bindings;
47554760
47564761 // / The set of protocol requirements placed on this type variable.
47574762 llvm::SmallVector<Constraint *, 4 > Protocols;
@@ -4981,13 +4986,21 @@ class ConstraintSystem {
49814986 // / \param canBeNil The flag that determines whether given type
49824987 // / variable requires all of its bindings to be optional.
49834988 // /
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 ;
49874996
49884997 // / Add a potential binding to the list of bindings,
49894998 // / 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,
49915004 bool allowJoinMeet = true );
49925005
49935006 // / Check if this binding is viable for inclusion in the set.
@@ -5024,13 +5037,9 @@ class ConstraintSystem {
50245037 // /
50255038 // / Which gives us a new (superclass A) binding for T2 as well as T1.
50265039 // /
5027- // / \param cs The constraint system this type variable is associated with.
5028- // /
50295040 // / \param inferredBindings The set of all bindings inferred for type
50305041 // / variables in the workset.
50315042 void inferTransitiveBindings (
5032- ConstraintSystem &cs,
5033- llvm::SmallPtrSetImpl<CanType> &existingTypes,
50345043 const llvm::SmallDenseMap<TypeVariableType *,
50355044 ConstraintSystem::PotentialBindings>
50365045 &inferredBindings);
@@ -5039,20 +5048,16 @@ class ConstraintSystem {
50395048 // / between two type variables and attempt to propagate protocol
50405049 // / requirements down the subtype or equivalence chain.
50415050 void inferTransitiveProtocolRequirements (
5042- const ConstraintSystem &cs,
50435051 llvm::SmallDenseMap<TypeVariableType *,
50445052 ConstraintSystem::PotentialBindings>
50455053 &inferredBindings);
50465054
50475055public:
5048- bool infer (ConstraintSystem &cs,
5049- llvm::SmallPtrSetImpl<CanType> &exactTypes,
5050- Constraint *constraint);
5056+ bool infer (Constraint *constraint);
50515057
50525058 // / Finalize binding computation for this type variable by
50535059 // / inferring bindings from context e.g. transitive bindings.
5054- void finalize (ConstraintSystem &cs,
5055- llvm::SmallDenseMap<TypeVariableType *,
5060+ void finalize (llvm::SmallDenseMap<TypeVariableType *,
50565061 ConstraintSystem::PotentialBindings>
50575062 &inferredBindings);
50585063
@@ -6233,6 +6238,54 @@ struct DenseMapInfo<swift::constraints::SolutionApplicationTargetsKey> {
62336238 }
62346239};
62356240
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+ };
62366289}
62376290
62386291#endif // LLVM_SWIFT_SEMA_CONSTRAINT_SYSTEM_H
0 commit comments