Skip to content

Commit a52b4d9

Browse files
authored
Merge pull request #10119 from rudkx/enable-type-map
[Constraint solver] Update type map code for recursion through salvag…
2 parents 856429c + 916ce89 commit a52b4d9

File tree

3 files changed

+54
-8
lines changed

3 files changed

+54
-8
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3282,14 +3282,23 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
32823282
// expression (which may lead to infinite recursion). If the client is
32833283
// telling us that it knows what it is doing, then believe it.
32843284
if (!options.contains(TCC_ForceRecheck)) {
3285-
if (Expr *res = CS->TC.isExprBeingDiagnosed(subExpr)) {
3285+
if (CS->TC.isExprBeingDiagnosed(subExpr)) {
3286+
auto exprAndCS = CS->TC.getExprBeingDiagnosed(subExpr);
3287+
auto *savedExpr = exprAndCS.first;
3288+
if (subExpr == savedExpr)
3289+
return subExpr;
3290+
3291+
auto *oldCS = exprAndCS.second;
3292+
32863293
// The types on the result might have already been cached into
32873294
// another CS, but likely not this one.
3288-
CS->cacheExprTypes(res);
3289-
return res;
3295+
if (oldCS != CS)
3296+
CS->transferExprTypes(oldCS, savedExpr);
3297+
3298+
return savedExpr;
32903299
}
32913300

3292-
CS->TC.addExprForDiagnosis(subExpr, subExpr);
3301+
CS->TC.addExprForDiagnosis(subExpr, std::make_pair(subExpr, CS));
32933302
}
32943303

32953304
// Validate contextual type before trying to use it.
@@ -3377,8 +3386,8 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
33773386
SavedTypeData.restore();
33783387
}
33793388

3380-
CS->TC.addExprForDiagnosis(preCheckedExpr, subExpr);
33813389
CS->cacheExprTypes(subExpr);
3390+
CS->TC.addExprForDiagnosis(preCheckedExpr, std::make_pair(subExpr, CS));
33823391

33833392
return subExpr;
33843393
}

lib/Sema/ConstraintSystem.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,30 @@ class ConstraintSystem {
12871287
bool walkToDeclPre(Decl *decl) override { return false; }
12881288
};
12891289

1290+
class TransferExprTypes : public ASTWalker {
1291+
ConstraintSystem &toCS;
1292+
ConstraintSystem &fromCS;
1293+
1294+
public:
1295+
TransferExprTypes(ConstraintSystem &toCS, ConstraintSystem &fromCS)
1296+
: toCS(toCS), fromCS(fromCS) {}
1297+
1298+
Expr *walkToExprPost(Expr *expr) override {
1299+
if (fromCS.hasType(expr))
1300+
toCS.setType(expr, fromCS.getType(expr));
1301+
1302+
return expr;
1303+
}
1304+
1305+
/// \brief Ignore statements.
1306+
std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
1307+
return { false, stmt };
1308+
}
1309+
1310+
/// \brief Ignore declarations.
1311+
bool walkToDeclPre(Decl *decl) override { return false; }
1312+
};
1313+
12901314
public:
12911315

12921316
void setExprTypes(Expr *expr) {
@@ -1312,6 +1336,10 @@ class ConstraintSystem {
13121336
expr->walk(CacheExprTypes(expr, *this, excludeRoot));
13131337
}
13141338

1339+
void transferExprTypes(ConstraintSystem *oldCS, Expr *expr) {
1340+
expr->walk(TransferExprTypes(*this, *oldCS));
1341+
}
1342+
13151343
/// \brief The current solver state.
13161344
///
13171345
/// This will be non-null when we're actively solving the constraint

lib/Sema/TypeChecker.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ namespace constraints {
5555
typedef llvm::DenseMap<SubstitutableType *,
5656
SmallVector<ProtocolConformance *, 2>> ConformanceMap;
5757

58+
/// \brief Used for recursive lookups into an expr that is already
59+
/// being type-checked and the constraint system in which its type is
60+
/// stored.
61+
typedef std::pair<Expr *,
62+
constraints::ConstraintSystem *> ExprAndConstraintSystem;
63+
5864
/// Special-case type checking semantics for certain declarations.
5965
enum class DeclTypeCheckingSemantics {
6066
/// A normal declaration.
@@ -816,7 +822,7 @@ class TypeChecker final : public LazyResolver {
816822
llvm::DenseSet<CanType> CIntegerTypes;
817823

818824
/// The set of expressions currently being analyzed for failures.
819-
llvm::DenseMap<Expr*, Expr*> DiagnosedExprs;
825+
llvm::DenseMap<Expr*, ExprAndConstraintSystem> DiagnosedExprs;
820826

821827
ModuleDecl *StdlibModule = nullptr;
822828

@@ -2307,10 +2313,13 @@ class TypeChecker final : public LazyResolver {
23072313
void checkInitializerErrorHandling(Initializer *I, Expr *E);
23082314
void checkEnumElementErrorHandling(EnumElementDecl *D);
23092315

2310-
void addExprForDiagnosis(Expr *E1, Expr *Result) {
2316+
void addExprForDiagnosis(Expr *E1, ExprAndConstraintSystem Result) {
23112317
DiagnosedExprs[E1] = Result;
23122318
}
2313-
Expr *isExprBeingDiagnosed(Expr *E) {
2319+
bool isExprBeingDiagnosed(Expr *E) {
2320+
return DiagnosedExprs.count(E);
2321+
}
2322+
ExprAndConstraintSystem getExprBeingDiagnosed(Expr *E) {
23142323
return DiagnosedExprs[E];
23152324
}
23162325

0 commit comments

Comments
 (0)