@@ -152,6 +152,8 @@ struct PotentialBinding {
152152};
153153
154154struct LiteralRequirement {
155+ // / The literal protocol.
156+ ProtocolDecl *Protocol;
155157 // / The source of the literal requirement.
156158 Constraint *Source;
157159 // / The default type associated with this literal (if any).
@@ -164,17 +166,23 @@ struct LiteralRequirement {
164166 // / this points to the source of the binding.
165167 mutable Constraint *CoveredBy = nullptr ;
166168
167- LiteralRequirement (Constraint *source, Type defaultTy, bool isDirect)
168- : Source(source), DefaultType(defaultTy), IsDirectRequirement(isDirect) {}
169+ LiteralRequirement (ProtocolDecl *protocol, Constraint *source,
170+ Type defaultTy, bool isDirect)
171+ : Protocol(protocol), Source(source), DefaultType(defaultTy),
172+ IsDirectRequirement (isDirect) {}
169173
170174 Constraint *getSource () const { return Source; }
171175
172- ProtocolDecl *getProtocol () const { return Source-> getProtocol () ; }
176+ ProtocolDecl *getProtocol () const { return Protocol ; }
173177
174178 bool isCovered () const { return bool (CoveredBy); }
175179
176180 bool isDirectRequirement () const { return IsDirectRequirement; }
177181
182+ void setDirectRequirement (bool isDirectRequirement) {
183+ IsDirectRequirement = isDirectRequirement;
184+ }
185+
178186 bool hasDefaultType () const { return bool (DefaultType); }
179187
180188 Type getDefaultType () const {
@@ -241,6 +249,16 @@ struct PotentialBindings {
241249 llvm::SmallVector<std::pair<TypeVariableType *, Constraint *>, 4 > SupertypeOf;
242250 llvm::SmallVector<std::pair<TypeVariableType *, Constraint *>, 4 > EquivalentTo;
243251
252+ // / The set of protocol conformance requirements imposed on this type variable.
253+ llvm::SmallVector<Constraint *, 4 > Protocols;
254+
255+ // / The set of unique literal protocol requirements placed on this
256+ // / type variable.
257+ llvm::SmallVector<LiteralRequirement, 2 > Literals;
258+
259+ // / The set of fallback constraints imposed on this type variable.
260+ llvm::SmallVector<Constraint *, 2 > Defaults;
261+
244262 ASTNode AssociatedCodeCompletionToken = ASTNode();
245263
246264 // / Add a potential binding to the list of bindings,
@@ -256,7 +274,14 @@ struct PotentialBindings {
256274 });
257275 }
258276
259- private:
277+ ArrayRef<Constraint *> getConformanceRequirements () const {
278+ return Protocols;
279+ }
280+
281+ void inferFromLiteral (ConstraintSystem &CS,
282+ TypeVariableType *TypeVar,
283+ Constraint *literal);
284+
260285 // / Attempt to infer a new binding and other useful information
261286 // / (i.e. whether bindings should be delayed) from the given
262287 // / relational constraint.
@@ -265,7 +290,6 @@ struct PotentialBindings {
265290 TypeVariableType *TypeVar,
266291 Constraint *constraint);
267292
268- public:
269293 void infer (ConstraintSystem &CS,
270294 TypeVariableType *TypeVar,
271295 Constraint *constraint);
@@ -365,18 +389,15 @@ class BindingSet {
365389public:
366390 swift::SmallSetVector<PotentialBinding, 4 > Bindings;
367391
368- // / The set of protocol conformance requirements placed on this type variable.
369- llvm::SmallVector<Constraint *, 4 > Protocols;
370-
371392 // / The set of unique literal protocol requirements placed on this
372393 // / type variable or inferred transitively through subtype chains.
373394 // /
374395 // / Note that ordering is important when it comes to bindings, we'd
375396 // / like to add any "direct" default types first to attempt them
376397 // / before transitive ones.
377- llvm::SmallMapVector<ProtocolDecl *, LiteralRequirement, 2 > Literals;
398+ llvm::SmallVector< LiteralRequirement, 2 > Literals;
378399
379- llvm::SmallDenseMap<CanType, Constraint *, 2 > Defaults;
400+ llvm::SmallVector< Constraint *, 2 > Defaults;
380401
381402 // / The set of transitive protocol requirements inferred through
382403 // / subtype/conversion/equivalence relations with other type variables.
@@ -389,8 +410,6 @@ class BindingSet {
389410
390411 BindingSet (const BindingSet &other) = delete ;
391412
392- ConstraintSystem &getConstraintSystem () const { return CS; }
393-
394413 TypeVariableType *getTypeVariable () const { return TypeVar; }
395414
396415 // / Check whether this binding set belongs to a type variable
@@ -457,7 +476,7 @@ class BindingSet {
457476 // Literal requirements always result in a subtype/supertype
458477 // relationship to a concrete type.
459478 if (llvm::any_of (Literals, [](const auto &literal) {
460- return literal.second . viableAsBinding ();
479+ return literal.viableAsBinding ();
461480 }))
462481 return false ;
463482
@@ -494,19 +513,15 @@ class BindingSet {
494513 return hasViableBindings () || isDirectHole ();
495514 }
496515
497- ArrayRef<Constraint *> getConformanceRequirements () const {
498- return Protocols;
499- }
500-
501516 unsigned getNumViableLiteralBindings () const ;
502517
503518 unsigned getNumViableDefaultableBindings () const {
504519 if (isDirectHole ())
505520 return 1 ;
506521
507522 auto numDefaultable = llvm::count_if (
508- Defaults, [](const std::pair<CanType, Constraint *> &entry ) {
509- return entry. second ->getKind () == ConstraintKind::Defaultable;
523+ Defaults, [](Constraint *constraint ) {
524+ return constraint ->getKind () == ConstraintKind::Defaultable;
510525 });
511526
512527 // Short-circuit unviable checks if there are no defaultable bindings.
@@ -518,10 +533,12 @@ class BindingSet {
518533 auto unviable =
519534 llvm::count_if (Bindings, [&](const PotentialBinding &binding) {
520535 auto type = binding.BindingType ->getCanonicalType ();
521- auto def = Defaults.find (type);
522- return def != Defaults.end ()
523- ? def->second ->getKind () == ConstraintKind::Defaultable
524- : false ;
536+ for (auto *constraint : Defaults) {
537+ if (constraint->getSecondType ()->isEqual (type)) {
538+ return constraint->getKind () == ConstraintKind::Defaultable;
539+ }
540+ }
541+ return false ;
525542 });
526543
527544 assert (numDefaultable >= unviable);
@@ -572,6 +589,11 @@ class BindingSet {
572589 // / requirements down the subtype or equivalence chain.
573590 void inferTransitiveProtocolRequirements ();
574591
592+ // / Try to coalesce integer and floating point literal protocols
593+ // / if they appear together because the only possible default type that
594+ // / could satisfy both requirements is `Double`.
595+ void coalesceIntegerAndFloatLiteralRequirements ();
596+
575597 // / Check whether the given binding set covers any of the literal protocols
576598 // / associated with this type variable. The idea is that if a type variable
577599 // / has a binding like Int and also it has a conformance requirement to
@@ -607,8 +629,6 @@ class BindingSet {
607629 // / checking.
608630 void addBinding (PotentialBinding binding, bool isTransitive);
609631
610- void addLiteralRequirement (Constraint *literal);
611-
612632 void addDefault (Constraint *constraint);
613633
614634 StringRef getLiteralBindingKind (LiteralBindingKind K) const {
0 commit comments