@@ -4741,7 +4741,7 @@ class ConstraintSystem {
47414741 Optional<llvm::SmallPtrSet<Constraint *, 4 >> TransitiveProtocols;
47424742
47434743 // / The set of constraints which would be used to infer default types.
4744- llvm::TinyPtrVector< Constraint *> Defaults;
4744+ llvm::SmallDenseMap<CanType, Constraint *, 2 > Defaults;
47454745
47464746 // / The set of constraints which delay attempting this type variable.
47474747 llvm::TinyPtrVector<Constraint *> DelayedBy;
@@ -4772,7 +4772,7 @@ class ConstraintSystem {
47724772
47734773 // / Determine whether the set of bindings is non-empty.
47744774 explicit operator bool () const {
4775- return !Bindings.empty () || isDirectHole ();
4775+ return !Bindings.empty () || !Defaults. empty () || isDirectHole ();
47764776 }
47774777
47784778 // / Determine whether attempting this type variable should be
@@ -4822,7 +4822,8 @@ class ConstraintSystem {
48224822 if (!CS.shouldAttemptFixes ())
48234823 return false ;
48244824
4825- return Bindings.empty () && TypeVar->getImpl ().canBindToHole ();
4825+ return Bindings.empty () && Defaults.empty () &&
4826+ TypeVar->getImpl ().canBindToHole ();
48264827 }
48274828
48284829 // / Determine if the bindings only constrain the type variable from above
@@ -4838,19 +4839,38 @@ class ConstraintSystem {
48384839 });
48394840 }
48404841
4841- unsigned getNumDefaultableBindings () const {
4842- return isDirectHole ()
4843- ? 1
4844- : llvm::count_if (Bindings,
4845- [](const PotentialBinding &binding) {
4846- return binding.isDefaultableBinding ();
4847- });
4842+ unsigned getNumViableDefaultableBindings () const {
4843+ if (isDirectHole ())
4844+ return 1 ;
4845+
4846+ // We might want to consider adding this as a field to `PotentialBindings`
4847+ // and collect this information as new bindings become available but,
4848+ // since we are moving towards incremental model, which implies that
4849+ // `PotentialBindings` would stay alive for a long time, it's not
4850+ // immediately clear whether storage overhead of keeping this set just
4851+ // for ranking is worth it.
4852+ llvm::SmallPtrSet<CanType, 4 > discoveredTypes;
4853+ for (const auto &binding : Bindings)
4854+ discoveredTypes.insert (binding.BindingType ->getCanonicalType ());
4855+
4856+ return llvm::count_if (
4857+ Defaults, [&](const std::pair<CanType, Constraint *> &def) {
4858+ return def.second ->getKind () == ConstraintKind::Defaultable &&
4859+ discoveredTypes.count (def.first ) == 0 ;
4860+ });
48484861 }
48494862
48504863 static BindingScore formBindingScore (const PotentialBindings &b) {
4851- auto numDefaults = b.getNumDefaultableBindings ();
4864+ // If there are no bindings available but this type
4865+ // variable represents a closure - let's consider it
4866+ // as having a single non-default binding - that would
4867+ // be a type inferred based on context.
4868+ // It's considered to be non-default for purposes of
4869+ // ranking because we'd like to prioritize resolving
4870+ // closures to gain more information from their bodies.
48524871 auto numNonDefaultableBindings =
4853- b.isDirectHole () ? 0 : b.Bindings .size () - numDefaults;
4872+ !b.Bindings .empty () ? b.Bindings .size ()
4873+ : b.TypeVar ->getImpl ().isClosureType () ? 1 : 0 ;
48544874
48554875 return std::make_tuple (b.isHole (),
48564876 numNonDefaultableBindings == 0 ,
@@ -4874,10 +4894,8 @@ class ConstraintSystem {
48744894 if (yScore < xScore)
48754895 return false ;
48764896
4877- auto xDefaults =
4878- x.isDirectHole () ? 1 : x.Bindings .size () + std::get<6 >(xScore);
4879- auto yDefaults =
4880- y.isDirectHole () ? 1 : y.Bindings .size () + std::get<6 >(yScore);
4897+ auto xDefaults = x.getNumViableDefaultableBindings ();
4898+ auto yDefaults = y.getNumViableDefaultableBindings ();
48814899
48824900 // If there is a difference in number of default types,
48834901 // prioritize bindings with fewer of them.
@@ -4922,6 +4940,8 @@ class ConstraintSystem {
49224940 }
49234941 }
49244942
4943+ void addDefault (Constraint *constraint);
4944+
49254945 // / Add a potential binding to the list of bindings,
49264946 // / coalescing supertype bounds when we are able to compute the meet.
49274947 void addPotentialBinding (PotentialBinding binding,
@@ -5014,34 +5034,46 @@ class ConstraintSystem {
50145034 if (involvesTypeVariables ())
50155035 out << " involves_type_vars " ;
50165036
5017- auto numDefaultable = getNumDefaultableBindings ();
5037+ auto numDefaultable = getNumViableDefaultableBindings ();
50185038 if (numDefaultable > 0 )
50195039 out << " #defaultable_bindings=" << numDefaultable << " " ;
50205040
50215041 PrintOptions PO;
50225042 PO.PrintTypesForDebugging = true ;
5043+
5044+ auto printBinding = [&](const PotentialBinding &binding) {
5045+ auto type = binding.BindingType ;
5046+ switch (binding.Kind ) {
5047+ case AllowedBindingKind::Exact:
5048+ break ;
5049+
5050+ case AllowedBindingKind::Subtypes:
5051+ out << " (subtypes of) " ;
5052+ break ;
5053+
5054+ case AllowedBindingKind::Supertypes:
5055+ out << " (supertypes of) " ;
5056+ break ;
5057+ }
5058+ if (auto *literal = binding.getDefaultedLiteralProtocol ())
5059+ out << " (default from " << literal->getName () << " ) " ;
5060+ out << type.getString (PO);
5061+ };
5062+
50235063 out << " bindings={" ;
5024- interleave (Bindings,
5025- [&](const PotentialBinding &binding) {
5026- auto type = binding.BindingType ;
5027- switch (binding.Kind ) {
5028- case AllowedBindingKind::Exact:
5029- break ;
5030-
5031- case AllowedBindingKind::Subtypes:
5032- out << " (subtypes of) " ;
5033- break ;
5034-
5035- case AllowedBindingKind::Supertypes:
5036- out << " (supertypes of) " ;
5037- break ;
5038- }
5039- if (auto *literal = binding.getDefaultedLiteralProtocol ())
5040- out << " (default from " << literal->getName () << " ) " ;
5041- out << type.getString (PO);
5042- },
5043- [&]() { out << " ; " ; });
5064+ interleave (Bindings, printBinding, [&]() { out << " ; " ; });
50445065 out << " }" ;
5066+
5067+ if (!Defaults.empty ()) {
5068+ out << " defaults={" ;
5069+ for (const auto &entry : Defaults) {
5070+ auto *constraint = entry.second ;
5071+ PotentialBinding binding{constraint->getSecondType (),
5072+ AllowedBindingKind::Exact, constraint};
5073+ printBinding (binding);
5074+ }
5075+ out << " }" ;
5076+ }
50455077 }
50465078
50475079 void dump (ConstraintSystem *cs,
@@ -5839,6 +5871,9 @@ class TypeVarBindingProducer : public BindingProducer<TypeVariableBinding> {
58395871
58405872 TypeVariableType *TypeVar;
58415873 llvm::SmallVector<Binding, 8 > Bindings;
5874+ // / The set of defaults to attempt once producer
5875+ // / runs out of direct & transitive bindings.
5876+ llvm::SmallVector<Constraint *, 4 > DelayedDefaults;
58425877
58435878 // The index pointing to the offset in the bindings
58445879 // generator is currently at, `numTries` represents
@@ -5886,6 +5921,8 @@ class TypeVarBindingProducer : public BindingProducer<TypeVariableBinding> {
58865921 // / Check whether binding type is required to either conform to
58875922 // / `ExpressibleByNilLiteral` protocol or be wrapped into an optional type.
58885923 bool requiresOptionalAdjustment (const Binding &binding) const ;
5924+
5925+ Binding getDefaultBinding (Constraint *constraint) const ;
58895926};
58905927
58915928// / Iterator over disjunction choices, makes it
0 commit comments