@@ -908,6 +908,7 @@ using OpenedTypeMap =
908908// / within a constraint system.
909909struct ContextualTypeInfo {
910910 TypeLoc typeLoc;
911+
911912 ContextualTypePurpose purpose;
912913
913914 ContextualTypeInfo () : typeLoc(TypeLoc()), purpose(CTP_Unused) {}
@@ -2343,8 +2344,10 @@ class ConstraintSystem {
23432344 solutionApplicationTargets;
23442345
23452346 // / 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;
23482351
23492352 // / Information about each case label item tracked by the constraint system.
23502353 llvm::SmallMapVector<const CaseLabelItem *, CaseLabelItemInfo, 4 >
@@ -3184,21 +3187,47 @@ class ConstraintSystem {
31843187 assert (bool (node) && " Expected non-null expression!" );
31853188 assert (contextualTypes.count (node) == 0 &&
31863189 " Already set this contextual type" );
3187- contextualTypes[node] = {T, purpose};
3190+ contextualTypes[node] = {{ T, purpose}, Type () };
31883191 }
31893192
31903193 Optional<ContextualTypeInfo> getContextualTypeInfo (ASTNode node) const {
31913194 auto known = contextualTypes.find (node);
31923195 if (known == contextualTypes.end ())
31933196 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+ }
32023231 }
32033232
32043233 TypeLoc getContextualTypeLoc (ASTNode node) const {
0 commit comments