Skip to content

Commit 520c05b

Browse files
authored
Merge pull request #79508 from xedin/feature-proof-execution-attrs
[Frontend] Rename `NonIsolatedAsyncInheritsIsolationFromContext` feature and add a feature for `@execution`
2 parents 205bfee + dd1be8f commit 520c05b

24 files changed

+165
-47
lines changed

include/swift/AST/DeclAttr.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ DECL_ATTR_FEATURE_REQUIREMENT(ABI, ABIAttribute)
545545
DECL_ATTR(execution, Execution,
546546
OnFunc | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
547547
166)
548+
DECL_ATTR_FEATURE_REQUIREMENT(Execution, ExecutionAttribute)
548549

549550
LAST_DECL_ATTR(Execution)
550551

include/swift/AST/PrintOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ struct PrintOptions {
397397
/// Suppress modify/read accessors.
398398
bool SuppressCoroutineAccessors = false;
399399

400+
/// Suppress the @execution attribute
401+
bool SuppressExecutionAttribute = false;
402+
400403
/// List of attribute kinds that should not be printed.
401404
std::vector<AnyAttrKind> ExcludeAttrList = {
402405
DeclAttrKind::Transparent, DeclAttrKind::Effects,

include/swift/Basic/Features.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,13 @@ SUPPRESSIBLE_EXPERIMENTAL_FEATURE(AddressableTypes, true)
437437
/// Allow the @abi attribute.
438438
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ABIAttribute, true)
439439

440+
/// Allow the @execution attribute. This is also connected to
441+
/// AsyncCallerExecution feature.
442+
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ExecutionAttribute, false)
443+
440444
/// Functions with nonisolated isolation inherit their isolation from the
441445
/// calling context.
442-
EXPERIMENTAL_FEATURE(NonIsolatedAsyncInheritsIsolationFromContext, false)
446+
EXPERIMENTAL_FEATURE(AsyncCallerExecution, false)
443447

444448
/// Allow custom availability domains to be defined and referenced.
445449
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(CustomAvailability, true)

lib/AST/ASTPrinter.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3251,6 +3251,14 @@ suppressingFeatureCustomAvailability(PrintOptions &options,
32513251
action();
32523252
}
32533253

3254+
static void
3255+
suppressingFeatureExecutionAttribute(PrintOptions &options,
3256+
llvm::function_ref<void()> action) {
3257+
llvm::SaveAndRestore<bool> scope1(options.SuppressExecutionAttribute, true);
3258+
ExcludeAttrRAII scope2(options.ExcludeAttrList, DeclAttrKind::Execution);
3259+
action();
3260+
}
3261+
32543262
/// Suppress the printing of a particular feature.
32553263
static void suppressingFeature(PrintOptions &options, Feature feature,
32563264
llvm::function_ref<void()> action) {
@@ -6423,7 +6431,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
64236431
break;
64246432

64256433
case FunctionTypeIsolation::Kind::NonIsolatedCaller:
6426-
Printer << "@execution(caller) ";
6434+
if (!Options.SuppressExecutionAttribute)
6435+
Printer << "@execution(caller) ";
64276436
break;
64286437
}
64296438

lib/AST/Attr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ void IsolatedTypeAttr::printImpl(ASTPrinter &printer,
305305

306306
void ExecutionTypeAttr::printImpl(ASTPrinter &printer,
307307
const PrintOptions &options) const {
308+
if (options.SuppressExecutionAttribute)
309+
return;
310+
308311
printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute);
309312
printer.printAttrName("@execution");
310313
printer << "(";

lib/AST/FeatureSet.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ UNINTERESTING_FEATURE(Volatile)
121121
UNINTERESTING_FEATURE(SuppressedAssociatedTypes)
122122
UNINTERESTING_FEATURE(StructLetDestructuring)
123123
UNINTERESTING_FEATURE(MacrosOnImports)
124-
UNINTERESTING_FEATURE(NonIsolatedAsyncInheritsIsolationFromContext)
124+
UNINTERESTING_FEATURE(AsyncCallerExecution)
125125

126126
static bool usesFeatureNonescapableTypes(Decl *decl) {
127127
auto containsNonEscapable =
@@ -416,6 +416,45 @@ static bool usesFeatureBuiltinEmplaceTypedThrows(Decl *decl) {
416416
return false;
417417
}
418418

419+
static bool usesFeatureExecutionAttribute(Decl *decl) {
420+
if (decl->getAttrs().hasAttribute<ExecutionAttr>())
421+
return true;
422+
423+
auto VD = dyn_cast<ValueDecl>(decl);
424+
if (!VD)
425+
return false;
426+
427+
auto hasExecutionAttr = [](TypeRepr *R) {
428+
if (!R)
429+
return false;
430+
431+
return R->findIf([](TypeRepr *repr) {
432+
if (auto *AT = dyn_cast<AttributedTypeRepr>(repr)) {
433+
return llvm::any_of(AT->getAttrs(), [](TypeOrCustomAttr attr) {
434+
if (auto *TA = attr.dyn_cast<TypeAttribute *>()) {
435+
return isa<ExecutionTypeAttr>(TA);
436+
}
437+
return false;
438+
});
439+
}
440+
return false;
441+
});
442+
};
443+
444+
// Check if any parameters that have `@execution` attribute.
445+
if (auto *PL = getParameterList(VD)) {
446+
for (auto *P : *PL) {
447+
if (hasExecutionAttr(P->getTypeRepr()))
448+
return true;
449+
}
450+
}
451+
452+
if (hasExecutionAttr(VD->getResultTypeRepr()))
453+
return true;
454+
455+
return false;
456+
}
457+
419458
// ----------------------------------------------------------------------------
420459
// MARK: - FeatureSet
421460
// ----------------------------------------------------------------------------

lib/Parse/ParseDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4725,6 +4725,12 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
47254725
}
47264726

47274727
case TypeAttrKind::Execution: {
4728+
if (!Context.LangOpts.hasFeature(Feature::ExecutionAttribute)) {
4729+
diagnose(Tok, diag::requires_experimental_feature, "@execution", false,
4730+
getFeatureName(Feature::ExecutionAttribute));
4731+
return makeParserError();
4732+
}
4733+
47284734
SourceLoc lpLoc = Tok.getLoc(), behaviorLoc, rpLoc;
47294735
if (!consumeIfNotAtStartOfLine(tok::l_paren)) {
47304736
if (!justChecking) {

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,8 +1658,7 @@ class DestructureInputs {
16581658
}
16591659

16601660
// If we are an async function that is unspecified or nonisolated, insert an
1661-
// isolated parameter if NonIsolatedAsyncInheritsIsolationFromContext is
1662-
// enabled.
1661+
// isolated parameter if AsyncCallerExecution is enabled.
16631662
if (IsolationInfo &&
16641663
IsolationInfo->getKind() == ActorIsolation::CallerIsolationInheriting &&
16651664
extInfoBuilder.isAsync()) {

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4759,9 +4759,8 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
47594759
// NOTE: This needs to occur before we handle an explicit nonisolated attr,
47604760
// since if @execution and nonisolated are used together, we want to ensure
47614761
// that @execution takes priority. This ensures that if we import code from a
4762-
// module that was compiled with a different value for
4763-
// NonIsolatedAsyncInheritsIsolationFromContext, we get the semantics of the
4764-
// source module.
4762+
// module that was compiled with a different value for AsyncCallerExecution,
4763+
// we get the semantics of the source module.
47654764
if (concurrentExecutionAttr) {
47664765
switch (concurrentExecutionAttr->getBehavior()) {
47674766
case ExecutionKind::Concurrent:
@@ -4777,7 +4776,7 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
47774776
// If the nonisolated async inherits isolation from context is set, return
47784777
// caller isolation inheriting.
47794778
if (decl->getASTContext().LangOpts.hasFeature(
4780-
Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
4779+
Feature::AsyncCallerExecution)) {
47814780
if (auto *func = dyn_cast<AbstractFunctionDecl>(decl);
47824781
func && func->hasAsync() &&
47834782
func->getModuleContext() == decl->getASTContext().MainModule) {
@@ -5612,8 +5611,7 @@ computeDefaultInferredActorIsolation(ValueDecl *value) {
56125611
}
56135612

56145613
// If we have an async function... by default we inherit isolation.
5615-
if (ctx.LangOpts.hasFeature(
5616-
Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
5614+
if (ctx.LangOpts.hasFeature(Feature::AsyncCallerExecution)) {
56175615
if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
56185616
func && func->hasAsync() &&
56195617
func->getModuleContext() == ctx.MainModule) {
@@ -5702,8 +5700,8 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
57025700
// did not have an ExecutionKind::Caller attached to it.
57035701
//
57045702
// DISCUSSION: This occurs when we have a value decl that is explicitly marked
5705-
// as nonisolated but since NonIsolatedAsyncInheritsIsolationFromContext is
5706-
// enabled, we return CallerIsolationInheriting.
5703+
// as nonisolated but since AsyncCallerExecution is enabled, we return
5704+
// CallerIsolationInheriting.
57075705
if (isolationFromAttr && isolationFromAttr->getKind() ==
57085706
ActorIsolation::CallerIsolationInheriting &&
57095707
!value->getAttrs().hasAttribute<ExecutionAttr>()) {
@@ -6001,7 +5999,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
60015999

60026000
if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
60036001
ctx.LangOpts.hasFeature(
6004-
Feature::NonIsolatedAsyncInheritsIsolationFromContext) &&
6002+
Feature::AsyncCallerExecution) &&
60056003
func && func->hasAsync() &&
60066004
func->getModuleContext() == ctx.MainModule &&
60076005
isolation.isNonisolated()) {

test/ASTGen/attrs.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22

33
// RUN: %target-swift-frontend-dump-parse \
44
// RUN: -enable-experimental-feature ABIAttribute \
5+
// RUN: -enable-experimental-feature ExecutionAttribute \
56
// RUN: -enable-experimental-feature Extern \
67
// RUN: -enable-experimental-feature LifetimeDependence \
7-
// RUN: -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext \
88
// RUN: -enable-experimental-feature SymbolLinkageMarkers \
99
// RUN: -enable-experimental-move-only \
1010
// RUN: -enable-experimental-feature ParserASTGen \
1111
// RUN: | %sanitize-address > %t/astgen.ast
1212

1313
// RUN: %target-swift-frontend-dump-parse \
1414
// RUN: -enable-experimental-feature ABIAttribute \
15+
// RUN: -enable-experimental-feature ExecutionAttribute \
1516
// RUN: -enable-experimental-feature Extern \
1617
// RUN: -enable-experimental-feature LifetimeDependence \
17-
// RUN: -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext \
1818
// RUN: -enable-experimental-feature SymbolLinkageMarkers \
1919
// RUN: -enable-experimental-move-only \
2020
// RUN: | %sanitize-address > %t/cpp-parser.ast
@@ -25,19 +25,19 @@
2525
// RUN: -module-abi-name ASTGen \
2626
// RUN: -enable-experimental-feature ParserASTGen \
2727
// RUN: -enable-experimental-feature ABIAttribute \
28+
// RUN: -enable-experimental-feature ExecutionAttribute \
2829
// RUN: -enable-experimental-feature Extern \
2930
// RUN: -enable-experimental-feature LifetimeDependence \
30-
// RUN: -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext \
3131
// RUN: -enable-experimental-feature SymbolLinkageMarkers \
3232
// RUN: -enable-experimental-move-only
3333

3434
// REQUIRES: executable_test
3535
// REQUIRES: swift_swift_parser
3636
// REQUIRES: swift_feature_ParserASTGen
3737
// REQUIRES: swift_feature_ABIAttribute
38+
// REQUIRES: swift_feature_ExecutionAttribute
3839
// REQUIRES: swift_feature_Extern
3940
// REQUIRES: swift_feature_LifetimeDependence
40-
// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
4141
// REQUIRES: swift_feature_SymbolLinkageMarkers
4242

4343
// rdar://116686158

test/Concurrency/Runtime/nonisolated_inherits_isolation.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
// RUN: %target-run-simple-swift( -swift-version 6 -g %import-libdispatch -import-objc-header %S/Inputs/RunOnMainActor.h -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext )
1+
// RUN: %target-run-simple-swift( -swift-version 6 -g %import-libdispatch -import-objc-header %S/Inputs/RunOnMainActor.h -enable-experimental-feature ExecutionAttribute -enable-experimental-feature AsyncCallerExecution )
22

33
// REQUIRES: executable_test
44
// REQUIRES: concurrency
55
// REQUIRES: concurrency_runtime
66
// REQUIRES: libdispatch
77
// REQUIRES: asserts
88

9-
// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
9+
// REQUIRES: swift_feature_ExecutionAttribute
10+
// REQUIRES: swift_feature_AsyncCallerExecution
1011

1112
// UNSUPPORTED: freestanding
1213

test/Concurrency/attr_execution.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// RUN: %target-swift-emit-silgen -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext %s | %FileCheck %s
1+
// RUN: %target-swift-emit-silgen -enable-experimental-feature ExecutionAttribute -enable-experimental-feature AsyncCallerExecution %s | %FileCheck %s
22

33
// REQUIRES: asserts
4-
// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
4+
// REQUIRES: swift_feature_ExecutionAttribute
5+
// REQUIRES: swift_feature_AsyncCallerExecution
56

67

78
// CHECK-LABEL: // concurrentTest()

test/Concurrency/attr_execution_conversions.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// RUN: %target-typecheck-verify-swift -target %target-swift-5.1-abi-triple
1+
// RUN: %target-typecheck-verify-swift -target %target-swift-5.1-abi-triple -enable-experimental-feature ExecutionAttribute
22

3+
// REQUIRES: asserts
34
// REQUIRES: concurrency
5+
// REQUIRES: swift_feature_ExecutionAttribute
46

57
@execution(concurrent)
68
func concurrentTest() async {

test/Concurrency/nonisolated_inherits_isolation.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
// RUN: %target-swift-frontend %s -swift-version 6 -verify -verify-additional-prefix disabled- -c
2-
// RUN: %target-swift-frontend %s -swift-version 6 -verify -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext -verify-additional-prefix enable- -c -verify-additional-prefix enabled-
2+
// RUN: %target-swift-frontend %s -swift-version 6 -verify -enable-experimental-feature AsyncCallerExecution -verify-additional-prefix enable- -c -verify-additional-prefix enabled-
33

44
// REQUIRES: asserts
55
// REQUIRES: concurrency
6-
// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
6+
// REQUIRES: swift_feature_AsyncCallerExecution
77

8-
// This test checks and validates that when
9-
// NonIsolatedAsyncInheritsIsolationFromContext is enabled, we emit the
8+
// This test checks and validates that when AsyncCallerExecution is enabled, we emit the
109
// appropriate diagnostics. It also runs with the mode off so we can validate
1110
// and compare locally against the normal errors.
1211

test/Concurrency/nonisolated_inherits_isolation_sema.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
// RUN: %target-typecheck-verify-swift -swift-version 6 -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext -parse-as-library
1+
// RUN: %target-typecheck-verify-swift -swift-version 6 -enable-experimental-feature AsyncCallerExecution -parse-as-library
22

33
// REQUIRES: asserts
44
// REQUIRES: concurrency
5-
// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
5+
// REQUIRES: swift_feature_AsyncCallerExecution
66

77
class NonSendable {} // expected-note {{}}
88

test/IDE/complete_decl_attribute.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ struct _S {
251251
// ON_METHOD-DAG: Keyword/None: preconcurrency[#Func Attribute#]; name=preconcurrency
252252
// ON_METHOD-DAG: Keyword/None: backDeployed[#Func Attribute#]; name=backDeployed
253253
// ON_METHOD-DAG: Keyword/None: lifetime[#Func Attribute#]; name=lifetime
254-
// ON_METHOD-DAG: Keyword/None: execution[#Func Attribute#]; name=execution
255254
// ON_METHOD-NOT: Keyword
256255
// ON_METHOD-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
257256
// ON_METHOD-DAG: Decl[Struct]/CurrModule: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
@@ -326,7 +325,6 @@ struct _S {
326325
// ON_MEMBER_LAST-DAG: Keyword/None: freestanding[#Declaration Attribute#]; name=freestanding
327326
// ON_MEMBER_LAST-DAG: Keyword/None: storageRestrictions[#Declaration Attribute#]; name=storageRestrictions
328327
// ON_MEMBER_LAST-DAG: Keyword/None: lifetime[#Declaration Attribute#]; name=lifetime
329-
// ON_MEMBER_LAST-DAG: Keyword/None: execution[#Declaration Attribute#]; name=execution
330328
// ON_MEMBER_LAST-NOT: Keyword
331329
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
332330
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
@@ -399,7 +397,6 @@ func dummy2() {}
399397
// KEYWORD_LAST-DAG: Keyword/None: attached[#Declaration Attribute#]; name=attached
400398
// KEYWORD_LAST-DAG: Keyword/None: storageRestrictions[#Declaration Attribute#]; name=storageRestrictions
401399
// KEYWORD_LAST-DAG: Keyword/None: lifetime[#Declaration Attribute#]; name=lifetime
402-
// KEYWORD_LAST-DAG: Keyword/None: execution[#Declaration Attribute#]; name=execution
403400
// KEYWORD_LAST-NOT: Keyword
404401
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
405402
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#Property Wrapper#]; name=MyGenericPropertyWrapper

0 commit comments

Comments
 (0)