diff --git a/include/swift/Basic/SourceManager.h b/include/swift/Basic/SourceManager.h index 1ad3dc07dcf..fd3b9a8d5bd 100644 --- a/include/swift/Basic/SourceManager.h +++ b/include/swift/Basic/SourceManager.h @@ -103,6 +103,13 @@ public: rangeContainsTokenLoc(Enclosing, Inner.End); } + /// Returns true if range \p R contains the code-completion location, if any. + bool rangeContainsCodeCompletionLoc(SourceRange R) const { + return CodeCompletionBufferID + ? rangeContainsTokenLoc(R, getCodeCompletionLoc()) + : false; + } + /// Returns the buffer ID for the specified *valid* location. /// /// Because a valid source location always corresponds to a source buffer, diff --git a/lib/Sema/BuilderTransform.cpp b/lib/Sema/BuilderTransform.cpp index 311e14fd2b6..0196d753113 100644 --- a/lib/Sema/BuilderTransform.cpp +++ b/lib/Sema/BuilderTransform.cpp @@ -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());