Skip to content

Commit 8598ec6

Browse files
committed
[AST/ASTGen] Introduce @concurrent attribute to replace @execution(concurrent) spelling
1 parent cd97415 commit 8598ec6

File tree

10 files changed

+61
-9
lines changed

10 files changed

+61
-9
lines changed

include/swift/AST/DeclAttr.def

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,13 @@ SIMPLE_DECL_ATTR(constInitialized, ConstInitialized,
879879
168)
880880
DECL_ATTR_FEATURE_REQUIREMENT(ConstInitialized, CompileTimeValues)
881881

882-
LAST_DECL_ATTR(ConstInitialized)
882+
SIMPLE_DECL_ATTR(concurrent, Concurrent,
883+
OnFunc | OnConstructor | OnSubscript | OnVar,
884+
ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove | UnconstrainedInABIAttr,
885+
170)
886+
DECL_ATTR_FEATURE_REQUIREMENT(Concurrent, ExecutionAttribute)
887+
888+
LAST_DECL_ATTR(Concurrent)
883889

884890
#undef DECL_ATTR_ALIAS
885891
#undef CONTEXTUAL_DECL_ATTR_ALIAS

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4925,6 +4925,7 @@ class PrintAttribute : public AttributeVisitor<PrintAttribute, void, Label>,
49254925
TRIVIAL_ATTR_PRINTER(Used, used)
49264926
TRIVIAL_ATTR_PRINTER(WarnUnqualifiedAccess, warn_unqualified_access)
49274927
TRIVIAL_ATTR_PRINTER(WeakLinked, weak_linked)
4928+
TRIVIAL_ATTR_PRINTER(Concurrent, concurrent)
49284929

49294930
#undef TRIVIAL_ATTR_PRINTER
49304931

lib/AST/Decl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8757,6 +8757,9 @@ void VarDecl::emitLetToVarNoteIfSimple(DeclContext *UseDC) const {
87578757

87588758
std::optional<ExecutionKind>
87598759
AbstractFunctionDecl::getExecutionBehavior() const {
8760+
if (getAttrs().hasAttribute<ConcurrentAttr>())
8761+
return ExecutionKind::Concurrent;
8762+
87608763
auto *attr = getAttrs().getAttribute<ExecutionAttr>();
87618764
if (!attr)
87628765
return {};

lib/AST/FeatureSet.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,9 @@ static bool usesFeatureExecutionAttribute(Decl *decl) {
511511
if (decl->getAttrs().hasAttribute<ExecutionAttr>())
512512
return true;
513513

514+
if (decl->getAttrs().hasAttribute<ConcurrentAttr>())
515+
return true;
516+
514517
auto hasExecutionAttr = [](TypeRepr *R) {
515518
if (!R)
516519
return false;

lib/ASTGen/Sources/ASTGen/DeclAttrs.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ extension ASTGenVisitor {
197197
return handle(self.generateSimpleDeclAttr(attribute: node, kind: .atReasync))
198198
case .rethrows:
199199
return handle(self.generateSimpleDeclAttr(attribute: node, kind: .atRethrows))
200+
case .concurrent:
201+
return handle(self.generateSimpleDeclAttr(attribute: node, kind: .concurrent))
200202
case .none where attrName == "_unavailableInEmbedded":
201203
return handle(self.generateUnavailableInEmbeddedAttr(attribute: node)?.asDeclAttribute)
202204

lib/Sema/ConstraintSystem.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,8 +1414,10 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
14141414
bool async = expr->getAsyncLoc().isValid();
14151415
bool sendable = expr->getAttrs().hasAttribute<SendableAttr>();
14161416

1417-
// `@execution(...)` attribute is only valid on asynchronous function types.
1418-
if (expr->getAttrs().hasAttribute<ExecutionAttr>()) {
1417+
// `@execution(...)` and `@concurrent` attributes are only
1418+
// valid on asynchronous function types.
1419+
if (expr->getAttrs().hasAttribute<ExecutionAttr>() ||
1420+
expr->getAttrs().hasAttribute<ConcurrentAttr>()) {
14191421
async = true;
14201422
}
14211423

lib/Sema/TypeCheckAttr.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
198198
TypeChecker::checkDeclABIAttribute(D, attr);
199199
}
200200

201-
void visitExecutionAttr(ExecutionAttr *attr) {
201+
void checkExecutionBehaviorAttribute(DeclAttribute *attr) {
202202
auto *const decl = cast<ValueDecl>(D);
203203

204204
auto *const storage = dyn_cast<AbstractStorageDecl>(decl);
@@ -243,6 +243,22 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
243243
}
244244
}
245245

246+
void visitExecutionAttr(ExecutionAttr *attr) {
247+
checkExecutionBehaviorAttribute(attr);
248+
249+
if (auto *concurrentAttr = D->getAttrs().getAttribute<ConcurrentAttr>())
250+
diagnoseAndRemoveAttr(attr, diag::actor_isolation_multiple_attr_2, D,
251+
attr, concurrentAttr);
252+
}
253+
254+
void visitConcurrentAttr(ConcurrentAttr *attr) {
255+
checkExecutionBehaviorAttribute(attr);
256+
257+
if (auto *executionAttr = D->getAttrs().getAttribute<ExecutionAttr>())
258+
diagnoseAndRemoveAttr(attr, diag::actor_isolation_multiple_attr_2, D,
259+
attr, executionAttr);
260+
}
261+
246262
void visitAlignmentAttr(AlignmentAttr *attr) {
247263
// Alignment must be a power of two.
248264
auto value = attr->getValue();
@@ -4317,6 +4333,7 @@ static void checkGlobalActorAttr(
43174333
auto isolatedAttr = decl->getAttrs().getAttribute<IsolatedAttr>();
43184334
auto nonisolatedAttr = decl->getAttrs().getAttribute<NonisolatedAttr>();
43194335
auto executionAttr = decl->getAttrs().getAttribute<ExecutionAttr>();
4336+
auto concurrentAttr = decl->getAttrs().getAttribute<ConcurrentAttr>();
43204337

43214338
llvm::SmallVector<const DeclAttribute *, 2> attributes;
43224339

@@ -4331,7 +4348,9 @@ static void checkGlobalActorAttr(
43314348
if (executionAttr) {
43324349
attributes.push_back(executionAttr);
43334350
}
4334-
4351+
if (concurrentAttr) {
4352+
attributes.push_back(concurrentAttr);
4353+
}
43354354
if (attributes.size() == 1)
43364355
return;
43374356

@@ -8152,13 +8171,13 @@ class ClosureAttributeChecker
81528171
// Nothing else to check.
81538172
}
81548173

8155-
void visitExecutionAttr(ExecutionAttr *attr) {
8174+
void checkExecutionBehaviorAttribute(DeclAttribute *attr) {
81568175
if (!ctx.LangOpts.hasFeature(Feature::ExecutionAttribute)) {
81578176
visitDeclAttribute(attr);
81588177
return;
81598178
}
81608179

8161-
// `@execution(...)` implies `async`.
8180+
// execution behavior attribute implies `async`.
81628181
if (closure->hasExplicitResultType() &&
81638182
closure->getAsyncLoc().isInvalid()) {
81648183
ctx.Diags
@@ -8191,6 +8210,14 @@ class ClosureAttributeChecker
81918210
}
81928211
}
81938212

8213+
void visitExecutionAttr(ExecutionAttr *attr) {
8214+
checkExecutionBehaviorAttribute(attr);
8215+
}
8216+
8217+
void visitConcurrentAttr(ConcurrentAttr *attr) {
8218+
checkExecutionBehaviorAttribute(attr);
8219+
}
8220+
81948221
void visitNonisolatedAttr(NonisolatedAttr *attr) {
81958222
if (attr->isUnsafe() ||
81968223
!ctx.LangOpts.hasFeature(Feature::ClosureIsolation)) {

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4903,6 +4903,7 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
49034903
auto nonisolatedAttr = decl->getAttrs().getAttribute<NonisolatedAttr>();
49044904
auto globalActorAttr = decl->getGlobalActorAttr();
49054905
auto concurrentExecutionAttr = decl->getAttrs().getAttribute<ExecutionAttr>();
4906+
auto concurrentAttr = decl->getAttrs().getAttribute<ConcurrentAttr>();
49064907

49074908
// Remove implicit attributes if we only care about explicit ones.
49084909
if (onlyExplicit) {
@@ -4914,11 +4915,14 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
49144915
globalActorAttr = std::nullopt;
49154916
if (concurrentExecutionAttr && concurrentExecutionAttr->isImplicit())
49164917
concurrentExecutionAttr = nullptr;
4918+
if (concurrentAttr && concurrentAttr->isImplicit())
4919+
concurrentAttr = nullptr;
49174920
}
49184921

49194922
unsigned numIsolationAttrs =
49204923
(isolatedAttr ? 1 : 0) + (nonisolatedAttr ? 1 : 0) +
4921-
(globalActorAttr ? 1 : 0) + (concurrentExecutionAttr ? 1 : 0);
4924+
(globalActorAttr ? 1 : 0) + (concurrentExecutionAttr ? 1 : 0) +
4925+
(concurrentAttr ? 1 : 0);
49224926
if (numIsolationAttrs == 0) {
49234927
if (isa<DestructorDecl>(decl) && !decl->isImplicit()) {
49244928
return ActorIsolation::forNonisolated(false);
@@ -4943,6 +4947,9 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
49434947
}
49444948
}
49454949

4950+
if (concurrentAttr)
4951+
return ActorIsolation::forNonisolated(/*is unsafe*/ false);
4952+
49464953
// If the declaration is explicitly marked 'nonisolated', report it as
49474954
// independent.
49484955
if (nonisolatedAttr) {

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,7 @@ namespace {
15931593
UNINTERESTING_ATTR(Borrowed)
15941594
UNINTERESTING_ATTR(Borrowing)
15951595
UNINTERESTING_ATTR(CDecl)
1596+
UNINTERESTING_ATTR(Concurrent)
15961597
UNINTERESTING_ATTR(Consuming)
15971598
UNINTERESTING_ATTR(Documentation)
15981599
UNINTERESTING_ATTR(Dynamic)

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 934; // custom AvailabilityDomains
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 935; // @concurrent attribute
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///

0 commit comments

Comments
 (0)