@@ -4843,21 +4843,28 @@ class ConstraintSystem {
4843
4843
if (isDirectHole ())
4844
4844
return 1 ;
4845
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 ;
4846
+ auto numDefaultable = llvm::count_if (
4847
+ Defaults, [](const std::pair<CanType, Constraint *> &entry) {
4848
+ return entry.second ->getKind () == ConstraintKind::Defaultable;
4860
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;
4861
4868
}
4862
4869
4863
4870
static BindingScore formBindingScore (const PotentialBindings &b) {
0 commit comments