Skip to content

[Frontend] Rename NonIsolatedAsyncInheritsIsolationFromContext feature and add a feature for @execution #79508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/AST/DeclAttr.def
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ DECL_ATTR_FEATURE_REQUIREMENT(ABI, ABIAttribute)
DECL_ATTR(execution, Execution,
OnFunc | ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
166)
DECL_ATTR_FEATURE_REQUIREMENT(Execution, ExecutionAttribute)

LAST_DECL_ATTR(Execution)

Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/PrintOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ struct PrintOptions {
/// Suppress modify/read accessors.
bool SuppressCoroutineAccessors = false;

/// Suppress the @execution attribute
bool SuppressExecutionAttribute = false;

/// List of attribute kinds that should not be printed.
std::vector<AnyAttrKind> ExcludeAttrList = {
DeclAttrKind::Transparent, DeclAttrKind::Effects,
Expand Down
6 changes: 5 additions & 1 deletion include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,13 @@ SUPPRESSIBLE_EXPERIMENTAL_FEATURE(AddressableTypes, true)
/// Allow the @abi attribute.
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ABIAttribute, true)

/// Allow the @execution attribute. This is also connected to
/// AsyncCallerExecution feature.
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ExecutionAttribute, false)

/// Functions with nonisolated isolation inherit their isolation from the
/// calling context.
EXPERIMENTAL_FEATURE(NonIsolatedAsyncInheritsIsolationFromContext, false)
EXPERIMENTAL_FEATURE(AsyncCallerExecution, false)

/// Allow custom availability domains to be defined and referenced.
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(CustomAvailability, true)
Expand Down
11 changes: 10 additions & 1 deletion lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3251,6 +3251,14 @@ suppressingFeatureCustomAvailability(PrintOptions &options,
action();
}

static void
suppressingFeatureExecutionAttribute(PrintOptions &options,
llvm::function_ref<void()> action) {
llvm::SaveAndRestore<bool> scope1(options.SuppressExecutionAttribute, true);
ExcludeAttrRAII scope2(options.ExcludeAttrList, DeclAttrKind::Execution);
action();
}

/// Suppress the printing of a particular feature.
static void suppressingFeature(PrintOptions &options, Feature feature,
llvm::function_ref<void()> action) {
Expand Down Expand Up @@ -6423,7 +6431,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
break;

case FunctionTypeIsolation::Kind::NonIsolatedCaller:
Printer << "@execution(caller) ";
if (!Options.SuppressExecutionAttribute)
Printer << "@execution(caller) ";
break;
}

Expand Down
3 changes: 3 additions & 0 deletions lib/AST/Attr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ void IsolatedTypeAttr::printImpl(ASTPrinter &printer,

void ExecutionTypeAttr::printImpl(ASTPrinter &printer,
const PrintOptions &options) const {
if (options.SuppressExecutionAttribute)
return;

printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute);
printer.printAttrName("@execution");
printer << "(";
Expand Down
41 changes: 40 additions & 1 deletion lib/AST/FeatureSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ UNINTERESTING_FEATURE(Volatile)
UNINTERESTING_FEATURE(SuppressedAssociatedTypes)
UNINTERESTING_FEATURE(StructLetDestructuring)
UNINTERESTING_FEATURE(MacrosOnImports)
UNINTERESTING_FEATURE(NonIsolatedAsyncInheritsIsolationFromContext)
UNINTERESTING_FEATURE(AsyncCallerExecution)

static bool usesFeatureNonescapableTypes(Decl *decl) {
auto containsNonEscapable =
Expand Down Expand Up @@ -416,6 +416,45 @@ static bool usesFeatureBuiltinEmplaceTypedThrows(Decl *decl) {
return false;
}

static bool usesFeatureExecutionAttribute(Decl *decl) {
if (decl->getAttrs().hasAttribute<ExecutionAttr>())
return true;

auto VD = dyn_cast<ValueDecl>(decl);
if (!VD)
return false;

auto hasExecutionAttr = [](TypeRepr *R) {
if (!R)
return false;

return R->findIf([](TypeRepr *repr) {
if (auto *AT = dyn_cast<AttributedTypeRepr>(repr)) {
return llvm::any_of(AT->getAttrs(), [](TypeOrCustomAttr attr) {
if (auto *TA = attr.dyn_cast<TypeAttribute *>()) {
return isa<ExecutionTypeAttr>(TA);
}
return false;
});
}
return false;
});
};

// Check if any parameters that have `@execution` attribute.
if (auto *PL = getParameterList(VD)) {
for (auto *P : *PL) {
if (hasExecutionAttr(P->getTypeRepr()))
return true;
}
}

if (hasExecutionAttr(VD->getResultTypeRepr()))
return true;

return false;
}

// ----------------------------------------------------------------------------
// MARK: - FeatureSet
// ----------------------------------------------------------------------------
Expand Down
6 changes: 6 additions & 0 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4725,6 +4725,12 @@ ParserStatus Parser::parseTypeAttribute(TypeOrCustomAttr &result,
}

case TypeAttrKind::Execution: {
if (!Context.LangOpts.hasFeature(Feature::ExecutionAttribute)) {
diagnose(Tok, diag::requires_experimental_feature, "@execution", false,
getFeatureName(Feature::ExecutionAttribute));
return makeParserError();
}

SourceLoc lpLoc = Tok.getLoc(), behaviorLoc, rpLoc;
if (!consumeIfNotAtStartOfLine(tok::l_paren)) {
if (!justChecking) {
Expand Down
3 changes: 1 addition & 2 deletions lib/SIL/IR/SILFunctionType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1658,8 +1658,7 @@ class DestructureInputs {
}

// If we are an async function that is unspecified or nonisolated, insert an
// isolated parameter if NonIsolatedAsyncInheritsIsolationFromContext is
// enabled.
// isolated parameter if AsyncCallerExecution is enabled.
if (IsolationInfo &&
IsolationInfo->getKind() == ActorIsolation::CallerIsolationInheriting &&
extInfoBuilder.isAsync()) {
Expand Down
16 changes: 7 additions & 9 deletions lib/Sema/TypeCheckConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4759,9 +4759,8 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
// NOTE: This needs to occur before we handle an explicit nonisolated attr,
// since if @execution and nonisolated are used together, we want to ensure
// that @execution takes priority. This ensures that if we import code from a
// module that was compiled with a different value for
// NonIsolatedAsyncInheritsIsolationFromContext, we get the semantics of the
// source module.
// module that was compiled with a different value for AsyncCallerExecution,
// we get the semantics of the source module.
if (concurrentExecutionAttr) {
switch (concurrentExecutionAttr->getBehavior()) {
case ExecutionKind::Concurrent:
Expand All @@ -4777,7 +4776,7 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
// If the nonisolated async inherits isolation from context is set, return
// caller isolation inheriting.
if (decl->getASTContext().LangOpts.hasFeature(
Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
Feature::AsyncCallerExecution)) {
if (auto *func = dyn_cast<AbstractFunctionDecl>(decl);
func && func->hasAsync() &&
func->getModuleContext() == decl->getASTContext().MainModule) {
Expand Down Expand Up @@ -5612,8 +5611,7 @@ computeDefaultInferredActorIsolation(ValueDecl *value) {
}

// If we have an async function... by default we inherit isolation.
if (ctx.LangOpts.hasFeature(
Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
if (ctx.LangOpts.hasFeature(Feature::AsyncCallerExecution)) {
if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
func && func->hasAsync() &&
func->getModuleContext() == ctx.MainModule) {
Expand Down Expand Up @@ -5702,8 +5700,8 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
// did not have an ExecutionKind::Caller attached to it.
//
// DISCUSSION: This occurs when we have a value decl that is explicitly marked
// as nonisolated but since NonIsolatedAsyncInheritsIsolationFromContext is
// enabled, we return CallerIsolationInheriting.
// as nonisolated but since AsyncCallerExecution is enabled, we return
// CallerIsolationInheriting.
if (isolationFromAttr && isolationFromAttr->getKind() ==
ActorIsolation::CallerIsolationInheriting &&
!value->getAttrs().hasAttribute<ExecutionAttr>()) {
Expand Down Expand Up @@ -6001,7 +5999,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate(

if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
ctx.LangOpts.hasFeature(
Feature::NonIsolatedAsyncInheritsIsolationFromContext) &&
Feature::AsyncCallerExecution) &&
func && func->hasAsync() &&
func->getModuleContext() == ctx.MainModule &&
isolation.isNonisolated()) {
Expand Down
8 changes: 4 additions & 4 deletions test/ASTGen/attrs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

// RUN: %target-swift-frontend-dump-parse \
// RUN: -enable-experimental-feature ABIAttribute \
// RUN: -enable-experimental-feature ExecutionAttribute \
// RUN: -enable-experimental-feature Extern \
// RUN: -enable-experimental-feature LifetimeDependence \
// RUN: -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext \
// RUN: -enable-experimental-feature SymbolLinkageMarkers \
// RUN: -enable-experimental-move-only \
// RUN: -enable-experimental-feature ParserASTGen \
// RUN: | %sanitize-address > %t/astgen.ast

// RUN: %target-swift-frontend-dump-parse \
// RUN: -enable-experimental-feature ABIAttribute \
// RUN: -enable-experimental-feature ExecutionAttribute \
// RUN: -enable-experimental-feature Extern \
// RUN: -enable-experimental-feature LifetimeDependence \
// RUN: -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext \
// RUN: -enable-experimental-feature SymbolLinkageMarkers \
// RUN: -enable-experimental-move-only \
// RUN: | %sanitize-address > %t/cpp-parser.ast
Expand All @@ -25,19 +25,19 @@
// RUN: -module-abi-name ASTGen \
// RUN: -enable-experimental-feature ParserASTGen \
// RUN: -enable-experimental-feature ABIAttribute \
// RUN: -enable-experimental-feature ExecutionAttribute \
// RUN: -enable-experimental-feature Extern \
// RUN: -enable-experimental-feature LifetimeDependence \
// RUN: -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext \
// RUN: -enable-experimental-feature SymbolLinkageMarkers \
// RUN: -enable-experimental-move-only

// REQUIRES: executable_test
// REQUIRES: swift_swift_parser
// REQUIRES: swift_feature_ParserASTGen
// REQUIRES: swift_feature_ABIAttribute
// REQUIRES: swift_feature_ExecutionAttribute
// REQUIRES: swift_feature_Extern
// REQUIRES: swift_feature_LifetimeDependence
// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
// REQUIRES: swift_feature_SymbolLinkageMarkers

// rdar://116686158
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// RUN: %target-run-simple-swift( -swift-version 6 -g %import-libdispatch -import-objc-header %S/Inputs/RunOnMainActor.h -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext )
// 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 )

// REQUIRES: executable_test
// REQUIRES: concurrency
// REQUIRES: concurrency_runtime
// REQUIRES: libdispatch
// REQUIRES: asserts

// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
// REQUIRES: swift_feature_ExecutionAttribute
// REQUIRES: swift_feature_AsyncCallerExecution

// UNSUPPORTED: freestanding

Expand Down
5 changes: 3 additions & 2 deletions test/Concurrency/attr_execution.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// RUN: %target-swift-emit-silgen -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext %s | %FileCheck %s
// RUN: %target-swift-emit-silgen -enable-experimental-feature ExecutionAttribute -enable-experimental-feature AsyncCallerExecution %s | %FileCheck %s

// REQUIRES: asserts
// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
// REQUIRES: swift_feature_ExecutionAttribute
// REQUIRES: swift_feature_AsyncCallerExecution


// CHECK-LABEL: // concurrentTest()
Expand Down
4 changes: 3 additions & 1 deletion test/Concurrency/attr_execution_conversions.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// RUN: %target-typecheck-verify-swift -target %target-swift-5.1-abi-triple
// RUN: %target-typecheck-verify-swift -target %target-swift-5.1-abi-triple -enable-experimental-feature ExecutionAttribute

// REQUIRES: asserts
// REQUIRES: concurrency
// REQUIRES: swift_feature_ExecutionAttribute

@execution(concurrent)
func concurrentTest() async {
Expand Down
7 changes: 3 additions & 4 deletions test/Concurrency/nonisolated_inherits_isolation.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// RUN: %target-swift-frontend %s -swift-version 6 -verify -verify-additional-prefix disabled- -c
// RUN: %target-swift-frontend %s -swift-version 6 -verify -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext -verify-additional-prefix enable- -c -verify-additional-prefix enabled-
// RUN: %target-swift-frontend %s -swift-version 6 -verify -enable-experimental-feature AsyncCallerExecution -verify-additional-prefix enable- -c -verify-additional-prefix enabled-

// REQUIRES: asserts
// REQUIRES: concurrency
// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
// REQUIRES: swift_feature_AsyncCallerExecution

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

Expand Down
4 changes: 2 additions & 2 deletions test/Concurrency/nonisolated_inherits_isolation_sema.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// RUN: %target-typecheck-verify-swift -swift-version 6 -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext -parse-as-library
// RUN: %target-typecheck-verify-swift -swift-version 6 -enable-experimental-feature AsyncCallerExecution -parse-as-library

// REQUIRES: asserts
// REQUIRES: concurrency
// REQUIRES: swift_feature_NonIsolatedAsyncInheritsIsolationFromContext
// REQUIRES: swift_feature_AsyncCallerExecution

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

Expand Down
3 changes: 0 additions & 3 deletions test/IDE/complete_decl_attribute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ struct _S {
// ON_METHOD-DAG: Keyword/None: preconcurrency[#Func Attribute#]; name=preconcurrency
// ON_METHOD-DAG: Keyword/None: backDeployed[#Func Attribute#]; name=backDeployed
// ON_METHOD-DAG: Keyword/None: lifetime[#Func Attribute#]; name=lifetime
// ON_METHOD-DAG: Keyword/None: execution[#Func Attribute#]; name=execution
// ON_METHOD-NOT: Keyword
// ON_METHOD-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
// ON_METHOD-DAG: Decl[Struct]/CurrModule: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
Expand Down Expand Up @@ -326,7 +325,6 @@ struct _S {
// ON_MEMBER_LAST-DAG: Keyword/None: freestanding[#Declaration Attribute#]; name=freestanding
// ON_MEMBER_LAST-DAG: Keyword/None: storageRestrictions[#Declaration Attribute#]; name=storageRestrictions
// ON_MEMBER_LAST-DAG: Keyword/None: lifetime[#Declaration Attribute#]; name=lifetime
// ON_MEMBER_LAST-DAG: Keyword/None: execution[#Declaration Attribute#]; name=execution
// ON_MEMBER_LAST-NOT: Keyword
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
Expand Down Expand Up @@ -399,7 +397,6 @@ func dummy2() {}
// KEYWORD_LAST-DAG: Keyword/None: attached[#Declaration Attribute#]; name=attached
// KEYWORD_LAST-DAG: Keyword/None: storageRestrictions[#Declaration Attribute#]; name=storageRestrictions
// KEYWORD_LAST-DAG: Keyword/None: lifetime[#Declaration Attribute#]; name=lifetime
// KEYWORD_LAST-DAG: Keyword/None: execution[#Declaration Attribute#]; name=execution
// KEYWORD_LAST-NOT: Keyword
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#Property Wrapper#]; name=MyGenericPropertyWrapper
Expand Down
Loading