@@ -94,6 +94,92 @@ void ConstraintSystem::PotentialBindings::inferTransitiveBindings(
94
94
95
95
void ConstraintSystem::PotentialBindings::inferDefaultTypes (
96
96
ConstraintSystem &cs, llvm::SmallPtrSetImpl<CanType> &existingTypes) {
97
+ // If we have any literal constraints, check whether there is already a
98
+ // binding that provides a type that conforms to that literal protocol. In
99
+ // such cases, don't add the default binding suggestion because the existing
100
+ // suggestion is better.
101
+ llvm::SmallPtrSet<ProtocolDecl *, 4 > coveredLiteralProtocols;
102
+
103
+ for (auto &binding : Bindings) {
104
+ Type type;
105
+
106
+ switch (binding.Kind ) {
107
+ case AllowedBindingKind::Exact:
108
+ type = binding.BindingType ;
109
+ break ;
110
+
111
+ case AllowedBindingKind::Subtypes:
112
+ case AllowedBindingKind::Supertypes:
113
+ type = binding.BindingType ->getRValueType ();
114
+ break ;
115
+ }
116
+
117
+ if (type->isTypeVariableOrMember () || type->isHole ())
118
+ continue ;
119
+
120
+ bool requiresUnwrap = false ;
121
+ for (auto *constraint : Protocols) {
122
+ if (constraint->getKind () != ConstraintKind::LiteralConformsTo)
123
+ continue ;
124
+
125
+ auto *protocol = constraint->getProtocol ();
126
+
127
+ assert (protocol);
128
+
129
+ if (coveredLiteralProtocols.count (protocol))
130
+ continue ;
131
+
132
+ do {
133
+ // If the type conforms to this protocol, we're covered.
134
+ if (TypeChecker::conformsToProtocol (type, protocol, cs.DC )) {
135
+ coveredLiteralProtocols.insert (protocol);
136
+ break ;
137
+ }
138
+
139
+ // If we're allowed to bind to subtypes, look through optionals.
140
+ // FIXME: This is really crappy special case of computing a reasonable
141
+ // result based on the given constraints.
142
+ if (binding.Kind == AllowedBindingKind::Subtypes) {
143
+ if (auto objTy = type->getOptionalObjectType ()) {
144
+ requiresUnwrap = true ;
145
+ type = objTy;
146
+ continue ;
147
+ }
148
+ }
149
+
150
+ requiresUnwrap = false ;
151
+ break ;
152
+ } while (true );
153
+ }
154
+
155
+ if (requiresUnwrap)
156
+ binding.BindingType = type;
157
+ }
158
+
159
+ for (auto *constraint : Protocols) {
160
+ auto *protocol = constraint->getProtocol ();
161
+ if (coveredLiteralProtocols.count (protocol))
162
+ continue ;
163
+
164
+ auto defaultType = TypeChecker::getDefaultType (protocol, cs.DC );
165
+ if (!defaultType)
166
+ continue ;
167
+
168
+ if (!existingTypes.insert (defaultType->getCanonicalType ()).second )
169
+ continue ;
170
+
171
+ // We need to figure out whether this is a direct conformance
172
+ // requirement or inferred transitive one to identify binding
173
+ // kind correctly.
174
+ auto *conformingVar = cs.getRepresentative (
175
+ constraint->getFirstType ()->castTo <TypeVariableType>());
176
+ addPotentialBinding ({defaultType,
177
+ TypeVar == conformingVar
178
+ ? AllowedBindingKind::Subtypes
179
+ : AllowedBindingKind::Supertypes,
180
+ constraint});
181
+ }
182
+
97
183
// / Add defaultable constraints.
98
184
for (auto *constraint : Defaults) {
99
185
Type type = constraint->getSecondType ();
@@ -704,50 +790,7 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) const {
704
790
// Record constraint where protocol requirement originated
705
791
// this is useful to use for the binding later.
706
792
result.Protocols .push_back (constraint);
707
-
708
- // If there is a default literal type for this protocol, it's a
709
- // potential binding.
710
- auto defaultType = TypeChecker::getDefaultType (constraint->getProtocol (), DC);
711
- if (!defaultType)
712
- continue ;
713
-
714
793
hasNonDependentMemberRelationalConstraints = true ;
715
-
716
- // Handle unspecialized types directly.
717
- if (!defaultType->hasUnboundGenericType ()) {
718
- if (!exactTypes.insert (defaultType->getCanonicalType ()).second )
719
- continue ;
720
-
721
- literalBindings.push_back (
722
- {defaultType, AllowedBindingKind::Subtypes, constraint});
723
- continue ;
724
- }
725
-
726
- // For generic literal types, check whether we already have a
727
- // specialization of this generic within our list.
728
- // FIXME: This assumes that, e.g., the default literal
729
- // int/float/char/string types are never generic.
730
- auto nominal = defaultType->getAnyNominal ();
731
- if (!nominal)
732
- continue ;
733
-
734
- bool matched = false ;
735
- for (auto exactType : exactTypes) {
736
- if (auto exactNominal = exactType->getAnyNominal ()) {
737
- // FIXME: Check parents?
738
- if (nominal == exactNominal) {
739
- matched = true ;
740
- break ;
741
- }
742
- }
743
- }
744
-
745
- if (!matched) {
746
- exactTypes.insert (defaultType->getCanonicalType ());
747
- literalBindings.push_back (
748
- {defaultType, AllowedBindingKind::Subtypes, constraint});
749
- }
750
-
751
794
break ;
752
795
}
753
796
@@ -813,80 +856,6 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) const {
813
856
}
814
857
}
815
858
816
- // If we have any literal constraints, check whether there is already a
817
- // binding that provides a type that conforms to that literal protocol. In
818
- // such cases, remove the default binding suggestion because the existing
819
- // suggestion is better.
820
- if (!literalBindings.empty ()) {
821
- SmallPtrSet<ProtocolDecl *, 5 > coveredLiteralProtocols;
822
- for (auto &binding : result.Bindings ) {
823
- Type testType;
824
-
825
- switch (binding.Kind ) {
826
- case AllowedBindingKind::Exact:
827
- testType = binding.BindingType ;
828
- break ;
829
-
830
- case AllowedBindingKind::Subtypes:
831
- case AllowedBindingKind::Supertypes:
832
- testType = binding.BindingType ->getRValueType ();
833
- break ;
834
- }
835
-
836
- // Attempting to check conformance of the type variable,
837
- // or unresolved type is invalid since it would result
838
- // in lose of viable literal bindings because that check
839
- // always returns trivial conformance.
840
- if (testType->isTypeVariableOrMember () || testType->is <UnresolvedType>())
841
- continue ;
842
-
843
- // Check each non-covered literal protocol to determine which ones
844
- // might be covered by non-defaulted bindings.
845
- bool updatedBindingType = false ;
846
- for (auto &literalBinding : literalBindings) {
847
- auto *protocol = literalBinding.getDefaultedLiteralProtocol ();
848
-
849
- assert (protocol);
850
-
851
- // Has already been covered by one of the bindings.
852
- if (coveredLiteralProtocols.count (protocol))
853
- continue ;
854
-
855
- do {
856
- // If the type conforms to this protocol, we're covered.
857
- if (DC->getParentModule ()->lookupConformance (testType, protocol)) {
858
- coveredLiteralProtocols.insert (protocol);
859
- break ;
860
- }
861
-
862
- // If we're allowed to bind to subtypes, look through optionals.
863
- // FIXME: This is really crappy special case of computing a reasonable
864
- // result based on the given constraints.
865
- if (binding.Kind == AllowedBindingKind::Subtypes) {
866
- if (auto objTy = testType->getOptionalObjectType ()) {
867
- updatedBindingType = true ;
868
- testType = objTy;
869
- continue ;
870
- }
871
- }
872
-
873
- updatedBindingType = false ;
874
- break ;
875
- } while (true );
876
- }
877
-
878
- if (updatedBindingType)
879
- binding.BindingType = testType;
880
- }
881
-
882
- for (auto &literalBinding : literalBindings) {
883
- auto *protocol = literalBinding.getDefaultedLiteralProtocol ();
884
- // For any literal type that has been covered, skip them.
885
- if (coveredLiteralProtocols.count (protocol) == 0 )
886
- result.addPotentialBinding (std::move (literalBinding));
887
- }
888
- }
889
-
890
859
// If there were both dependent-member and non-dependent-member relational
891
860
// constraints, consider this "fully bound"; we don't want to touch it.
892
861
if (hasDependentMemberRelationalConstraints) {
0 commit comments