Skip to content

Commit 5a58abd

Browse files
authored
Merge pull request #74873 from hamishknight/isolated-completion-6.0
[6.0] [Completion] Complete `.isolation` for `@isolated(any)` functions
2 parents 05ffb67 + 60c7261 commit 5a58abd

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
@@ -1764,6 +1764,15 @@ void CompletionLookup::addPrecedenceGroupRef(PrecedenceGroupDecl *PGD) {
17641764
builder.setAssociatedDecl(PGD);
17651765
}
17661766

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

22772286
unsigned Index = 0;
22782287
for (auto TupleElt : TT->getElements()) {
2279-
CodeCompletionResultBuilder Builder = makeResultBuilder(
2280-
CodeCompletionResultKind::Pattern, SemanticContextKind::CurrentNominal);
2281-
addLeadingDot(Builder);
2288+
auto Ty = TupleElt.getType();
22822289
if (TupleElt.hasName()) {
2283-
Builder.addBaseName(TupleElt.getName().str());
2290+
addBuiltinMemberRef(TupleElt.getName().str(), Ty);
22842291
} else {
22852292
llvm::SmallString<4> IndexStr;
22862293
{
22872294
llvm::raw_svector_ostream OS(IndexStr);
22882295
OS << Index;
22892296
}
2290-
Builder.addBaseName(IndexStr.str());
2297+
addBuiltinMemberRef(IndexStr, Ty);
22912298
}
2292-
addTypeAnnotation(Builder, TupleElt.getType());
22932299
++Index;
22942300
}
22952301
return true;
22962302
}
22972303

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

24492470
// Handle special cases
2471+
2472+
// Add '.isolation' to @isolated(any) functions.
2473+
tryFunctionIsolationCompletion(ExprType);
2474+
24502475
bool isIUO = VD && VD->isImplicitlyUnwrappedOptional();
24512476
if (tryFunctionCallCompletions(ExprType, IsDeclUnapplied ? VD : nullptr))
24522477
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)