@@ -66,12 +66,6 @@ class SolutionApplicationTarget;
66
66
67
67
} // end namespace constraints
68
68
69
- namespace unittest {
70
-
71
- class SemaTest ;
72
-
73
- } // end namespace unittest
74
-
75
69
// Forward declare some TypeChecker related functions
76
70
// so they could be made friends of ConstraintSystem.
77
71
namespace TypeChecker {
@@ -2026,8 +2020,6 @@ enum class SolutionApplicationToFunctionResult {
2026
2020
class ConstraintSystem {
2027
2021
ASTContext &Context;
2028
2022
2029
- friend class swift ::unittest::SemaTest;
2030
-
2031
2023
public:
2032
2024
DeclContext *DC;
2033
2025
ConstraintSystemOptions Options;
@@ -4625,7 +4617,8 @@ class ConstraintSystem {
4625
4617
ConstraintKind bodyResultConstraintKind,
4626
4618
ConstraintLocatorBuilder locator);
4627
4619
4628
- private:
4620
+ public: // binding inference logic is public for unit testing.
4621
+
4629
4622
// / The kind of bindings that are permitted.
4630
4623
enum class AllowedBindingKind : uint8_t {
4631
4624
// / Only the exact type.
@@ -4700,6 +4693,8 @@ class ConstraintSystem {
4700
4693
return BindingSource.get <ConstraintLocator *>();
4701
4694
}
4702
4695
4696
+ Constraint *getSource () const { return BindingSource.get <Constraint *>(); }
4697
+
4703
4698
PotentialBinding withType (Type type) const {
4704
4699
return {type, Kind, BindingSource};
4705
4700
}
@@ -4721,6 +4716,50 @@ class ConstraintSystem {
4721
4716
}
4722
4717
};
4723
4718
4719
+ struct LiteralRequirement {
4720
+ // / The source of the literal requirement.
4721
+ Constraint *Source;
4722
+ // / The default type associated with this literal (if any).
4723
+ Type DefaultType;
4724
+ // / Determines whether this literal is a direct requirement
4725
+ // / of the current type variable.
4726
+ bool IsDirectRequirement;
4727
+
4728
+ // / If the literal is covered by existing type binding,
4729
+ // / this points to the source of the binding.
4730
+ mutable Constraint *CoveredBy = nullptr ;
4731
+
4732
+ LiteralRequirement (Constraint *source, Type defaultTy, bool isDirect)
4733
+ : Source(source), DefaultType(defaultTy),
4734
+ IsDirectRequirement (isDirect) {}
4735
+
4736
+ Constraint *getSource () const { return Source; }
4737
+
4738
+ ProtocolDecl *getProtocol () const { return Source->getProtocol (); }
4739
+
4740
+ bool isCovered () const { return bool (CoveredBy); }
4741
+
4742
+ bool isDirectRequirement () const { return IsDirectRequirement; }
4743
+
4744
+ bool hasDefaultType () const { return bool (DefaultType); }
4745
+
4746
+ Type getDefaultType () const {
4747
+ assert (hasDefaultType ());
4748
+ return DefaultType;
4749
+ }
4750
+
4751
+ void setCoveredBy (Constraint *coveredBy) {
4752
+ assert (!isCovered ());
4753
+ CoveredBy = coveredBy;
4754
+ }
4755
+
4756
+ bool isCoveredBy (Type type, DeclContext *useDC) const ;
4757
+
4758
+ // / Determines whether literal protocol associated with this
4759
+ // / meta-information is viable for inclusion as a defaultable binding.
4760
+ bool viableAsBinding () const { return !isCovered () && hasDefaultType (); }
4761
+ };
4762
+
4724
4763
struct PotentialBindings {
4725
4764
using BindingScore =
4726
4765
std::tuple<bool , bool , bool , bool , bool , unsigned char , int >;
@@ -4740,6 +4779,14 @@ class ConstraintSystem {
4740
4779
// / subtype/conversion/equivalence relations with other type variables.
4741
4780
Optional<llvm::SmallPtrSet<Constraint *, 4 >> TransitiveProtocols;
4742
4781
4782
+ // / The set of unique literal protocol requirements placed on this
4783
+ // / type variable or inferred transitively through subtype chains.
4784
+ // /
4785
+ // / Note that ordering is important when it comes to bindings, we'd
4786
+ // / like to add any "direct" default types first to attempt them
4787
+ // / before transitive ones.
4788
+ llvm::SmallMapVector<ProtocolDecl *, LiteralRequirement, 2 > Literals;
4789
+
4743
4790
// / The set of constraints which would be used to infer default types.
4744
4791
llvm::SmallDenseMap<CanType, Constraint *, 2 > Defaults;
4745
4792
@@ -4756,9 +4803,6 @@ class ConstraintSystem {
4756
4803
4757
4804
ASTNode AssociatedCodeCompletionToken = ASTNode();
4758
4805
4759
- // / Whether this type variable has literal bindings.
4760
- LiteralBindingKind LiteralBinding = LiteralBindingKind::None;
4761
-
4762
4806
// / A set of all not-yet-resolved type variables this type variable
4763
4807
// / is a subtype of, supertype of or is equivalent to. This is used
4764
4808
// / to determine ordering inside of a chain of subtypes to help infer
@@ -4772,9 +4816,14 @@ class ConstraintSystem {
4772
4816
4773
4817
// / Determine whether the set of bindings is non-empty.
4774
4818
explicit operator bool () const {
4775
- return !Bindings.empty () || !Defaults.empty () || isDirectHole ();
4819
+ return !Bindings.empty () || getNumViableLiteralBindings () > 0 ||
4820
+ !Defaults.empty () || isDirectHole ();
4776
4821
}
4777
4822
4823
+ // / Determines whether this type variable could be `nil`,
4824
+ // / which means that all of its bindings should be optional.
4825
+ bool canBeNil () const ;
4826
+
4778
4827
// / Determine whether attempting this type variable should be
4779
4828
// / delayed until the rest of the constraint system is considered
4780
4829
// / "fully bound" meaning constraints, which affect completeness
@@ -4822,8 +4871,8 @@ class ConstraintSystem {
4822
4871
if (!CS.shouldAttemptFixes ())
4823
4872
return false ;
4824
4873
4825
- return Bindings.empty () && Defaults. empty () &&
4826
- TypeVar->getImpl ().canBindToHole ();
4874
+ return Bindings.empty () && getNumViableLiteralBindings () == 0 &&
4875
+ Defaults. empty () && TypeVar->getImpl ().canBindToHole ();
4827
4876
}
4828
4877
4829
4878
// / Determine if the bindings only constrain the type variable from above
@@ -4839,6 +4888,8 @@ class ConstraintSystem {
4839
4888
});
4840
4889
}
4841
4890
4891
+ unsigned getNumViableLiteralBindings () const ;
4892
+
4842
4893
unsigned getNumViableDefaultableBindings () const {
4843
4894
if (isDirectHole ())
4844
4895
return 1 ;
@@ -4875,16 +4926,19 @@ class ConstraintSystem {
4875
4926
// It's considered to be non-default for purposes of
4876
4927
// ranking because we'd like to prioritize resolving
4877
4928
// closures to gain more information from their bodies.
4878
- auto numNonDefaultableBindings =
4879
- !b.Bindings .empty () ? b.Bindings .size ()
4880
- : b.TypeVar ->getImpl ().isClosureType () ? 1 : 0 ;
4929
+ unsigned numBindings =
4930
+ b.Bindings .size () + b.getNumViableLiteralBindings ();
4931
+ auto numNonDefaultableBindings = numBindings > 0 ? numBindings
4932
+ : b.TypeVar ->getImpl ().isClosureType ()
4933
+ ? 1
4934
+ : 0 ;
4881
4935
4882
4936
return std::make_tuple (b.isHole (),
4883
4937
numNonDefaultableBindings == 0 ,
4884
4938
b.isDelayed (),
4885
4939
b.isSubtypeOfExistentialType (),
4886
4940
b.involvesTypeVariables (),
4887
- static_cast <unsigned char >(b.LiteralBinding ),
4941
+ static_cast <unsigned char >(b.getLiteralKind () ),
4888
4942
-numNonDefaultableBindings);
4889
4943
}
4890
4944
@@ -4928,26 +4982,27 @@ class ConstraintSystem {
4928
4982
return x.isPotentiallyIncomplete () < y.isPotentiallyIncomplete ();
4929
4983
}
4930
4984
4931
- void foundLiteralBinding (ProtocolDecl *proto) {
4932
- switch (*proto->getKnownProtocolKind ()) {
4933
- case KnownProtocolKind::ExpressibleByDictionaryLiteral:
4934
- case KnownProtocolKind::ExpressibleByArrayLiteral:
4935
- case KnownProtocolKind::ExpressibleByStringInterpolation:
4936
- LiteralBinding = LiteralBindingKind::Collection;
4937
- break ;
4985
+ LiteralBindingKind getLiteralKind () const ;
4938
4986
4939
- case KnownProtocolKind::ExpressibleByFloatLiteral:
4940
- LiteralBinding = LiteralBindingKind::Float;
4941
- break ;
4987
+ void addDefault (Constraint *constraint);
4942
4988
4943
- default :
4944
- if (LiteralBinding != LiteralBindingKind::Collection)
4945
- LiteralBinding = LiteralBindingKind::Atom;
4946
- break ;
4947
- }
4948
- }
4989
+ void addLiteral (Constraint *constraint);
4949
4990
4950
- void addDefault (Constraint *constraint);
4991
+ // / Determines whether the given literal protocol is "covered"
4992
+ // / by the given binding - type of the binding could either be
4993
+ // / equal (in canonical sense) to the protocol's default type,
4994
+ // / or conform to a protocol.
4995
+ // /
4996
+ // / \param literal The literal protocol requirement to check.
4997
+ // /
4998
+ // / \param binding The binding to check for coverage.
4999
+ // /
5000
+ // / \param canBeNil The flag that determines whether given type
5001
+ // / variable requires all of its bindings to be optional.
5002
+ // /
5003
+ // / \returns true if binding covers given literal protocol.
5004
+ bool isLiteralCoveredBy (const LiteralRequirement &literal,
5005
+ PotentialBinding &binding, bool canBeNil) const ;
4951
5006
4952
5007
// / Add a potential binding to the list of bindings,
4953
5008
// / coalescing supertype bounds when we are able to compute the meet.
@@ -5008,11 +5063,6 @@ class ConstraintSystem {
5008
5063
ConstraintSystem::PotentialBindings>
5009
5064
&inferredBindings);
5010
5065
5011
- // / Infer bindings based on any protocol conformances that have default
5012
- // / types.
5013
- void inferDefaultTypes (ConstraintSystem &cs,
5014
- llvm::SmallPtrSetImpl<CanType> &existingTypes);
5015
-
5016
5066
public:
5017
5067
bool infer (ConstraintSystem &cs,
5018
5068
llvm::SmallPtrSetImpl<CanType> &exactTypes,
@@ -5036,8 +5086,9 @@ class ConstraintSystem {
5036
5086
out << " delayed " ;
5037
5087
if (isSubtypeOfExistentialType ())
5038
5088
out << " subtype_of_existential " ;
5039
- if (LiteralBinding != LiteralBindingKind::None)
5040
- out << " literal=" << static_cast <int >(LiteralBinding) << " " ;
5089
+ auto literalKind = getLiteralKind ();
5090
+ if (literalKind != LiteralBindingKind::None)
5091
+ out << " literal=" << static_cast <int >(literalKind) << " " ;
5041
5092
if (involvesTypeVariables ())
5042
5093
out << " involves_type_vars " ;
5043
5094
@@ -5102,7 +5153,6 @@ class ConstraintSystem {
5102
5153
Optional<Type> checkTypeOfBinding (TypeVariableType *typeVar, Type type) const ;
5103
5154
Optional<PotentialBindings> determineBestBindings ();
5104
5155
5105
- public:
5106
5156
// / Infer bindings for the given type variable based on current
5107
5157
// / state of the constraint system.
5108
5158
PotentialBindings inferBindingsFor (TypeVariableType *typeVar,
0 commit comments