@@ -908,6 +908,7 @@ using OpenedTypeMap =
908
908
// / within a constraint system.
909
909
struct ContextualTypeInfo {
910
910
TypeLoc typeLoc;
911
+
911
912
ContextualTypePurpose purpose;
912
913
913
914
ContextualTypeInfo () : typeLoc(TypeLoc()), purpose(CTP_Unused) {}
@@ -2343,8 +2344,10 @@ class ConstraintSystem {
2343
2344
solutionApplicationTargets;
2344
2345
2345
2346
// / Contextual type information for expressions that are part of this
2346
- // / constraint system.
2347
- llvm::MapVector<ASTNode, ContextualTypeInfo> contextualTypes;
2347
+ // / constraint system. The second type, if valid, contains the type as it
2348
+ // / should appear in actual constraint. This will have unbound generic types
2349
+ // / opened, placeholder types converted to type variables, etc.
2350
+ llvm::MapVector<ASTNode, std::pair<ContextualTypeInfo, Type>> contextualTypes;
2348
2351
2349
2352
// / Information about each case label item tracked by the constraint system.
2350
2353
llvm::SmallMapVector<const CaseLabelItem *, CaseLabelItemInfo, 4 >
@@ -3184,21 +3187,47 @@ class ConstraintSystem {
3184
3187
assert (bool (node) && " Expected non-null expression!" );
3185
3188
assert (contextualTypes.count (node) == 0 &&
3186
3189
" Already set this contextual type" );
3187
- contextualTypes[node] = {T, purpose};
3190
+ contextualTypes[node] = {{ T, purpose}, Type () };
3188
3191
}
3189
3192
3190
3193
Optional<ContextualTypeInfo> getContextualTypeInfo (ASTNode node) const {
3191
3194
auto known = contextualTypes.find (node);
3192
3195
if (known == contextualTypes.end ())
3193
3196
return None;
3194
- return known->second ;
3195
- }
3196
-
3197
- Type getContextualType (ASTNode node) const {
3198
- auto result = getContextualTypeInfo (node);
3199
- if (result)
3200
- return result->typeLoc .getType ();
3201
- return Type ();
3197
+ return known->second .first ;
3198
+ }
3199
+
3200
+ // / Gets the contextual type recorded for an AST node. When fetching a type
3201
+ // / for use in constraint solving, \c forConstraint should be set to \c true,
3202
+ // / which will ensure that unbound generics have been opened and placeholder
3203
+ // / types have been converted to type variables, etc.
3204
+ Type getContextualType (ASTNode node, bool forConstraint = false ) {
3205
+ if (forConstraint) {
3206
+ auto known = contextualTypes.find (node);
3207
+ if (known == contextualTypes.end ())
3208
+ return Type ();
3209
+
3210
+ // If we've already computed a type for use in the constraint system,
3211
+ // use that.
3212
+ if (known->second .second )
3213
+ return known->second .second ;
3214
+
3215
+ // Otherwise, compute a type that can be used in a constraint and record
3216
+ // it.
3217
+ auto info = known->second .first ;
3218
+
3219
+ auto *locator = getConstraintLocator (
3220
+ node, LocatorPathElt::ContextualType (info.purpose ));
3221
+ known->second .second = replaceInferableTypesWithTypeVars (info.getType (),
3222
+ locator);
3223
+
3224
+ return known->second .second ;
3225
+ } else {
3226
+ auto result = getContextualTypeInfo (node);
3227
+ if (result)
3228
+ return result->getType ();
3229
+ return Type ();
3230
+ }
3202
3231
}
3203
3232
3204
3233
TypeLoc getContextualTypeLoc (ASTNode node) const {
0 commit comments