@@ -119,8 +119,8 @@ bool PotentialBindings::involvesTypeVariables() const {
119
119
// on each step of the solver, but once bindings are computed
120
120
// incrementally it becomes more important to double-check that
121
121
// any adjacent type variables found previously are still unresolved.
122
- return llvm::any_of (AdjacentVars, [](TypeVariableType *typeVar ) {
123
- return !typeVar ->getImpl ().getFixedType (/* record=*/ nullptr );
122
+ return llvm::any_of (AdjacentVars, [](const auto &adjacent ) {
123
+ return !adjacent. first ->getImpl ().getFixedType (/* record=*/ nullptr );
124
124
});
125
125
}
126
126
@@ -594,9 +594,9 @@ bool LiteralRequirement::isCoveredBy(Type type, DeclContext *useDC) const {
594
594
}
595
595
596
596
std::pair<bool , Type>
597
- PotentialBindings::isLiteralCoveredBy (const LiteralRequirement &literal ,
598
- const PotentialBinding &binding ,
599
- bool canBeNil ) const {
597
+ LiteralRequirement::isCoveredBy (const PotentialBinding &binding ,
598
+ bool canBeNil ,
599
+ DeclContext *useDC ) const {
600
600
auto type = binding.BindingType ;
601
601
switch (binding.Kind ) {
602
602
case AllowedBindingKind::Exact:
@@ -616,7 +616,7 @@ PotentialBindings::isLiteralCoveredBy(const LiteralRequirement &literal,
616
616
if (type->isTypeVariableOrMember () || type->isHole ())
617
617
return std::make_pair (false , Type ());
618
618
619
- if (literal. isCoveredBy (type, CS. DC )) {
619
+ if (isCoveredBy (type, useDC )) {
620
620
return std::make_pair (true , requiresUnwrap ? type : binding.BindingType );
621
621
}
622
622
@@ -628,7 +628,7 @@ PotentialBindings::isLiteralCoveredBy(const LiteralRequirement &literal,
628
628
// If this literal protocol is not a direct requirement it
629
629
// would not be possible to change optionality while inferring
630
630
// bindings for a supertype, so this hack doesn't apply.
631
- if (!literal. isDirectRequirement ())
631
+ if (!isDirectRequirement ())
632
632
return std::make_pair (false , Type ());
633
633
634
634
// If we're allowed to bind to subtypes, look through optionals.
@@ -726,7 +726,7 @@ void PotentialBindings::addPotentialBinding(PotentialBinding binding,
726
726
Type adjustedTy;
727
727
728
728
std::tie (isCovered, adjustedTy) =
729
- isLiteralCoveredBy ( info, binding, allowsNil);
729
+ info. isCoveredBy ( binding, allowsNil, CS. DC );
730
730
731
731
if (!isCovered)
732
732
continue ;
@@ -800,7 +800,7 @@ void PotentialBindings::addLiteral(Constraint *constraint) {
800
800
Type adjustedTy;
801
801
802
802
std::tie (isCovered, adjustedTy) =
803
- isLiteralCoveredBy (literal, *binding, allowsNil);
803
+ literal. isCoveredBy ( *binding, allowsNil, CS. DC );
804
804
805
805
// No luck here, let's try next literal requirement.
806
806
if (!isCovered)
@@ -983,7 +983,8 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
983
983
findInferableTypeVars (second, typeVars);
984
984
985
985
if (typeVars.erase (TypeVar)) {
986
- AdjacentVars.insert (typeVars.begin (), typeVars.end ());
986
+ for (auto *typeVar : typeVars)
987
+ AdjacentVars.insert ({typeVar, constraint});
987
988
}
988
989
989
990
return None;
@@ -1016,9 +1017,21 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
1016
1017
if (type->getWithoutSpecifierType ()
1017
1018
->lookThroughAllOptionalTypes ()
1018
1019
->is <DependentMemberType>()) {
1019
- type->getTypeVariables (AdjacentVars);
1020
+ llvm::SmallPtrSet<TypeVariableType *, 4 > referencedVars;
1021
+ type->getTypeVariables (referencedVars);
1022
+
1023
+ bool containsSelf = false ;
1024
+ for (auto *var : referencedVars) {
1025
+ // Add all type variables encountered in the type except
1026
+ // to the current type variable.
1027
+ if (var != TypeVar) {
1028
+ AdjacentVars.insert ({var, constraint});
1029
+ continue ;
1030
+ }
1031
+
1032
+ containsSelf = true ;
1033
+ }
1020
1034
1021
- bool containsSelf = AdjacentVars.erase (TypeVar);
1022
1035
// If inferred type doesn't contain the current type variable,
1023
1036
// let's mark bindings as delayed until dependent member type
1024
1037
// is resolved.
@@ -1043,15 +1056,20 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
1043
1056
// Check whether we can perform this binding.
1044
1057
if (auto boundType = checkTypeOfBinding (TypeVar, type)) {
1045
1058
type = *boundType;
1046
- if (type->hasTypeVariable ())
1047
- type->getTypeVariables (AdjacentVars);
1059
+ if (type->hasTypeVariable ()) {
1060
+ llvm::SmallPtrSet<TypeVariableType *, 4 > referencedVars;
1061
+ type->getTypeVariables (referencedVars);
1062
+ for (auto *var : referencedVars) {
1063
+ AdjacentVars.insert ({var, constraint});
1064
+ }
1065
+ }
1048
1066
} else {
1049
1067
auto *bindingTypeVar = type->getRValueType ()->getAs <TypeVariableType>();
1050
1068
1051
1069
if (!bindingTypeVar)
1052
1070
return None;
1053
1071
1054
- AdjacentVars.insert (bindingTypeVar);
1072
+ AdjacentVars.insert ({ bindingTypeVar, constraint} );
1055
1073
1056
1074
// If current type variable is associated with a code completion token
1057
1075
// it's possible that it doesn't have enough contextual information
0 commit comments