@@ -2994,6 +2994,11 @@ class ConstraintSystem {
2994
2994
bool isDeclUnavailable (const Decl *D,
2995
2995
ConstraintLocator *locator = nullptr ) const ;
2996
2996
2997
+ // / Returns the \c ExprKind of the given type variable if it's the type of an
2998
+ // / atomic literal expression, meaning the literal can't be composed of subexpressions.
2999
+ // / Otherwise, returns \c None.
3000
+ Optional<ExprKind> getAtomicLiteralKind (TypeVariableType *typeVar) const ;
3001
+
2997
3002
public:
2998
3003
2999
3004
// / Whether we should attempt to fix problems.
@@ -3076,6 +3081,14 @@ class ConstraintSystem {
3076
3081
Expr *expr, Type conversionType, ContextualTypePurpose purpose,
3077
3082
bool isOpaqueReturnType);
3078
3083
3084
+ // / Convenience function to pass an \c ArrayRef to \c addJoinConstraint
3085
+ Type addJoinConstraint (ConstraintLocator *locator,
3086
+ ArrayRef<std::pair<Type, ConstraintLocator *>> inputs,
3087
+ Optional<Type> supertype = None) {
3088
+ return addJoinConstraint<decltype (inputs)::iterator>(
3089
+ locator, inputs.begin (), inputs.end (), supertype, [](auto it) { return *it; });
3090
+ }
3091
+
3079
3092
// / Add a "join" constraint between a set of types, producing the common
3080
3093
// / supertype.
3081
3094
// /
@@ -3085,9 +3098,55 @@ class ConstraintSystem {
3085
3098
// /
3086
3099
// / \returns the joined type, which is generally a new type variable, unless there are
3087
3100
// / fewer than 2 input types or the \c supertype parameter is specified.
3101
+ template <typename Iterator>
3088
3102
Type addJoinConstraint (ConstraintLocator *locator,
3089
- ArrayRef<std::pair<Type, ConstraintLocator *>> inputs,
3090
- Optional<Type> supertype = None);
3103
+ Iterator begin, Iterator end,
3104
+ Optional<Type> supertype,
3105
+ std::function<std::pair<Type, ConstraintLocator *>(Iterator)> getType) {
3106
+ if (begin == end)
3107
+ return Type ();
3108
+
3109
+ // No need to generate a new type variable if there's only one type to join
3110
+ if ((begin + 1 == end) && !supertype.hasValue ())
3111
+ return getType (begin).first ;
3112
+
3113
+ // The type to capture the result of the join, which is either the specified supertype,
3114
+ // or a new type variable.
3115
+ Type resultTy = supertype.hasValue () ? supertype.getValue () :
3116
+ createTypeVariable (locator, (TVO_PrefersSubtypeBinding | TVO_CanBindToNoEscape));
3117
+
3118
+ using RawExprKind = uint8_t ;
3119
+ llvm::SmallDenseMap<RawExprKind, TypeVariableType *> representativeForKind;
3120
+
3121
+ // Join the input types.
3122
+ while (begin != end) {
3123
+ Type type;
3124
+ ConstraintLocator *locator;
3125
+ std::tie (type, locator) = getType (begin++);
3126
+
3127
+ // We can merge the type variables of same-kind atomic literal expressions because they
3128
+ // will all have the same set of constraints and therefore can never resolve to anything
3129
+ // different.
3130
+ auto *typeVar = type->getAs <TypeVariableType>();
3131
+ if (auto literalKind = getAtomicLiteralKind (typeVar)) {
3132
+ auto *&originalRep = representativeForKind[RawExprKind (*literalKind)];
3133
+ auto *currentRep = getRepresentative (typeVar);
3134
+
3135
+ if (originalRep) {
3136
+ if (originalRep != currentRep)
3137
+ mergeEquivalenceClasses (currentRep, originalRep);
3138
+ continue ;
3139
+ }
3140
+
3141
+ originalRep = currentRep;
3142
+ }
3143
+
3144
+ // Introduce conversions from each input type to the supertype.
3145
+ addConstraint (ConstraintKind::Conversion, type, resultTy, locator);
3146
+ }
3147
+
3148
+ return resultTy;
3149
+ }
3091
3150
3092
3151
// / Add a constraint to the constraint system with an associated fix.
3093
3152
void addFixConstraint (ConstraintFix *fix, ConstraintKind kind,
0 commit comments