1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
// This test aims to show that no preference is given to either the async or
// sync main function. The most specific, valid, main function will be
// selected if one exists. If two main functions could exist, the usage is
// ambiguous.
// async main is nested deeper in protocols than sync, use sync
// sync main is nested deeper in protocols than async, use async
// async and sync are same level, error
// REQUIRES: concurrency
// ASYNC_NESTED: async is nested more deeply than sync main in protocol chain
// NO_ASYNC: no async main function
// NO_SYNC: no sync main function
// BOTH: MainProtocol has both sync and async main
// INHERIT_SYNC: main type directly conforms to synchronous main protocol
// | has async main | has sync main | both | inherits sync | nested async | Result | | Run |
// | | | | | | Error | No main | RUN: not %target-swift-frontend -disable-availability-checking -DNO_SYNC -DNO_ASYNC -parse-as-library -typecheck -dump-ast %s 2>&1 | %FileCheck %s --check-prefix=CHECK-IS-ERROR1
// | x | x | x | x | | Error | Ambiguous main in MainP | RUN: not %target-swift-frontend -disable-availability-checking -DBOTH -DINHERIT_SYNC -parse-as-library -typecheck -dump-ast %s 2>&1 | %FileCheck %s --check-prefix=CHECK-IS-ERROR2
// | | x | x | x | | Error | Ambiguous main in MainP | RUN: not %target-swift-frontend -disable-availability-checking -DBOTH -DINHERIT_SYNC -parse-as-library -typecheck -dump-ast %s 2>&1 | %FileCheck %s --check-prefix=CHECK-IS-ERROR2
// | x | x | x | | | Async | Directly selected | RUN: %target-swift-frontend -disable-availability-checking -DBOTH -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
// | x | x | | | | Async | Directly selected | RUN: %target-swift-frontend -disable-availability-checking -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
// | | x | | | | Sync | Indirectly selected | RUN: %target-swift-frontend -disable-availability-checking -DNO_ASYNC -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-SYNC
// | x | x | | x | x | Sync | Directly selected | RUN: %target-swift-frontend -disable-availability-checking -DINHERIT_SYNC -DASYNC_NESTED -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-SYNC
// | x | | | x | x | Async | Indirectly selected | RUN: %target-swift-frontend -disable-availability-checking -DNO_SYNC -DINHERIT_SYNC -DASYNC_NESTED -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
// | x | | | x | | Error | Unrelated async main | RUN: not %target-swift-frontend -disable-availability-checking -DNO_SYNC -DINHERIT_SYNC -parse-as-library -typecheck -dump-ast %s 2>&1 | %FileCheck %s --check-prefix=CHECK-IS-ERROR1
// | | x | | | x | Error | Unrelated sync main | RUN: not %target-swift-frontend -disable-availability-checking -DNO_ASYNC -DASYNC_NESTED -parse-as-library -typecheck -dump-ast %s 2>&1 | %FileCheck %s --check-prefix=CHECK-IS-ERROR1
#if ASYNC_NESTED
protocol AsyncMainProtocol { }
protocol MainProtocol : AsyncMainProtocol { }
#else
protocol MainProtocol { }
protocol AsyncMainProtocol : MainProtocol { }
#endif
#if NO_SYNC
#else
extension MainProtocol {
static func main() { }
}
#endif
#if NO_ASYNC
#else
extension AsyncMainProtocol {
static func main() async { }
}
#endif
#if BOTH
extension MainProtocol {
static func main() async { }
}
#endif
#if INHERIT_SYNC
@main struct MyMain : MainProtocol {}
#else
@main struct MyMain : AsyncMainProtocol {}
#endif
// CHECK-IS-SYNC-LABEL: "MyMain" interface type="MyMain.Type"
// CHECK-IS-SYNC: (func_decl implicit "$main()" interface type="(MyMain.Type) -> () -> ()"
// CHECK-IS-SYNC: (declref_expr implicit type="(MyMain.Type) -> () -> ()"
// CHECK-IS-ASYNC-LABEL: "MyMain" interface type="MyMain.Type"
// CHECK-IS-ASYNC: (func_decl implicit "$main()" interface type="(MyMain.Type) -> () async -> ()"
// CHECK-IS-ASYNC: (declref_expr implicit type="(MyMain.Type) -> () async -> ()"
// CHECK-IS-ERROR1: error: 'MyMain' is annotated with @main and must provide a main static function of type {{\(\) -> Void or \(\) throws -> Void|\(\) -> Void, \(\) throws -> Void, \(\) async -> Void, or \(\) async throws -> Void}}
// CHECK-IS-ERROR2: error: ambiguous use of 'main'
|