@@ -4741,7 +4741,7 @@ class ConstraintSystem {
4741
4741
Optional<llvm::SmallPtrSet<Constraint *, 4 >> TransitiveProtocols;
4742
4742
4743
4743
// / The set of constraints which would be used to infer default types.
4744
- llvm::TinyPtrVector< Constraint *> Defaults;
4744
+ llvm::SmallDenseMap<CanType, Constraint *, 2 > Defaults;
4745
4745
4746
4746
// / The set of constraints which delay attempting this type variable.
4747
4747
llvm::TinyPtrVector<Constraint *> DelayedBy;
@@ -4772,7 +4772,7 @@ class ConstraintSystem {
4772
4772
4773
4773
// / Determine whether the set of bindings is non-empty.
4774
4774
explicit operator bool () const {
4775
- return !Bindings.empty () || isDirectHole ();
4775
+ return !Bindings.empty () || !Defaults. empty () || isDirectHole ();
4776
4776
}
4777
4777
4778
4778
// / Determine whether attempting this type variable should be
@@ -4822,7 +4822,8 @@ class ConstraintSystem {
4822
4822
if (!CS.shouldAttemptFixes ())
4823
4823
return false ;
4824
4824
4825
- return Bindings.empty () && TypeVar->getImpl ().canBindToHole ();
4825
+ return Bindings.empty () && Defaults.empty () &&
4826
+ TypeVar->getImpl ().canBindToHole ();
4826
4827
}
4827
4828
4828
4829
// / Determine if the bindings only constrain the type variable from above
@@ -4838,19 +4839,45 @@ class ConstraintSystem {
4838
4839
});
4839
4840
}
4840
4841
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
+ auto numDefaultable = llvm::count_if (
4847
+ Defaults, [](const std::pair<CanType, Constraint *> &entry) {
4848
+ return entry.second ->getKind () == ConstraintKind::Defaultable;
4849
+ });
4850
+
4851
+ // Short-circuit unviable checks if there are no defaultable bindings.
4852
+ if (numDefaultable == 0 )
4853
+ return 0 ;
4854
+
4855
+ // Defaultable constraint is unviable if its type is covered by
4856
+ // an existing direct or transitive binding.
4857
+ auto unviable =
4858
+ llvm::count_if (Bindings, [&](const PotentialBinding &binding) {
4859
+ auto type = binding.BindingType ->getCanonicalType ();
4860
+ auto def = Defaults.find (type);
4861
+ return def != Defaults.end ()
4862
+ ? def->second ->getKind () == ConstraintKind::Defaultable
4863
+ : false ;
4864
+ });
4865
+
4866
+ assert (numDefaultable >= unviable);
4867
+ return numDefaultable - unviable;
4848
4868
}
4849
4869
4850
4870
static BindingScore formBindingScore (const PotentialBindings &b) {
4851
- auto numDefaults = b.getNumDefaultableBindings ();
4871
+ // If there are no bindings available but this type
4872
+ // variable represents a closure - let's consider it
4873
+ // as having a single non-default binding - that would
4874
+ // be a type inferred based on context.
4875
+ // It's considered to be non-default for purposes of
4876
+ // ranking because we'd like to prioritize resolving
4877
+ // closures to gain more information from their bodies.
4852
4878
auto numNonDefaultableBindings =
4853
- b.isDirectHole () ? 0 : b.Bindings .size () - numDefaults;
4879
+ !b.Bindings .empty () ? b.Bindings .size ()
4880
+ : b.TypeVar ->getImpl ().isClosureType () ? 1 : 0 ;
4854
4881
4855
4882
return std::make_tuple (b.isHole (),
4856
4883
numNonDefaultableBindings == 0 ,
@@ -4874,10 +4901,8 @@ class ConstraintSystem {
4874
4901
if (yScore < xScore)
4875
4902
return false ;
4876
4903
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);
4904
+ auto xDefaults = x.getNumViableDefaultableBindings ();
4905
+ auto yDefaults = y.getNumViableDefaultableBindings ();
4881
4906
4882
4907
// If there is a difference in number of default types,
4883
4908
// prioritize bindings with fewer of them.
@@ -4922,6 +4947,8 @@ class ConstraintSystem {
4922
4947
}
4923
4948
}
4924
4949
4950
+ void addDefault (Constraint *constraint);
4951
+
4925
4952
// / Add a potential binding to the list of bindings,
4926
4953
// / coalescing supertype bounds when we are able to compute the meet.
4927
4954
void addPotentialBinding (PotentialBinding binding,
@@ -5014,34 +5041,46 @@ class ConstraintSystem {
5014
5041
if (involvesTypeVariables ())
5015
5042
out << " involves_type_vars " ;
5016
5043
5017
- auto numDefaultable = getNumDefaultableBindings ();
5044
+ auto numDefaultable = getNumViableDefaultableBindings ();
5018
5045
if (numDefaultable > 0 )
5019
5046
out << " #defaultable_bindings=" << numDefaultable << " " ;
5020
5047
5021
5048
PrintOptions PO;
5022
5049
PO.PrintTypesForDebugging = true ;
5050
+
5051
+ auto printBinding = [&](const PotentialBinding &binding) {
5052
+ auto type = binding.BindingType ;
5053
+ switch (binding.Kind ) {
5054
+ case AllowedBindingKind::Exact:
5055
+ break ;
5056
+
5057
+ case AllowedBindingKind::Subtypes:
5058
+ out << " (subtypes of) " ;
5059
+ break ;
5060
+
5061
+ case AllowedBindingKind::Supertypes:
5062
+ out << " (supertypes of) " ;
5063
+ break ;
5064
+ }
5065
+ if (auto *literal = binding.getDefaultedLiteralProtocol ())
5066
+ out << " (default from " << literal->getName () << " ) " ;
5067
+ out << type.getString (PO);
5068
+ };
5069
+
5023
5070
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 << " ; " ; });
5071
+ interleave (Bindings, printBinding, [&]() { out << " ; " ; });
5044
5072
out << " }" ;
5073
+
5074
+ if (!Defaults.empty ()) {
5075
+ out << " defaults={" ;
5076
+ for (const auto &entry : Defaults) {
5077
+ auto *constraint = entry.second ;
5078
+ PotentialBinding binding{constraint->getSecondType (),
5079
+ AllowedBindingKind::Exact, constraint};
5080
+ printBinding (binding);
5081
+ }
5082
+ out << " }" ;
5083
+ }
5045
5084
}
5046
5085
5047
5086
void dump (ConstraintSystem *cs,
@@ -5839,6 +5878,9 @@ class TypeVarBindingProducer : public BindingProducer<TypeVariableBinding> {
5839
5878
5840
5879
TypeVariableType *TypeVar;
5841
5880
llvm::SmallVector<Binding, 8 > Bindings;
5881
+ // / The set of defaults to attempt once producer
5882
+ // / runs out of direct & transitive bindings.
5883
+ llvm::SmallVector<Constraint *, 4 > DelayedDefaults;
5842
5884
5843
5885
// The index pointing to the offset in the bindings
5844
5886
// generator is currently at, `numTries` represents
@@ -5886,6 +5928,8 @@ class TypeVarBindingProducer : public BindingProducer<TypeVariableBinding> {
5886
5928
// / Check whether binding type is required to either conform to
5887
5929
// / `ExpressibleByNilLiteral` protocol or be wrapped into an optional type.
5888
5930
bool requiresOptionalAdjustment (const Binding &binding) const ;
5931
+
5932
+ Binding getDefaultBinding (Constraint *constraint) const ;
5889
5933
};
5890
5934
5891
5935
// / Iterator over disjunction choices, makes it
0 commit comments