@@ -100,61 +100,6 @@ CheckTypeWitnessResult checkTypeWitness(Type type,
100
100
const NormalProtocolConformance *Conf,
101
101
SubstOptions options = None);
102
102
103
- // / Describes the means of inferring an abstract type witness.
104
- enum class AbstractTypeWitnessKind : uint8_t {
105
- // / The type witness was inferred via a same-type-to-concrete constraint
106
- // / in a protocol requirement signature.
107
- Fixed,
108
-
109
- // / The type witness was inferred via a defaulted associated type.
110
- Default,
111
-
112
- // / The type witness was inferred to a generic parameter of the
113
- // / conforming type.
114
- GenericParam,
115
- };
116
-
117
- // / A type witness inferred without the aid of a specific potential
118
- // / value witness.
119
- class AbstractTypeWitness {
120
- AbstractTypeWitnessKind Kind;
121
- AssociatedTypeDecl *AssocType;
122
- Type TheType;
123
-
124
- // / When this is a default type witness, the declaration responsible for it.
125
- // / May not necessarilly match \c AssocType.
126
- AssociatedTypeDecl *DefaultedAssocType;
127
-
128
- AbstractTypeWitness (AbstractTypeWitnessKind Kind,
129
- AssociatedTypeDecl *AssocType, Type TheType,
130
- AssociatedTypeDecl *DefaultedAssocType)
131
- : Kind(Kind), AssocType(AssocType), TheType(TheType),
132
- DefaultedAssocType (DefaultedAssocType) {
133
- assert (AssocType && TheType);
134
- }
135
-
136
- public:
137
- static AbstractTypeWitness forFixed (AssociatedTypeDecl *assocType, Type type);
138
-
139
- static AbstractTypeWitness forDefault (AssociatedTypeDecl *assocType,
140
- Type type,
141
- AssociatedTypeDecl *defaultedAssocType);
142
-
143
- static AbstractTypeWitness forGenericParam (AssociatedTypeDecl *assocType,
144
- Type type);
145
-
146
- public:
147
- AbstractTypeWitnessKind getKind () const { return Kind; }
148
-
149
- AssociatedTypeDecl *getAssocType () const { return AssocType; }
150
-
151
- Type getType () const { return TheType; }
152
-
153
- AssociatedTypeDecl *getDefaultedAssocType () const {
154
- return DefaultedAssocType;
155
- }
156
- };
157
-
158
103
// / The set of associated types that have been inferred by matching
159
104
// / the given value witness to its corresponding requirement.
160
105
struct InferredAssociatedTypesByWitness {
@@ -855,9 +800,8 @@ class ConformanceChecker : public WitnessChecker {
855
800
// /
856
801
// / \param fn A function to call to emit the actual diagnostic. If
857
802
// / diagnostics are being deferred,
858
- void diagnoseOrDefer (
859
- ValueDecl *requirement, bool isError,
860
- std::function<void (NormalProtocolConformance *)> fn);
803
+ void diagnoseOrDefer (const ValueDecl *requirement, bool isError,
804
+ std::function<void (NormalProtocolConformance *)> fn);
861
805
862
806
ArrayRef<MissingWitness> getLocalMissingWitness () {
863
807
return GlobalMissingWitnesses.getArrayRef ().
@@ -929,6 +873,136 @@ class ConformanceChecker : public WitnessChecker {
929
873
llvm::function_ref<bool (AbstractFunctionDecl *)>predicate);
930
874
};
931
875
876
+ // / A system for recording and probing the intergrity of a type witness solution
877
+ // / for a set of unresolved associated type declarations.
878
+ // /
879
+ // / Right now can reason only about abstract type witnesses, i.e., same-type
880
+ // / constraints, default type definitions, and bindings to generic parameters.
881
+ class TypeWitnessSystem final {
882
+ // / Equivalence classes are used on demand to express equivalences between
883
+ // / witness candidates and reflect changes to resolved types across their
884
+ // / members.
885
+ class EquivalenceClass final {
886
+ // / The pointer:
887
+ // / - The resolved type for witness candidates belonging to this equivalence
888
+ // / class. The resolved type may be a type parameter, but cannot directly
889
+ // / pertain to a name variable in the owning system; instead, witness
890
+ // / candidates that should resolve to the same type share an equivalence
891
+ // / class.
892
+ // / The int:
893
+ // / - A flag indicating whether the resolved type is ambiguous. When set,
894
+ // / the resolved type is null.
895
+ llvm::PointerIntPair<Type, 1 , bool > ResolvedTyAndIsAmbiguous;
896
+
897
+ public:
898
+ EquivalenceClass (Type ty) : ResolvedTyAndIsAmbiguous(ty, false ) {}
899
+
900
+ EquivalenceClass (const EquivalenceClass &) = delete ;
901
+ EquivalenceClass (EquivalenceClass &&) = delete ;
902
+ EquivalenceClass &operator =(const EquivalenceClass &) = delete ;
903
+ EquivalenceClass &operator =(EquivalenceClass &&) = delete ;
904
+
905
+ Type getResolvedType () const {
906
+ return ResolvedTyAndIsAmbiguous.getPointer ();
907
+ }
908
+ void setResolvedType (Type ty);
909
+
910
+ bool isAmbiguous () const {
911
+ return ResolvedTyAndIsAmbiguous.getInt ();
912
+ }
913
+ void setAmbiguous () {
914
+ ResolvedTyAndIsAmbiguous = {nullptr , true };
915
+ }
916
+ };
917
+
918
+ // / A type witness candidate for a name variable.
919
+ struct TypeWitnessCandidate final {
920
+ // / The defaulted associated type declaration correlating with this
921
+ // / candidate, if present.
922
+ const AssociatedTypeDecl *DefaultedAssocType;
923
+
924
+ // / The equivalence class of this candidate.
925
+ EquivalenceClass *EquivClass;
926
+ };
927
+
928
+ // / The set of equivalence classes in the system.
929
+ llvm::SmallPtrSet<EquivalenceClass *, 4 > EquivalenceClasses;
930
+
931
+ // / The mapping from name variables (the names of unresolved associated
932
+ // / type declarations) to their corresponding type witness candidates.
933
+ llvm::SmallDenseMap<Identifier, TypeWitnessCandidate, 4 > TypeWitnesses;
934
+
935
+ public:
936
+ TypeWitnessSystem (ArrayRef<AssociatedTypeDecl *> assocTypes);
937
+ ~TypeWitnessSystem ();
938
+
939
+ TypeWitnessSystem (const TypeWitnessSystem &) = delete ;
940
+ TypeWitnessSystem (TypeWitnessSystem &&) = delete ;
941
+ TypeWitnessSystem &operator =(const TypeWitnessSystem &) = delete ;
942
+ TypeWitnessSystem &operator =(TypeWitnessSystem &&) = delete ;
943
+
944
+ // / Get the resolved type witness for the associated type with the given name.
945
+ Type getResolvedTypeWitness (Identifier name) const ;
946
+ bool hasResolvedTypeWitness (Identifier name) const ;
947
+
948
+ // / Get the defaulted associated type relating to the resolved type witness
949
+ // / for the associated type with the given name, if present.
950
+ const AssociatedTypeDecl *getDefaultedAssocType (Identifier name) const ;
951
+
952
+ // / Record a type witness for the given associated type name.
953
+ // /
954
+ // / \note This need not lead to the resolution of a type witness, e.g.
955
+ // / an associated type may be defaulted to another.
956
+ void addTypeWitness (Identifier name, Type type);
957
+
958
+ // / Record a default type witness.
959
+ // /
960
+ // / \param defaultedAssocType The specific associated type declaration that
961
+ // / defines the given default type.
962
+ // /
963
+ // / \note This need not lead to the resolution of a type witness.
964
+ void addDefaultTypeWitness (Type type,
965
+ const AssociatedTypeDecl *defaultedAssocType);
966
+
967
+ // / Record the given same-type requirement, if regarded of interest to
968
+ // / the system.
969
+ // /
970
+ // / \note This need not lead to the resolution of a type witness.
971
+ void addSameTypeRequirement (const Requirement &req);
972
+
973
+ void dump (llvm::raw_ostream &out,
974
+ const NormalProtocolConformance *conformance) const ;
975
+
976
+ private:
977
+ // / Form an equivalence between the given name variables.
978
+ void addEquivalence (Identifier name1, Identifier name2);
979
+
980
+ // / Merge \p equivClass2 into \p equivClass1.
981
+ // /
982
+ // / \note This will delete \p equivClass2 after migrating its members to
983
+ // / \p equivClass1.
984
+ void mergeEquivalenceClasses (EquivalenceClass *equivClass1,
985
+ const EquivalenceClass *equivClass2);
986
+
987
+ // / The result of comparing two resolved types targeting a single equivalence
988
+ // / class, in terms of their relative impact on solving the system.
989
+ enum class ResolvedTypeComparisonResult {
990
+ // / The first resolved type is a better choice than the second one.
991
+ Better,
992
+
993
+ // / The first resolved type is an equivalent or worse choice than the
994
+ // / second one.
995
+ EquivalentOrWorse,
996
+
997
+ // / Both resolved types are concrete and mutually exclusive.
998
+ Ambiguity
999
+ };
1000
+
1001
+ // / Compare the given resolved types as targeting a single equivalence class,
1002
+ // / in terms of the their relative impact on solving the system.
1003
+ static ResolvedTypeComparisonResult compareResolvedTypes (Type ty1, Type ty2);
1004
+ };
1005
+
932
1006
// / Captures the state needed to infer associated types.
933
1007
class AssociatedTypeInference {
934
1008
// / The type checker we'll need to validate declarations etc.
@@ -956,7 +1030,7 @@ class AssociatedTypeInference {
956
1030
typeWitnesses;
957
1031
958
1032
// / Information about a failed, defaulted associated type.
959
- AssociatedTypeDecl *failedDefaultedAssocType = nullptr ;
1033
+ const AssociatedTypeDecl *failedDefaultedAssocType = nullptr ;
960
1034
Type failedDefaultedWitness;
961
1035
CheckTypeWitnessResult failedDefaultedResult;
962
1036
@@ -1005,23 +1079,20 @@ class AssociatedTypeInference {
1005
1079
ConformanceChecker &checker,
1006
1080
const llvm::SetVector<AssociatedTypeDecl *> &assocTypes);
1007
1081
1008
- // / Compute a "fixed" type witness for an associated type, e.g.,
1009
- // / if the refined protocol requires it to be equivalent to some other type.
1010
- Type computeFixedTypeWitness (AssociatedTypeDecl *assocType);
1011
-
1012
1082
// / Compute the default type witness from an associated type default,
1013
1083
// / if there is one.
1014
- Optional<AbstractTypeWitness >
1015
- computeDefaultTypeWitness (AssociatedTypeDecl *assocType);
1084
+ Optional<std::pair<AssociatedTypeDecl *, Type> >
1085
+ computeDefaultTypeWitness (AssociatedTypeDecl *assocType) const ;
1016
1086
1017
1087
// / Compute the "derived" type witness for an associated type that is
1018
1088
// / known to the compiler.
1019
1089
std::pair<Type, TypeDecl *>
1020
1090
computeDerivedTypeWitness (AssociatedTypeDecl *assocType);
1021
1091
1022
- // / Compute a type witness without using a specific potential witness.
1023
- Optional<AbstractTypeWitness>
1024
- computeAbstractTypeWitness (AssociatedTypeDecl *assocType);
1092
+ // / Collect abstract type witnesses and feed them to the given system.
1093
+ void collectAbstractTypeWitnesses (
1094
+ TypeWitnessSystem &system,
1095
+ ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) const ;
1025
1096
1026
1097
// / Substitute the current type witnesses into the given interface type.
1027
1098
Type substCurrentTypeWitnesses (Type type);
@@ -1040,14 +1111,12 @@ class AssociatedTypeInference {
1040
1111
// / requirements of the given constrained extension.
1041
1112
bool checkConstrainedExtension (ExtensionDecl *ext);
1042
1113
1043
- // / Validate the current tentative solution represented by \p typeWitnesses
1044
- // / and attempt to resolve abstract type witnesses for associated types that
1045
- // / could not be inferred otherwise.
1114
+ // / Attempt to infer abstract type witnesses for the given set of associated
1115
+ // / types.
1046
1116
// /
1047
1117
// / \returns \c nullptr, or the associated type that failed.
1048
- AssociatedTypeDecl *
1049
- completeSolution (ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes,
1050
- unsigned reqDepth);
1118
+ AssociatedTypeDecl *inferAbstractTypeWitnesses (
1119
+ ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes, unsigned reqDepth);
1051
1120
1052
1121
// / Top-level operation to find solutions for the given unresolved
1053
1122
// / associated types.
0 commit comments