Skip to content

Commit 92ef981

Browse files
authored
[5.5] Async let family (swiftlang#37307)
* Revert "[Concurrency] Resyntax 'async let' as 'spawn let'." This reverts commit 41f42fa. * Reinstate "async let", with "spawn let" as an alias. * Add "async" aliases to task group "spawn" operations
1 parent 8ed3c4a commit 92ef981

19 files changed

+116
-89
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,7 +1862,7 @@ class PatternBindingDecl final : public Decl,
18621862
bool isComputingPatternBindingEntry(const VarDecl *vd) const;
18631863

18641864
/// Is this an "async let" declaration?
1865-
bool isSpawnLet() const;
1865+
bool isAsyncLet() const;
18661866

18671867
/// Gets the text of the initializer expression for the pattern entry at the
18681868
/// given index, stripping out inactive branches of any #ifs inside the
@@ -4942,7 +4942,7 @@ class VarDecl : public AbstractStorageDecl {
49424942
bool isLet() const { return getIntroducer() == Introducer::Let; }
49434943

49444944
/// Is this an "async let" property?
4945-
bool isSpawnLet() const;
4945+
bool isAsyncLet() const;
49464946

49474947
Introducer getIntroducer() const {
49484948
return Introducer(Bits.VarDecl.Introducer);

include/swift/AST/DiagnosticsSema.def

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4243,8 +4243,8 @@ ERROR(throwing_interpolation_without_try,none,
42434243
"interpolation can throw but is not marked with 'try'", ())
42444244
ERROR(throwing_call_without_try,none,
42454245
"call can throw but is not marked with 'try'", ())
4246-
ERROR(throwing_spawn_let_without_try,none,
4247-
"reading 'spawn let' can throw but is not marked with 'try'", ())
4246+
ERROR(throwing_async_let_without_try,none,
4247+
"reading 'async let' can throw but is not marked with 'try'", ())
42484248
ERROR(throwing_prop_access_without_try,none,
42494249
"property access can throw but is not marked with 'try'", ())
42504250
ERROR(throwing_subscript_access_without_try,none,
@@ -4273,8 +4273,8 @@ NOTE(async_access_without_await,none,
42734273

42744274
NOTE(async_call_without_await_in_autoclosure,none,
42754275
"call is 'async' in an autoclosure argument", ())
4276-
NOTE(async_call_without_await_in_spawn_let,none,
4277-
"call is 'async' in an 'spawn let' initializer", ())
4276+
NOTE(async_call_without_await_in_async_let,none,
4277+
"call is 'async' in an 'async let' initializer", ())
42784278

42794279
WARNING(no_async_in_await,none,
42804280
"no 'async' operations occur within 'await' expression", ())
@@ -4287,7 +4287,7 @@ ERROR(await_in_illegal_context,none,
42874287
"%select{<<ERROR>>|a default argument|a property wrapper initializer|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}0",
42884288
(unsigned))
42894289
ERROR(async_in_nonasync_function,none,
4290-
"%select{'async'|'async' call|'await'|'spawn let'|'async' property access|'async' subscript access}0 in "
4290+
"%select{'async'|'async' call|'await'|'async let'|'async' property access|'async' subscript access}0 in "
42914291
"%select{a function|an autoclosure}1 that does not support concurrency",
42924292
(unsigned, bool))
42934293
NOTE(note_add_async_to_function,none,
@@ -4314,21 +4314,18 @@ NOTE(protocol_witness_async_conflict,none,
43144314
ERROR(async_autoclosure_nonasync_function,none,
43154315
"'async' autoclosure parameter in a non-'async' function", ())
43164316

4317-
WARNING(async_let_is_spawn_let,none,
4318-
"'async let' is now 'spawn let'", ())
4319-
4320-
ERROR(spawn_not_let,none,
4321-
"'spawn' can only be used with 'let' declarations", ())
4322-
ERROR(spawn_let_not_local,none,
4323-
"'spawn let' can only be used on local declarations", ())
4324-
ERROR(spawn_let_not_initialized,none,
4325-
"'spawn let' binding requires an initializer expression", ())
4326-
ERROR(spawn_let_no_variables,none,
4327-
"'spawn let' requires at least one named variable", ())
4328-
NOTE(spawn_let_without_await,none,
4329-
"reference to spawn let %0 is 'async'", (DeclName))
4330-
ERROR(spawn_let_in_illegal_context,none,
4331-
"spawn let %0 cannot be referenced in "
4317+
ERROR(async_not_let,none,
4318+
"'async' can only be used with 'let' declarations", ())
4319+
ERROR(async_let_not_local,none,
4320+
"'async let' can only be used on local declarations", ())
4321+
ERROR(async_let_not_initialized,none,
4322+
"'async let' binding requires an initializer expression", ())
4323+
ERROR(async_let_no_variables,none,
4324+
"'async let' requires at least one named variable", ())
4325+
NOTE(async_let_without_await,none,
4326+
"reference to async let %0 is 'async'", (DeclName))
4327+
ERROR(async_let_in_illegal_context,none,
4328+
"async let %0 cannot be referenced in "
43324329
"%select{<<ERROR>>|a default argument|a property wrapper initializer|a property initializer|a global variable initializer|an enum case raw value|a catch pattern|a catch guard expression|a defer body}1",
43334330
(DeclName, unsigned))
43344331

@@ -4418,8 +4415,8 @@ ERROR(actor_isolated_from_concurrent_closure,none,
44184415
ERROR(actor_isolated_from_concurrent_function,none,
44194416
"actor-isolated %0 %1 cannot be %select{referenced|mutated|used 'inout'}2 from a concurrent function",
44204417
(DescriptiveDeclKind, DeclName, unsigned))
4421-
ERROR(actor_isolated_from_spawn_let,none,
4422-
"actor-isolated %0 %1 cannot be %select{referenced|mutated|used 'inout'}2 from 'spawn let' initializer",
4418+
ERROR(actor_isolated_from_async_let,none,
4419+
"actor-isolated %0 %1 cannot be %select{referenced|mutated|used 'inout'}2 from 'async let' initializer",
44234420
(DescriptiveDeclKind, DeclName, unsigned))
44244421
ERROR(actor_isolated_keypath_component,none,
44254422
"cannot form key path to actor-isolated %0 %1",

include/swift/Sema/ConstraintSystem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4433,7 +4433,7 @@ class ConstraintSystem {
44334433
/// Given expression represents computed result of the closure.
44344434
Expr *buildAutoClosureExpr(Expr *expr, FunctionType *closureType,
44354435
bool isDefaultWrappedValue = false,
4436-
bool isSpawnLetWrapper = false);
4436+
bool isAsyncLetWrapper = false);
44374437

44384438
/// Builds a type-erased return expression that can be used in dynamic
44394439
/// replacement.

lib/AST/Decl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,9 +1581,9 @@ StaticSpellingKind PatternBindingDecl::getCorrectStaticSpelling() const {
15811581
return getCorrectStaticSpellingForDecl(this);
15821582
}
15831583

1584-
bool PatternBindingDecl::isSpawnLet() const {
1584+
bool PatternBindingDecl::isAsyncLet() const {
15851585
if (auto var = getAnchoringVarDecl(0))
1586-
return var->isSpawnLet();
1586+
return var->isAsyncLet();
15871587

15881588
return false;
15891589
}
@@ -5876,7 +5876,7 @@ bool VarDecl::isMemberwiseInitialized(bool preferDeclaredProperties) const {
58765876
return true;
58775877
}
58785878

5879-
bool VarDecl::isSpawnLet() const {
5879+
bool VarDecl::isAsyncLet() const {
58805880
return getAttrs().hasAttribute<AsyncAttr>() || getAttrs().hasAttribute<SpawnAttr>();
58815881
}
58825882

lib/SILGen/SILGenDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ class LetValueInitialization : public Initialization {
440440
// buffer. DI will make sure it is only assigned to once.
441441
needsTemporaryBuffer = true;
442442
isUninitialized = true;
443-
} else if (vd->isSpawnLet()) {
443+
} else if (vd->isAsyncLet()) {
444444
// If this is an async let, treat it like a let-value without an
445445
// initializer. The initializer runs concurrently in a child task,
446446
// and value will be initialized at the point the variable in the
@@ -1146,7 +1146,7 @@ void SILGenFunction::emitPatternBinding(PatternBindingDecl *PBD,
11461146

11471147
// If this is an async let, create a child task to compute the initializer
11481148
// value.
1149-
if (PBD->isSpawnLet()) {
1149+
if (PBD->isAsyncLet()) {
11501150
// Look through the implicit await (if present), try (if present), and
11511151
// call to reach the autoclosure that computes the value.
11521152
auto *init = PBD->getExecutableInit(idx);

lib/SILGen/SILGenLValue.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2816,7 +2816,7 @@ SILGenFunction::maybeEmitValueOfLocalVarDecl(
28162816
if (It != VarLocs.end()) {
28172817
// If the variable is part of an async let, ensure that the child task
28182818
// has completed first.
2819-
if (var->isSpawnLet() && accessKind != AccessKind::Write) {
2819+
if (var->isAsyncLet() && accessKind != AccessKind::Write) {
28202820
auto patternBinding = var->getParentPatternBinding();
28212821
unsigned index = patternBinding->getPatternEntryIndexForVarDecl(var);
28222822
completeAsyncLetChildTask(patternBinding, index);

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8330,7 +8330,7 @@ static Expr *wrapAsyncLetInitializer(
83308330
ASTContext &ctx = dc->getASTContext();
83318331
Expr *autoclosureExpr = cs.buildAutoClosureExpr(
83328332
initializer, closureType, /*isDefaultWrappedValue=*/false,
8333-
/*isSpawnLetWrapper=*/true);
8333+
/*isAsyncLetWrapper=*/true);
83348334

83358335
// Call the autoclosure so that the AST types line up. SILGen will ignore the
83368336
// actual calls and translate them into a different mechanism.
@@ -8431,7 +8431,7 @@ static Optional<SolutionApplicationTarget> applySolutionToInitialization(
84318431
// For an async let, wrap the initializer appropriately to make it a child
84328432
// task.
84338433
if (auto patternBinding = target.getInitializationPatternBindingDecl()) {
8434-
if (patternBinding->isSpawnLet()) {
8434+
if (patternBinding->isAsyncLet()) {
84358435
resultTarget.setExpr(
84368436
wrapAsyncLetInitializer(
84378437
cs, resultTarget.getAsExpr(), resultTarget.getDeclContext()));

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4960,7 +4960,7 @@ ConstraintSystem::isConversionEphemeral(ConversionRestrictionKind conversion,
49604960
Expr *ConstraintSystem::buildAutoClosureExpr(Expr *expr,
49614961
FunctionType *closureType,
49624962
bool isDefaultWrappedValue,
4963-
bool isSpawnLetWrapper) {
4963+
bool isAsyncLetWrapper) {
49644964
auto &Context = DC->getASTContext();
49654965
bool isInDefaultArgumentContext = false;
49664966
if (auto *init = dyn_cast<Initializer>(DC)) {
@@ -4982,7 +4982,7 @@ Expr *ConstraintSystem::buildAutoClosureExpr(Expr *expr,
49824982

49834983
closure->setParameterList(ParameterList::createEmpty(Context));
49844984

4985-
if (isSpawnLetWrapper)
4985+
if (isAsyncLetWrapper)
49864986
closure->setThunkKind(AutoClosureExpr::Kind::AsyncLet);
49874987

49884988
Expr *result = closure;
@@ -5724,7 +5724,7 @@ ASTNode constraints::findAsyncNode(ClosureExpr *closure) {
57245724
bool walkToDeclPre(Decl *decl) override {
57255725
// Do not walk into function or type declarations.
57265726
if (auto *patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
5727-
if (patternBinding->isSpawnLet())
5727+
if (patternBinding->isAsyncLet())
57285728
AsyncNode = patternBinding;
57295729

57305730
return true;

lib/Sema/TypeCheckAttr.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5506,10 +5506,6 @@ void AttributeChecker::visitGlobalActorAttr(GlobalActorAttr *attr) {
55065506

55075507
void AttributeChecker::visitAsyncAttr(AsyncAttr *attr) {
55085508
if (isa<VarDecl>(D)) {
5509-
D->getASTContext().Diags.diagnose(
5510-
attr->getLocation(), diag::async_let_is_spawn_let)
5511-
.fixItReplace(attr->getRange(), "spawn");
5512-
55135509
visitAsyncOrSpawnAttr(attr);
55145510
}
55155511
}
@@ -5529,7 +5525,7 @@ void AttributeChecker::visitAsyncOrSpawnAttr(DeclAttribute *attr) {
55295525

55305526
// "Async" modifier can only be applied to local declarations.
55315527
if (!patternBinding->getDeclContext()->isLocalContext()) {
5532-
diagnoseAndRemoveAttr(attr, diag::spawn_let_not_local);
5528+
diagnoseAndRemoveAttr(attr, diag::async_let_not_local);
55335529
return;
55345530
}
55355531

@@ -5550,21 +5546,21 @@ void AttributeChecker::visitAsyncOrSpawnAttr(DeclAttribute *attr) {
55505546
// Each entry must bind at least one named variable, so that there is
55515547
// something to "await".
55525548
if (!foundAnyVariable) {
5553-
diagnose(pattern->getLoc(), diag::spawn_let_no_variables);
5549+
diagnose(pattern->getLoc(), diag::async_let_no_variables);
55545550
attr->setInvalid();
55555551
return;
55565552
}
55575553

55585554
// Async can only be used on an "async let".
55595555
if (!isLet && !diagnosedVar) {
5560-
diagnose(patternBinding->getLoc(), diag::spawn_not_let)
5556+
diagnose(patternBinding->getLoc(), diag::async_not_let)
55615557
.fixItReplace(patternBinding->getLoc(), "let");
55625558
diagnosedVar = true;
55635559
}
55645560

55655561
// Each pattern entry must have an initializer expression.
55665562
if (patternBinding->getEqualLoc(index).isInvalid()) {
5567-
diagnose(pattern->getLoc(), diag::spawn_let_not_initialized);
5563+
diagnose(pattern->getLoc(), diag::async_let_not_initialized);
55685564
attr->setInvalid();
55695565
return;
55705566
}

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2039,7 +2039,7 @@ namespace {
20392039
if (auto autoclosure = dyn_cast<AutoClosureExpr>(dc)) {
20402040
switch (autoclosure->getThunkKind()) {
20412041
case AutoClosureExpr::Kind::AsyncLet:
2042-
return diag::actor_isolated_from_spawn_let;
2042+
return diag::actor_isolated_from_async_let;
20432043

20442044
case AutoClosureExpr::Kind::DoubleCurryThunk:
20452045
case AutoClosureExpr::Kind::SingleCurryThunk:

0 commit comments

Comments
 (0)