@@ -27,6 +27,9 @@ using namespace swift;
27
27
using namespace constraints ;
28
28
using namespace inference ;
29
29
30
+ static llvm::Optional<Type> checkTypeOfBinding (TypeVariableType *typeVar,
31
+ Type type);
32
+
30
33
bool BindingSet::forClosureResult () const {
31
34
return Info.TypeVar ->getImpl ().isClosureResultType ();
32
35
}
@@ -473,7 +476,7 @@ void BindingSet::inferTransitiveBindings(
473
476
474
477
// Copy the bindings over to the root.
475
478
for (const auto &binding : bindings.Bindings )
476
- addBinding (binding);
479
+ addBinding (binding, /* isTransitive= */ true );
477
480
478
481
// Make a note that the key path root is transitively adjacent
479
482
// to contextual root type variable and all of its variables.
@@ -484,7 +487,8 @@ void BindingSet::inferTransitiveBindings(
484
487
}
485
488
} else {
486
489
addBinding (
487
- binding.withSameSource (inferredRootTy, BindingKind::Exact));
490
+ binding.withSameSource (inferredRootTy, BindingKind::Exact),
491
+ /* isTransitive=*/ true );
488
492
}
489
493
}
490
494
}
@@ -553,7 +557,8 @@ void BindingSet::inferTransitiveBindings(
553
557
if (ConstraintSystem::typeVarOccursInType (TypeVar, type))
554
558
continue ;
555
559
556
- addBinding (binding.withSameSource (type, BindingKind::Supertypes));
560
+ addBinding (binding.withSameSource (type, BindingKind::Supertypes),
561
+ /* isTransitive=*/ true );
557
562
}
558
563
}
559
564
}
@@ -631,7 +636,8 @@ void BindingSet::finalize(
631
636
continue ;
632
637
}
633
638
634
- addBinding ({protocolTy, AllowedBindingKind::Exact, constraint});
639
+ addBinding ({protocolTy, AllowedBindingKind::Exact, constraint},
640
+ /* isTransitive=*/ false );
635
641
}
636
642
}
637
643
}
@@ -740,11 +746,11 @@ void BindingSet::finalize(
740
746
}
741
747
}
742
748
743
- void BindingSet::addBinding (PotentialBinding binding) {
749
+ void BindingSet::addBinding (PotentialBinding binding, bool isTransitive ) {
744
750
if (Bindings.count (binding))
745
751
return ;
746
752
747
- if (!isViable (binding))
753
+ if (!isViable (binding, isTransitive ))
748
754
return ;
749
755
750
756
SmallPtrSet<TypeVariableType *, 4 > referencedTypeVars;
@@ -1165,14 +1171,17 @@ void PotentialBindings::addLiteral(Constraint *constraint) {
1165
1171
Literals.insert (constraint);
1166
1172
}
1167
1173
1168
- bool BindingSet::isViable (PotentialBinding &binding) {
1174
+ bool BindingSet::isViable (PotentialBinding &binding, bool isTransitive ) {
1169
1175
// Prevent against checking against the same opened nominal type
1170
1176
// over and over again. Doing so means redundant work in the best
1171
1177
// case. In the worst case, we'll produce lots of duplicate solutions
1172
1178
// for this constraint system, which is problematic for overload
1173
1179
// resolution.
1174
1180
auto type = binding.BindingType ;
1175
1181
1182
+ if (isTransitive && !checkTypeOfBinding (TypeVar, type))
1183
+ return false ;
1184
+
1176
1185
auto *NTD = type->getAnyNominal ();
1177
1186
if (!NTD)
1178
1187
return true ;
0 commit comments