Skip to content

Commit

Permalink
Banish @asyncHandler to a hidden flag.
Browse files Browse the repository at this point in the history
We don't want @asyncHandler to be part of the concurrency model, so put
it behind a different flag.
  • Loading branch information
DougGregor committed Mar 25, 2021
1 parent 6207dd8 commit c76dac7
Show file tree
Hide file tree
Showing 24 changed files with 40 additions and 20 deletions.
2 changes: 2 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -4314,6 +4314,8 @@ ERROR(asynchandler_noescape_closure_parameter,none,
ERROR(asynchandler_mutating,none,
"'@asyncHandler' function cannot be 'mutating'",
())
ERROR(asynchandler_removed,none,
"'@asyncHandler' has been removed from the language", ())

ERROR(objc_ambiguous_async_convention,none,
"%0 overrides or implements protocol requirements for Objective-C "
Expand Down
3 changes: 3 additions & 0 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ namespace swift {
/// Enable experimental concurrency model.
bool EnableExperimentalConcurrency = false;

/// Enable experimental asyncHandler support.
bool EnableExperimentalAsyncHandler = false;

/// Enable experimental flow-sensitive concurrent captures.
bool EnableExperimentalFlowSensitiveConcurrentCaptures = false;

Expand Down
4 changes: 4 additions & 0 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ def enable_experimental_concurrency :
Flag<["-"], "enable-experimental-concurrency">,
HelpText<"Enable experimental concurrency model">;

def enable_experimental_async_handler :
Flag<["-"], "enable-experimental-async-handler">,
HelpText<"Enable experimental @asyncHandler feature">;

def enable_experimental_flow_sensitive_concurrent_captures :
Flag<["-"], "enable-experimental-flow-sensitive-concurrent-captures">,
HelpText<"Enable flow-sensitive concurrent captures">;
Expand Down
2 changes: 2 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Args.hasFlag(OPT_enable_infer_public_concurrent_value,
OPT_disable_infer_public_concurrent_value,
false);
Opts.EnableExperimentalAsyncHandler |=
Args.hasArg(OPT_enable_experimental_async_handler);
Opts.EnableExperimentalFlowSensitiveConcurrentCaptures |=
Args.hasArg(OPT_enable_experimental_flow_sensitive_concurrent_captures);

Expand Down
5 changes: 5 additions & 0 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5389,6 +5389,11 @@ void AttributeChecker::visitTransposeAttr(TransposeAttr *attr) {
}

void AttributeChecker::visitAsyncHandlerAttr(AsyncHandlerAttr *attr) {
if (!Ctx.LangOpts.EnableExperimentalAsyncHandler) {
diagnoseAndRemoveAttr(attr, diag::asynchandler_removed);
return;
}

auto func = dyn_cast<FuncDecl>(D);
if (!func) {
diagnoseAndRemoveAttr(attr, diag::asynchandler_non_func);
Expand Down
10 changes: 10 additions & 0 deletions lib/Sema/TypeCheckConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ void swift::addAsyncNotes(AbstractFunctionDecl const* func) {

bool IsAsyncHandlerRequest::evaluate(
Evaluator &evaluator, FuncDecl *func) const {
// Turn off @asyncHandler when not specifically enabled.
if (!func->getASTContext().LangOpts.EnableExperimentalAsyncHandler) {
return false;
}

// Check whether the attribute was explicitly specified.
if (auto attr = func->getAttrs().getAttribute<AsyncHandlerAttr>()) {
// Check for well-formedness.
Expand Down Expand Up @@ -231,6 +236,11 @@ bool IsAsyncHandlerRequest::evaluate(

bool CanBeAsyncHandlerRequest::evaluate(
Evaluator &evaluator, FuncDecl *func) const {
// Turn off @asyncHandler when not specifically enabled.
if (!func->getASTContext().LangOpts.EnableExperimentalAsyncHandler) {
return false;
}

return !checkAsyncHandler(func, /*diagnose=*/false);
}

Expand Down
2 changes: 1 addition & 1 deletion test/ClangImporter/objc_async.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/Inputs/custom-modules -enable-experimental-concurrency %s -verify
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -I %S/Inputs/custom-modules -enable-experimental-concurrency -enable-experimental-async-handler %s -verify

// REQUIRES: objc_interop
// REQUIRES: concurrency
Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/actor_isolation.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -warn-concurrency
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -enable-experimental-async-handler -warn-concurrency
// REQUIRES: concurrency

let immutableGlobal: String = "hello"
Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/actor_isolation_objc.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -enable-experimental-async-handler
// REQUIRES: concurrency
// REQUIRES: objc_interop

Expand Down
1 change: 0 additions & 1 deletion test/Concurrency/async_throwing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ func throwingTask() async throws -> String {
return "ok!"
}

// expected-note@+2 7 {{add '@asyncHandler' to function 'syncTest()' to create an implicit asynchronous context}} {{1-1=@asyncHandler }}
// expected-note@+1 7 {{add 'async' to function 'syncTest()' to make it asynchronous}} {{16-16= async}}
func syncTest() {
let _ = invoke(fn: normalTask) // expected-error{{'async' call in a function that does not support concurrency}}
Expand Down
1 change: 0 additions & 1 deletion test/Concurrency/global_actor_from_ordinary_context.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ func referenceGlobalActor2() {
}


// expected-note@+2 {{add '@asyncHandler' to function 'referenceAsyncGlobalActor()' to create an implicit asynchronous context}} {{1-1=@asyncHandler }}
// expected-note@+1 {{add 'async' to function 'referenceAsyncGlobalActor()' to make it asynchronous}} {{33-33= async}}
func referenceAsyncGlobalActor() {
let y = asyncGlobalActFn
Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/global_actor_inference.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -enable-experimental-async-handler
// REQUIRES: concurrency

actor SomeActor { }
Expand Down
1 change: 0 additions & 1 deletion test/Concurrency/reasync.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ func reasyncWithAutoclosure(_: @autoclosure () async -> Int) reasync {}

func callReasyncWithAutoclosure1() {
// expected-note@-1 2{{add 'async' to function 'callReasyncWithAutoclosure1()' to make it asynchronous}}
// expected-note@-2 2{{add '@asyncHandler' to function 'callReasyncWithAutoclosure1()' to create an implicit asynchronous context}}
reasyncWithAutoclosure(computeValue())
await reasyncWithAutoclosure(await computeValueAsync())
// expected-error@-1 {{'async' call in a function that does not support concurrency}}
Expand Down
2 changes: 1 addition & 1 deletion test/IDE/print_clang_objc_async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import _Concurrency

// CHECK-LABEL: protocol ProtocolWithSwiftAttributes {
// CHECK-NEXT: @actorIndependent func independentMethod()
// CHECK-NEXT: @asyncHandler func asyncHandlerMethod()
// CHECK-NEXT: func asyncHandlerMethod()
// CHECK-NEXT: {{^}} @MainActor func mainActorMethod()
// CHECK-NEXT: {{^}} @MainActor func uiActorMethod()
// CHECK-NEXT: {{^}} optional func missingAtAttributeMethod()
Expand Down
2 changes: 1 addition & 1 deletion test/ModuleInterface/actor_protocol.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -typecheck -enable-library-evolution -enable-experimental-concurrency -emit-module-interface-path %t/Library.swiftinterface -module-name Library %s
// RUN: %target-swift-frontend -typecheck -enable-library-evolution -enable-experimental-concurrency -enable-experimental-async-handler -emit-module-interface-path %t/Library.swiftinterface -module-name Library %s
// RUN: %FileCheck --check-prefix CHECK-EXTENSION %s <%t/Library.swiftinterface
// RUN: %FileCheck --check-prefix CHECK %s <%t/Library.swiftinterface
// REQUIRES: concurrency
Expand Down
2 changes: 1 addition & 1 deletion test/SILGen/async_handler.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 -enable-experimental-concurrency | %FileCheck %s
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 -enable-experimental-concurrency -enable-experimental-async-handler | %FileCheck %s
// REQUIRES: concurrency

func take<T>(_ t: T) async {
Expand Down
2 changes: 1 addition & 1 deletion test/SILGen/async_handler_witness_table.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-emit-silgen -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -enable-experimental-concurrency > %t.out
// RUN: %target-swift-emit-silgen -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -enable-experimental-concurrency -enable-experimental-async-handler> %t.out
// RUN: %FileCheck %s < %t.out

// REQUIRES: objc_interop
Expand Down
2 changes: 1 addition & 1 deletion test/TBD/async-function-pointer.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// REQUIRES: VENDOR=apple
// REQUIRES: concurrency
// RUN: %target-swift-frontend -emit-ir %s -enable-experimental-concurrency -validate-tbd-against-ir=all -module-name test | %FileCheck %s
// RUN: %target-swift-frontend -emit-ir %s -enable-experimental-concurrency -enable-experimental-async-handler -validate-tbd-against-ir=all -module-name test | %FileCheck %s

// CHECK: @"$s4test6testityyYFTu" = hidden global %swift.async_func_pointer

Expand Down
2 changes: 1 addition & 1 deletion test/TBD/async-handler.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -enable-experimental-concurrency -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all %s
// RUN: %target-swift-frontend -enable-experimental-concurrency -enable-experimental-async-handler -emit-ir -o/dev/null -parse-as-library -module-name test -validate-tbd-against-ir=all %s

// REQUIRES: VENDOR=apple
// REQUIRES: concurrency
Expand Down
2 changes: 1 addition & 1 deletion test/attr/asynchandler.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -typecheck -verify %s -enable-experimental-concurrency
// RUN: %target-swift-frontend -typecheck -verify %s -enable-experimental-concurrency -enable-experimental-async-handler

// REQUIRES: concurrency

Expand Down
1 change: 0 additions & 1 deletion test/attr/attr_objc_async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ actor MyActor {
// Actor-isolated entities cannot be exposed to Objective-C.
@objc func synchronousBad() { } // expected-error{{actor-isolated instance method 'synchronousBad()' cannot be @objc}}
// expected-note@-1{{add 'async' to function 'synchronousBad()' to make it asynchronous}} {{30-30= async}}
// expected-note@-2{{add '@asyncHandler' to function 'synchronousBad()' to create an implicit asynchronous context}} {{3-3=@asyncHandler }}

@objc var badProp: AnyObject { self } // expected-error{{actor-isolated property 'badProp' cannot be @objc}}
@objc subscript(index: Int) -> AnyObject { self } // expected-error{{actor-isolated subscript 'subscript(_:)' cannot be @objc}}
Expand Down
2 changes: 1 addition & 1 deletion test/decl/class/actor/conformance.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -enable-experimental-async-handler

// REQUIRES: concurrency

Expand Down
2 changes: 1 addition & 1 deletion test/decl/class/actor/global_actor_conformance.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -enable-experimental-async-handler
// REQUIRES: concurrency

actor SomeActor { }
Expand Down
4 changes: 1 addition & 3 deletions test/expr/unary/async_await.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ func test2(
}

func test3() { // expected-note{{add 'async' to function 'test3()' to make it asynchronous}} {{13-13= async}}
// expected-note@-1{{add '@asyncHandler' to function 'test3()' to create an implicit asynchronous context}}{{1-1=@asyncHandler }}
_ = await getInt() // expected-error{{'async' call in a function that does not support concurrency}}
}

Expand Down Expand Up @@ -190,8 +189,7 @@ func testAsyncLet() async throws {
_ = await x5
}

// expected-note@+2 4{{add 'async' to function 'testAsyncLetOutOfAsync()' to make it asynchronous}} {{30-30= async}}
// expected-note@+1 4{{add '@asyncHandler' to function 'testAsyncLetOutOfAsync()' to create an implicit asynchronous context}} {{1-1=@asyncHandler }}
// expected-note@+1 4{{add 'async' to function 'testAsyncLetOutOfAsync()' to make it asynchronous}} {{30-30= async}}
func testAsyncLetOutOfAsync() {
async let x = 1 // expected-error{{'async let' in a function that does not support concurrency}}
// FIXME: expected-error@-1{{'async' call in a function that does not support concurrency}}
Expand Down

0 comments on commit c76dac7

Please sign in to comment.