@@ -1300,17 +1300,21 @@ class ConstraintSystem {
1300
1300
llvm::DenseMap<std::pair<const KeyPathExpr *, unsigned >, TypeBase *>
1301
1301
KeyPathComponentTypes;
1302
1302
1303
+ struct ContextualTypeInfo {
1304
+ TypeLoc typeLoc;
1305
+ ContextualTypePurpose purpose;
1306
+
1307
+ Type getType () const { return typeLoc.getType (); }
1308
+ };
1309
+
1310
+ // / Contextual type information for expressions that are part of this
1311
+ // / constraint system.
1312
+ llvm::MapVector<const Expr *, ContextualTypeInfo> contextualTypes;
1313
+
1303
1314
// / Maps closure parameters to type variables.
1304
1315
llvm::DenseMap<const ParamDecl *, TypeVariableType *>
1305
1316
OpenedParameterTypes;
1306
1317
1307
- // / There can only be a single contextual type on the root of the expression
1308
- // / being checked. If specified, this holds its type along with the base
1309
- // / expression, and the purpose of it.
1310
- TypeLoc contextualType;
1311
- Expr *contextualTypeNode = nullptr ;
1312
- ContextualTypePurpose contextualTypePurpose = CTP_Unused;
1313
-
1314
1318
// / The set of constraint restrictions used to reach the
1315
1319
// / current constraint system.
1316
1320
// /
@@ -1880,6 +1884,9 @@ class ConstraintSystem {
1880
1884
// / The length of \c ClosureTypes.
1881
1885
unsigned numInferredClosureTypes;
1882
1886
1887
+ // / The length of \c contextualTypes.
1888
+ unsigned numContextualTypes;
1889
+
1883
1890
// / The previous score.
1884
1891
Score PreviousScore;
1885
1892
@@ -2167,25 +2174,39 @@ class ConstraintSystem {
2167
2174
return E;
2168
2175
}
2169
2176
2170
- void setContextualType (Expr *E , TypeLoc T, ContextualTypePurpose purpose) {
2171
- assert (E != nullptr && " Expected non-null expression!" );
2172
- contextualTypeNode = E;
2173
- contextualType = T ;
2174
- contextualTypePurpose = purpose;
2177
+ void setContextualType (Expr *expr , TypeLoc T, ContextualTypePurpose purpose) {
2178
+ assert (expr != nullptr && " Expected non-null expression!" );
2179
+ assert (contextualTypes. count (expr) == 0 &&
2180
+ " Already set this contextual type " ) ;
2181
+ contextualTypes[expr] = { T, purpose } ;
2175
2182
}
2176
2183
2177
- Type getContextualType (Expr *E) const {
2178
- assert (E != nullptr && " Expected non-null expression!" );
2179
- return E == contextualTypeNode ? contextualType.getType () : Type ();
2184
+ Optional<ContextualTypeInfo> getContextualTypeInfo (Expr *expr) const {
2185
+ auto known = contextualTypes.find (expr);
2186
+ if (known == contextualTypes.end ())
2187
+ return None;
2188
+ return known->second ;
2189
+ }
2190
+
2191
+ Type getContextualType (Expr *expr) const {
2192
+ auto result = getContextualTypeInfo (expr);
2193
+ if (result)
2194
+ return result->typeLoc .getType ();
2195
+ return Type ();
2180
2196
}
2181
2197
2182
2198
TypeLoc getContextualTypeLoc (Expr *expr) const {
2183
- return expr == contextualTypeNode ? contextualType : TypeLoc ();
2199
+ auto result = getContextualTypeInfo (expr);
2200
+ if (result)
2201
+ return result->typeLoc ;
2202
+ return TypeLoc ();
2184
2203
}
2185
2204
2186
2205
ContextualTypePurpose getContextualTypePurpose (Expr *expr) const {
2187
- return (expr && expr == contextualTypeNode) ? contextualTypePurpose
2188
- : CTP_Unused;
2206
+ auto result = getContextualTypeInfo (expr);
2207
+ if (result)
2208
+ return result->purpose ;
2209
+ return CTP_Unused;
2189
2210
}
2190
2211
2191
2212
// / Retrieve the constraint locator for the given anchor and
0 commit comments