Skip to content

Commit 83cb351

Browse files
committed
[Constraint solver] Allow contextual types for multiple expressions.
Generalize the representation of contextual types so we can store contextual types for more than one expression. Allow these to be added/rolled back in solver scopes. Nothing uses this functionality yet.
1 parent 5b195ae commit 83cb351

File tree

3 files changed

+46
-21
lines changed

3 files changed

+46
-21
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ ConstraintSystem::SolverScope::SolverScope(ConstraintSystem &cs)
441441
numFunctionBuilderTransformed = cs.functionBuilderTransformed.size();
442442
numResolvedOverloads = cs.ResolvedOverloads.size();
443443
numInferredClosureTypes = cs.ClosureTypes.size();
444+
numContextualTypes = cs.contextualTypes.size();
444445

445446
PreviousScore = cs.CurrentScore;
446447

@@ -510,6 +511,9 @@ ConstraintSystem::SolverScope::~SolverScope() {
510511
// Remove any inferred closure types (e.g. used in function builder body).
511512
truncate(cs.ClosureTypes, numInferredClosureTypes);
512513

514+
// Remove any contextual types.
515+
truncate(cs.contextualTypes, numContextualTypes);
516+
513517
// Reset the previous score.
514518
cs.CurrentScore = PreviousScore;
515519

lib/Sema/ConstraintSystem.h

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,17 +1300,21 @@ class ConstraintSystem {
13001300
llvm::DenseMap<std::pair<const KeyPathExpr *, unsigned>, TypeBase *>
13011301
KeyPathComponentTypes;
13021302

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+
13031314
/// Maps closure parameters to type variables.
13041315
llvm::DenseMap<const ParamDecl *, TypeVariableType *>
13051316
OpenedParameterTypes;
13061317

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-
13141318
/// The set of constraint restrictions used to reach the
13151319
/// current constraint system.
13161320
///
@@ -1880,6 +1884,9 @@ class ConstraintSystem {
18801884
/// The length of \c ClosureTypes.
18811885
unsigned numInferredClosureTypes;
18821886

1887+
/// The length of \c contextualTypes.
1888+
unsigned numContextualTypes;
1889+
18831890
/// The previous score.
18841891
Score PreviousScore;
18851892

@@ -2167,25 +2174,39 @@ class ConstraintSystem {
21672174
return E;
21682175
}
21692176

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 };
21752182
}
21762183

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();
21802196
}
21812197

21822198
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();
21842203
}
21852204

21862205
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;
21892210
}
21902211

21912212
/// Retrieve the constraint locator for the given anchor and

lib/Sema/TypeCheckConstraints.cpp

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

37713771
out << "Score: " << CurrentScore << "\n";
37723772

3773-
if (auto ty = contextualType.getType()) {
3774-
out << "Contextual Type: " << ty.getString(PO);
3775-
if (TypeRepr *TR = contextualType.getTypeRepr()) {
3773+
for (const auto &contextualType : contextualTypes) {
3774+
out << "Contextual Type: " << contextualType.second.getType().getString(PO);
3775+
if (TypeRepr *TR = contextualType.second.typeLoc.getTypeRepr()) {
37763776
out << " at ";
37773777
TR->getSourceRange().print(out, getASTContext().SourceMgr, /*text*/false);
37783778
}

0 commit comments

Comments
 (0)