[code-completion] Disable diagnostics in @functionBuilder bodies

When performing code-completion inside the body of a @functionBuilder
closure/function, set the flag to suppress diagnostics. This works
around a big performance problem in some complex bodies that do not
typecheck, which is typical during code-completion. A real-world example
with SwitfUI went from ~50 seconds to 0.5. We do not disable diagnostics
in general because the diagnostic paths provide falback types that are
useful to code-completion.

rdar://52356229
This commit is contained in:
Ben Langmuir
2019-07-02 07:31:53 -07:00
parent 7211a51dc3
commit c6eade1c44
2 changed files with 19 additions and 0 deletions

View File

@@ -496,6 +496,12 @@ bool TypeChecker::typeCheckFunctionBuilderFuncBody(FuncDecl *FD,
options |= TypeCheckExprFlags::ConvertTypeIsOpaqueReturnType;
}
// If we are performing code-completion inside the functions body, supress
// diagnostics to workaround typechecking performance problems.
if (Context.SourceMgr.rangeContainsCodeCompletionLoc(
FD->getBody()->getSourceRange()))
options |= TypeCheckExprFlags::SuppressDiagnostics;
// Type-check the single result expression.
Type returnExprType = typeCheckExpression(returnExpr, FD,
TypeLoc::withoutLoc(returnType),
@@ -574,6 +580,12 @@ ConstraintSystem::TypeMatchResult ConstraintSystem::applyFunctionBuilder(
assert(!builderType->hasTypeParameter());
}
// If we are performing code-completion inside the closure body, supress
// diagnostics to workaround typechecking performance problems.
if (getASTContext().SourceMgr.rangeContainsCodeCompletionLoc(
closure->getSourceRange()))
Options |= ConstraintSystemFlags::SuppressDiagnostics;
BuilderClosureVisitor visitor(getASTContext(), this,
/*wantExpr=*/true, builderType);
Expr *singleExpr = visitor.visit(closure->getBody());