Skip to content

Commit db6694b

Browse files
committed
[Type checker] Limit the number of type variables introduced for placeholders.
The type checker introduces fresh type variables for editor placeholders that are encountered in the source. If there are many such editor placeholders, we'll create a large number of type variables with very little context, which can cause poor scaling in the type checker. Since we get very little information out of these type variables, artificially limit the number of type variables we create (to 2) and rotate through them. Another piece of rdar://problem/29389887. (cherry picked from commit 207fffc)
1 parent d993a51 commit db6694b

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

lib/Sema/CSGen.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,16 @@ namespace {
10221022
DeclContext *CurDC;
10231023
SmallVector<DeclContext*, 4> DCStack;
10241024

1025+
static const unsigned numEditorPlaceholderVariables = 2;
1026+
1027+
/// A buffer of type variables used for editor placeholders. We only
1028+
/// use a small number of these (rotating through), to prevent expressions
1029+
/// with a large number of editor placeholders from flooding the constraint
1030+
/// system with type variables.
1031+
TypeVariableType *editorPlaceholderVariables[numEditorPlaceholderVariables]
1032+
= { nullptr, nullptr };
1033+
unsigned currentEditorPlaceholderVariable = 0;
1034+
10251035
/// \brief Add constraints for a reference to a named member of the given
10261036
/// base type, and return the type of such a reference.
10271037
Type addMemberRefConstraints(Expr *expr, Expr *base, DeclName name,
@@ -2760,14 +2770,28 @@ namespace {
27602770
Type visitEditorPlaceholderExpr(EditorPlaceholderExpr *E) {
27612771
if (E->getTypeLoc().isNull()) {
27622772
auto locator = CS.getConstraintLocator(E);
2763-
auto placeholderTy = CS.createTypeVariable(locator, /*options*/0);
2773+
27642774
// A placeholder may have any type, but default to Void type if
27652775
// otherwise unconstrained.
2766-
CS.addConstraint(ConstraintKind::Defaultable,
2767-
placeholderTy, TupleType::getEmpty(CS.getASTContext()),
2768-
locator);
2776+
auto &placeholderTy
2777+
= editorPlaceholderVariables[currentEditorPlaceholderVariable];
2778+
if (!placeholderTy) {
2779+
placeholderTy = CS.createTypeVariable(locator, /*options*/0);
2780+
2781+
CS.addConstraint(ConstraintKind::Defaultable,
2782+
placeholderTy,
2783+
TupleType::getEmpty(CS.getASTContext()),
2784+
locator);
2785+
}
2786+
2787+
// Move to the next placeholder variable.
2788+
currentEditorPlaceholderVariable
2789+
= (currentEditorPlaceholderVariable + 1) %
2790+
numEditorPlaceholderVariables;
2791+
27692792
return placeholderTy;
27702793
}
2794+
27712795
// NOTE: The type loc may be there but have failed to validate, in which
27722796
// case we return the null type.
27732797
return E->getType();

0 commit comments

Comments
 (0)