[Completion] Complete .isolation for @isolated(any) functions

This was added in SE-0431.

rdar://124615036
This commit is contained in:
Hamish Knight
2024-07-01 12:49:52 +01:00
parent 1f83e66a3e
commit 94ed2418f4
3 changed files with 46 additions and 0 deletions

View File

@@ -510,6 +510,9 @@ public:
bool tryTupleExprCompletions(Type ExprType);
/// Try add the completion for '.isolation' for @isolated(any) function types.
void tryFunctionIsolationCompletion(Type ExprType);
bool tryFunctionCallCompletions(
Type ExprType, const ValueDecl *VD,
std::optional<SemanticContextKind> SemanticContext = std::nullopt);

View File

@@ -2302,6 +2302,18 @@ bool CompletionLookup::tryTupleExprCompletions(Type ExprType) {
return true;
}
void CompletionLookup::tryFunctionIsolationCompletion(Type ExprType) {
auto *FT = ExprType->getAs<FunctionType>();
if (!FT || !FT->getIsolation().isErased())
return;
// The type of `.isolation` is `(any Actor)?`
auto *actorProto = Ctx.getProtocol(KnownProtocolKind::Actor);
auto memberTy = OptionalType::get(actorProto->getDeclaredExistentialType());
addBuiltinMemberRef(Ctx.Id_isolation.str(), memberTy);
}
bool CompletionLookup::tryFunctionCallCompletions(
Type ExprType, const ValueDecl *VD,
std::optional<SemanticContextKind> SemanticContext) {
@@ -2379,6 +2391,9 @@ bool CompletionLookup::tryUnwrappedCompletions(Type ExprType, bool isIUO) {
}
if (NumBytesToEraseForOptionalUnwrap <=
CodeCompletionResult::MaxNumBytesToErase) {
// Add '.isolation' to @isolated(any) functions.
tryFunctionIsolationCompletion(Unwrapped);
if (!tryTupleExprCompletions(Unwrapped)) {
lookupVisibleMemberDecls(*this, Unwrapped, DotLoc,
CurrDeclContext,
@@ -2454,6 +2469,10 @@ void CompletionLookup::getValueExprCompletions(Type ExprType, ValueDecl *VD,
ExprType = OptionalType::get(ExprType);
// Handle special cases
// Add '.isolation' to @isolated(any) functions.
tryFunctionIsolationCompletion(ExprType);
bool isIUO = VD && VD->isImplicitlyUnwrappedOptional();
if (tryFunctionCallCompletions(ExprType, IsDeclUnapplied ? VD : nullptr))
return;

View File

@@ -0,0 +1,24 @@
// RUN: %batch-code-completion
// REQUIRES: concurrency
func test1(_ x: () -> Void) {
x.#^NORMAL_FN^#
// NORMAL_FN: Begin completions, 2 items
// NORMAL_FN-DAG: Keyword[self]/CurrNominal: self[#() -> Void#]; name=self
// NORMAL_FN-DAG: Pattern/CurrModule/Flair[ArgLabels]/Erase[1]: ()[#Void#]; name=()
}
func test2(_ x: @isolated(any) () -> Void) {
x.#^ISOLATED_ANY_FN^#
// ISOLATED_ANY_FN: Begin completions, 3 items
// ISOLATED_ANY_FN-DAG: Pattern/CurrNominal: isolation[#(any Actor)?#]; name=isolation
// ISOLATED_ANY_FN-DAG: Keyword[self]/CurrNominal: self[#@isolated(any) () -> Void#]; name=self
// ISOLATED_ANY_FN-DAG: Pattern/CurrModule/Flair[ArgLabels]/Erase[1]: ()[#Void#]; name=()
}
func test3(_ x: (@isolated(any) () -> Void)?) {
x.#^ISOLATED_ANY_OPTIONAL_FN^#
// ISOLATED_ANY_OPTIONAL_FN-DAG: Pattern/CurrNominal/Erase[1]: ?.isolation[#(any Actor)?#]; name=isolation
// ISOLATED_ANY_OPTIONAL_FN-DAG: Keyword[self]/CurrNominal: self[#(@isolated(any) () -> Void)?#]; name=self
}