Skip to content

Commit 34c34b5

Browse files
authored
Merge pull request #74860 from hamishknight/isolated-completion
[Completion] Complete `.isolation` for `@isolated(any)` functions
2 parents c349110 + 94ed241 commit 34c34b5

File tree

3 files changed

+62
-6
lines changed

3 files changed

+62
-6
lines changed

include/swift/IDE/CompletionLookup.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
441441

442442
void addPrecedenceGroupRef(PrecedenceGroupDecl *PGD);
443443

444+
/// Add a builtin member reference pattern. This is used for members that
445+
/// do not have associated decls, e.g tuple access and '.isolation'.
446+
void addBuiltinMemberRef(StringRef Name, Type TypeAnnotation);
447+
444448
void addEnumElementRef(const EnumElementDecl *EED, DeclVisibilityKind Reason,
445449
DynamicLookupInfo dynamicLookupInfo,
446450
bool HasTypeContext);
@@ -506,6 +510,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
506510

507511
bool tryTupleExprCompletions(Type ExprType);
508512

513+
/// Try add the completion for '.isolation' for @isolated(any) function types.
514+
void tryFunctionIsolationCompletion(Type ExprType);
515+
509516
bool tryFunctionCallCompletions(
510517
Type ExprType, const ValueDecl *VD,
511518
std::optional<SemanticContextKind> SemanticContext = std::nullopt);

lib/IDE/CompletionLookup.cpp

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,6 +1765,15 @@ void CompletionLookup::addPrecedenceGroupRef(PrecedenceGroupDecl *PGD) {
17651765
builder.setAssociatedDecl(PGD);
17661766
}
17671767

1768+
void CompletionLookup::addBuiltinMemberRef(StringRef Name,
1769+
Type TypeAnnotation) {
1770+
CodeCompletionResultBuilder Builder = makeResultBuilder(
1771+
CodeCompletionResultKind::Pattern, SemanticContextKind::CurrentNominal);
1772+
addLeadingDot(Builder);
1773+
Builder.addBaseName(Name);
1774+
addTypeAnnotation(Builder, TypeAnnotation);
1775+
}
1776+
17681777
void CompletionLookup::addEnumElementRef(const EnumElementDecl *EED,
17691778
DeclVisibilityKind Reason,
17701779
DynamicLookupInfo dynamicLookupInfo,
@@ -2277,25 +2286,34 @@ bool CompletionLookup::tryTupleExprCompletions(Type ExprType) {
22772286

22782287
unsigned Index = 0;
22792288
for (auto TupleElt : TT->getElements()) {
2280-
CodeCompletionResultBuilder Builder = makeResultBuilder(
2281-
CodeCompletionResultKind::Pattern, SemanticContextKind::CurrentNominal);
2282-
addLeadingDot(Builder);
2289+
auto Ty = TupleElt.getType();
22832290
if (TupleElt.hasName()) {
2284-
Builder.addBaseName(TupleElt.getName().str());
2291+
addBuiltinMemberRef(TupleElt.getName().str(), Ty);
22852292
} else {
22862293
llvm::SmallString<4> IndexStr;
22872294
{
22882295
llvm::raw_svector_ostream OS(IndexStr);
22892296
OS << Index;
22902297
}
2291-
Builder.addBaseName(IndexStr.str());
2298+
addBuiltinMemberRef(IndexStr, Ty);
22922299
}
2293-
addTypeAnnotation(Builder, TupleElt.getType());
22942300
++Index;
22952301
}
22962302
return true;
22972303
}
22982304

2305+
void CompletionLookup::tryFunctionIsolationCompletion(Type ExprType) {
2306+
auto *FT = ExprType->getAs<FunctionType>();
2307+
if (!FT || !FT->getIsolation().isErased())
2308+
return;
2309+
2310+
// The type of `.isolation` is `(any Actor)?`
2311+
auto *actorProto = Ctx.getProtocol(KnownProtocolKind::Actor);
2312+
auto memberTy = OptionalType::get(actorProto->getDeclaredExistentialType());
2313+
2314+
addBuiltinMemberRef(Ctx.Id_isolation.str(), memberTy);
2315+
}
2316+
22992317
bool CompletionLookup::tryFunctionCallCompletions(
23002318
Type ExprType, const ValueDecl *VD,
23012319
std::optional<SemanticContextKind> SemanticContext) {
@@ -2373,6 +2391,9 @@ bool CompletionLookup::tryUnwrappedCompletions(Type ExprType, bool isIUO) {
23732391
}
23742392
if (NumBytesToEraseForOptionalUnwrap <=
23752393
CodeCompletionResult::MaxNumBytesToErase) {
2394+
// Add '.isolation' to @isolated(any) functions.
2395+
tryFunctionIsolationCompletion(Unwrapped);
2396+
23762397
if (!tryTupleExprCompletions(Unwrapped)) {
23772398
lookupVisibleMemberDecls(*this, Unwrapped, DotLoc,
23782399
CurrDeclContext,
@@ -2448,6 +2469,10 @@ void CompletionLookup::getValueExprCompletions(Type ExprType, ValueDecl *VD,
24482469
ExprType = OptionalType::get(ExprType);
24492470

24502471
// Handle special cases
2472+
2473+
// Add '.isolation' to @isolated(any) functions.
2474+
tryFunctionIsolationCompletion(ExprType);
2475+
24512476
bool isIUO = VD && VD->isImplicitlyUnwrappedOptional();
24522477
if (tryFunctionCallCompletions(ExprType, IsDeclUnapplied ? VD : nullptr))
24532478
return;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %batch-code-completion
2+
3+
// REQUIRES: concurrency
4+
5+
func test1(_ x: () -> Void) {
6+
x.#^NORMAL_FN^#
7+
// NORMAL_FN: Begin completions, 2 items
8+
// NORMAL_FN-DAG: Keyword[self]/CurrNominal: self[#() -> Void#]; name=self
9+
// NORMAL_FN-DAG: Pattern/CurrModule/Flair[ArgLabels]/Erase[1]: ()[#Void#]; name=()
10+
}
11+
12+
func test2(_ x: @isolated(any) () -> Void) {
13+
x.#^ISOLATED_ANY_FN^#
14+
// ISOLATED_ANY_FN: Begin completions, 3 items
15+
// ISOLATED_ANY_FN-DAG: Pattern/CurrNominal: isolation[#(any Actor)?#]; name=isolation
16+
// ISOLATED_ANY_FN-DAG: Keyword[self]/CurrNominal: self[#@isolated(any) () -> Void#]; name=self
17+
// ISOLATED_ANY_FN-DAG: Pattern/CurrModule/Flair[ArgLabels]/Erase[1]: ()[#Void#]; name=()
18+
}
19+
20+
func test3(_ x: (@isolated(any) () -> Void)?) {
21+
x.#^ISOLATED_ANY_OPTIONAL_FN^#
22+
// ISOLATED_ANY_OPTIONAL_FN-DAG: Pattern/CurrNominal/Erase[1]: ?.isolation[#(any Actor)?#]; name=isolation
23+
// ISOLATED_ANY_OPTIONAL_FN-DAG: Keyword[self]/CurrNominal: self[#(@isolated(any) () -> Void)?#]; name=self
24+
}

0 commit comments

Comments
 (0)