Skip to content

Commit f6b6f0c

Browse files
committed
Lift replaceInferableTypes call into getContextualType
1 parent 0000448 commit f6b6f0c

File tree

4 files changed

+57
-22
lines changed

4 files changed

+57
-22
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,7 @@ using OpenedTypeMap =
908908
/// within a constraint system.
909909
struct 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 {

lib/Sema/CSGen.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,8 +1732,9 @@ namespace {
17321732

17331733
// If a contextual type exists for this expression, apply it directly.
17341734
if (contextualType && ConstraintSystem::isArrayType(contextualType)) {
1735-
contextualType = CS.replaceInferableTypesWithTypeVars(
1736-
contextualType, CS.getConstraintLocator(expr));
1735+
// Now that we know we're actually going to use the type, get the
1736+
// version for use in a constraint.
1737+
contextualType = CS.getContextualType(expr, /*forConstraint=*/true);
17371738
Optional<Type> arrayElementType =
17381739
ConstraintSystem::isArrayType(contextualType);
17391740
CS.addConstraint(ConstraintKind::LiteralConformsTo, contextualType,
@@ -1838,15 +1839,18 @@ namespace {
18381839
auto locator = CS.getConstraintLocator(expr);
18391840
auto contextualType = CS.getContextualType(expr);
18401841
auto contextualPurpose = CS.getContextualTypePurpose(expr);
1841-
auto openedType =
1842-
CS.openOpaqueType(contextualType, contextualPurpose, locator);
18431842

18441843
// If a contextual type exists for this expression and is a dictionary
18451844
// type, apply it directly.
1846-
if (openedType && ConstraintSystem::isDictionaryType(openedType)) {
1845+
if (contextualType && ConstraintSystem::isDictionaryType(contextualType)) {
1846+
// Now that we know we're actually going to use the type, get the
1847+
// version for use in a constraint.
1848+
contextualType = CS.getContextualType(expr, /*forConstraint=*/true);
1849+
auto openedType =
1850+
CS.openOpaqueType(contextualType, contextualPurpose, locator);
18471851
openedType = CS.replaceInferableTypesWithTypeVars(
18481852
openedType, CS.getConstraintLocator(expr));
1849-
Optional<std::pair<Type, Type>> dictionaryKeyValue =
1853+
auto dictionaryKeyValue =
18501854
ConstraintSystem::isDictionaryType(openedType);
18511855
Type contextualDictionaryKeyType;
18521856
Type contextualDictionaryValueType;

lib/Sema/CSSolver.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,9 @@ Solution ConstraintSystem::finalize() {
180180
}
181181

182182
// Remember contextual types.
183-
solution.contextualTypes.assign(
184-
contextualTypes.begin(), contextualTypes.end());
183+
for (auto &entry : contextualTypes) {
184+
solution.contextualTypes.push_back({entry.first, entry.second.first});
185+
}
185186

186187
solution.solutionApplicationTargets = solutionApplicationTargets;
187188
solution.caseLabelItems = caseLabelItems;

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,9 +1116,10 @@ void ConstraintSystem::print(raw_ostream &out) const {
11161116

11171117
out << "Score: " << CurrentScore << "\n";
11181118

1119-
for (const auto &contextualType : contextualTypes) {
1120-
out << "Contextual Type: " << contextualType.second.getType().getString(PO);
1121-
if (TypeRepr *TR = contextualType.second.typeLoc.getTypeRepr()) {
1119+
for (const auto &contextualTypeEntry : contextualTypes) {
1120+
auto info = contextualTypeEntry.second.first;
1121+
out << "Contextual Type: " << info.getType().getString(PO);
1122+
if (TypeRepr *TR = info.typeLoc.getTypeRepr()) {
11221123
out << " at ";
11231124
TR->getSourceRange().print(out, getASTContext().SourceMgr, /*text*/false);
11241125
}

0 commit comments

Comments
 (0)