@@ -66,12 +66,6 @@ class SolutionApplicationTarget;
6666
6767} // end namespace constraints
6868
69- namespace unittest {
70-
71- class SemaTest ;
72-
73- } // end namespace unittest
74-
7569// Forward declare some TypeChecker related functions
7670// so they could be made friends of ConstraintSystem.
7771namespace TypeChecker {
@@ -2026,8 +2020,6 @@ enum class SolutionApplicationToFunctionResult {
20262020class ConstraintSystem {
20272021 ASTContext &Context;
20282022
2029- friend class swift ::unittest::SemaTest;
2030-
20312023public:
20322024 DeclContext *DC;
20332025 ConstraintSystemOptions Options;
@@ -4625,7 +4617,8 @@ class ConstraintSystem {
46254617 ConstraintKind bodyResultConstraintKind,
46264618 ConstraintLocatorBuilder locator);
46274619
4628- private:
4620+ public: // binding inference logic is public for unit testing.
4621+
46294622 // / The kind of bindings that are permitted.
46304623 enum class AllowedBindingKind : uint8_t {
46314624 // / Only the exact type.
@@ -4700,6 +4693,8 @@ class ConstraintSystem {
47004693 return BindingSource.get <ConstraintLocator *>();
47014694 }
47024695
4696+ Constraint *getSource () const { return BindingSource.get <Constraint *>(); }
4697+
47034698 PotentialBinding withType (Type type) const {
47044699 return {type, Kind, BindingSource};
47054700 }
@@ -4721,6 +4716,50 @@ class ConstraintSystem {
47214716 }
47224717 };
47234718
4719+ struct LiteralRequirement {
4720+ // / The source of the literal requirement.
4721+ Constraint *Source;
4722+ // / The default type associated with this literal (if any).
4723+ Type DefaultType;
4724+ // / Determines whether this literal is a direct requirement
4725+ // / of the current type variable.
4726+ bool IsDirectRequirement;
4727+
4728+ // / If the literal is covered by existing type binding,
4729+ // / this points to the source of the binding.
4730+ mutable Constraint *CoveredBy = nullptr ;
4731+
4732+ LiteralRequirement (Constraint *source, Type defaultTy, bool isDirect)
4733+ : Source(source), DefaultType(defaultTy),
4734+ IsDirectRequirement (isDirect) {}
4735+
4736+ Constraint *getSource () const { return Source; }
4737+
4738+ ProtocolDecl *getProtocol () const { return Source->getProtocol (); }
4739+
4740+ bool isCovered () const { return bool (CoveredBy); }
4741+
4742+ bool isDirectRequirement () const { return IsDirectRequirement; }
4743+
4744+ bool hasDefaultType () const { return bool (DefaultType); }
4745+
4746+ Type getDefaultType () const {
4747+ assert (hasDefaultType ());
4748+ return DefaultType;
4749+ }
4750+
4751+ void setCoveredBy (Constraint *coveredBy) {
4752+ assert (!isCovered ());
4753+ CoveredBy = coveredBy;
4754+ }
4755+
4756+ bool isCoveredBy (Type type, DeclContext *useDC) const ;
4757+
4758+ // / Determines whether literal protocol associated with this
4759+ // / meta-information is viable for inclusion as a defaultable binding.
4760+ bool viableAsBinding () const { return !isCovered () && hasDefaultType (); }
4761+ };
4762+
47244763 struct PotentialBindings {
47254764 using BindingScore =
47264765 std::tuple<bool , bool , bool , bool , bool , unsigned char , int >;
@@ -4740,6 +4779,14 @@ class ConstraintSystem {
47404779 // / subtype/conversion/equivalence relations with other type variables.
47414780 Optional<llvm::SmallPtrSet<Constraint *, 4 >> TransitiveProtocols;
47424781
4782+ // / The set of unique literal protocol requirements placed on this
4783+ // / type variable or inferred transitively through subtype chains.
4784+ // /
4785+ // / Note that ordering is important when it comes to bindings, we'd
4786+ // / like to add any "direct" default types first to attempt them
4787+ // / before transitive ones.
4788+ llvm::SmallMapVector<ProtocolDecl *, LiteralRequirement, 2 > Literals;
4789+
47434790 // / The set of constraints which would be used to infer default types.
47444791 llvm::SmallDenseMap<CanType, Constraint *, 2 > Defaults;
47454792
@@ -4756,9 +4803,6 @@ class ConstraintSystem {
47564803
47574804 ASTNode AssociatedCodeCompletionToken = ASTNode();
47584805
4759- // / Whether this type variable has literal bindings.
4760- LiteralBindingKind LiteralBinding = LiteralBindingKind::None;
4761-
47624806 // / A set of all not-yet-resolved type variables this type variable
47634807 // / is a subtype of, supertype of or is equivalent to. This is used
47644808 // / to determine ordering inside of a chain of subtypes to help infer
@@ -4772,9 +4816,14 @@ class ConstraintSystem {
47724816
47734817 // / Determine whether the set of bindings is non-empty.
47744818 explicit operator bool () const {
4775- return !Bindings.empty () || !Defaults.empty () || isDirectHole ();
4819+ return !Bindings.empty () || getNumViableLiteralBindings () > 0 ||
4820+ !Defaults.empty () || isDirectHole ();
47764821 }
47774822
4823+ // / Determines whether this type variable could be `nil`,
4824+ // / which means that all of its bindings should be optional.
4825+ bool canBeNil () const ;
4826+
47784827 // / Determine whether attempting this type variable should be
47794828 // / delayed until the rest of the constraint system is considered
47804829 // / "fully bound" meaning constraints, which affect completeness
@@ -4822,8 +4871,8 @@ class ConstraintSystem {
48224871 if (!CS.shouldAttemptFixes ())
48234872 return false ;
48244873
4825- return Bindings.empty () && Defaults. empty () &&
4826- TypeVar->getImpl ().canBindToHole ();
4874+ return Bindings.empty () && getNumViableLiteralBindings () == 0 &&
4875+ Defaults. empty () && TypeVar->getImpl ().canBindToHole ();
48274876 }
48284877
48294878 // / Determine if the bindings only constrain the type variable from above
@@ -4839,6 +4888,8 @@ class ConstraintSystem {
48394888 });
48404889 }
48414890
4891+ unsigned getNumViableLiteralBindings () const ;
4892+
48424893 unsigned getNumViableDefaultableBindings () const {
48434894 if (isDirectHole ())
48444895 return 1 ;
@@ -4875,16 +4926,19 @@ class ConstraintSystem {
48754926 // It's considered to be non-default for purposes of
48764927 // ranking because we'd like to prioritize resolving
48774928 // closures to gain more information from their bodies.
4878- auto numNonDefaultableBindings =
4879- !b.Bindings .empty () ? b.Bindings .size ()
4880- : b.TypeVar ->getImpl ().isClosureType () ? 1 : 0 ;
4929+ unsigned numBindings =
4930+ b.Bindings .size () + b.getNumViableLiteralBindings ();
4931+ auto numNonDefaultableBindings = numBindings > 0 ? numBindings
4932+ : b.TypeVar ->getImpl ().isClosureType ()
4933+ ? 1
4934+ : 0 ;
48814935
48824936 return std::make_tuple (b.isHole (),
48834937 numNonDefaultableBindings == 0 ,
48844938 b.isDelayed (),
48854939 b.isSubtypeOfExistentialType (),
48864940 b.involvesTypeVariables (),
4887- static_cast <unsigned char >(b.LiteralBinding ),
4941+ static_cast <unsigned char >(b.getLiteralKind () ),
48884942 -numNonDefaultableBindings);
48894943 }
48904944
@@ -4928,26 +4982,27 @@ class ConstraintSystem {
49284982 return x.isPotentiallyIncomplete () < y.isPotentiallyIncomplete ();
49294983 }
49304984
4931- void foundLiteralBinding (ProtocolDecl *proto) {
4932- switch (*proto->getKnownProtocolKind ()) {
4933- case KnownProtocolKind::ExpressibleByDictionaryLiteral:
4934- case KnownProtocolKind::ExpressibleByArrayLiteral:
4935- case KnownProtocolKind::ExpressibleByStringInterpolation:
4936- LiteralBinding = LiteralBindingKind::Collection;
4937- break ;
4985+ LiteralBindingKind getLiteralKind () const ;
49384986
4939- case KnownProtocolKind::ExpressibleByFloatLiteral:
4940- LiteralBinding = LiteralBindingKind::Float;
4941- break ;
4987+ void addDefault (Constraint *constraint);
49424988
4943- default :
4944- if (LiteralBinding != LiteralBindingKind::Collection)
4945- LiteralBinding = LiteralBindingKind::Atom;
4946- break ;
4947- }
4948- }
4989+ void addLiteral (Constraint *constraint);
49494990
4950- void addDefault (Constraint *constraint);
4991+ // / Determines whether the given literal protocol is "covered"
4992+ // / by the given binding - type of the binding could either be
4993+ // / equal (in canonical sense) to the protocol's default type,
4994+ // / or conform to a protocol.
4995+ // /
4996+ // / \param literal The literal protocol requirement to check.
4997+ // /
4998+ // / \param binding The binding to check for coverage.
4999+ // /
5000+ // / \param canBeNil The flag that determines whether given type
5001+ // / variable requires all of its bindings to be optional.
5002+ // /
5003+ // / \returns true if binding covers given literal protocol.
5004+ bool isLiteralCoveredBy (const LiteralRequirement &literal,
5005+ PotentialBinding &binding, bool canBeNil) const ;
49515006
49525007 // / Add a potential binding to the list of bindings,
49535008 // / coalescing supertype bounds when we are able to compute the meet.
@@ -5008,11 +5063,6 @@ class ConstraintSystem {
50085063 ConstraintSystem::PotentialBindings>
50095064 &inferredBindings);
50105065
5011- // / Infer bindings based on any protocol conformances that have default
5012- // / types.
5013- void inferDefaultTypes (ConstraintSystem &cs,
5014- llvm::SmallPtrSetImpl<CanType> &existingTypes);
5015-
50165066public:
50175067 bool infer (ConstraintSystem &cs,
50185068 llvm::SmallPtrSetImpl<CanType> &exactTypes,
@@ -5036,8 +5086,9 @@ class ConstraintSystem {
50365086 out << " delayed " ;
50375087 if (isSubtypeOfExistentialType ())
50385088 out << " subtype_of_existential " ;
5039- if (LiteralBinding != LiteralBindingKind::None)
5040- out << " literal=" << static_cast <int >(LiteralBinding) << " " ;
5089+ auto literalKind = getLiteralKind ();
5090+ if (literalKind != LiteralBindingKind::None)
5091+ out << " literal=" << static_cast <int >(literalKind) << " " ;
50415092 if (involvesTypeVariables ())
50425093 out << " involves_type_vars " ;
50435094
@@ -5102,7 +5153,6 @@ class ConstraintSystem {
51025153 Optional<Type> checkTypeOfBinding (TypeVariableType *typeVar, Type type) const ;
51035154 Optional<PotentialBindings> determineBestBindings ();
51045155
5105- public:
51065156 // / Infer bindings for the given type variable based on current
51075157 // / state of the constraint system.
51085158 PotentialBindings inferBindingsFor (TypeVariableType *typeVar,
0 commit comments