Files
swift-mirror/test/Concurrency/async_main_resolution.swift
Evan Wilde 1ed855611c Update tests
This patch contains the updates for the tests. The merge removes the
`-async-main` flag, so the tests using that flag fail on that.

Additionally, the tests reflect the newer behavior of the main
resolution. `async_main_resolution` verifies that we're not preferring
an async function over a synchronous function, and vice versa.

This is also verified in `where_clause_main_resolution`, where we select
a main function using various configuration typealiases.

Finally, we only select a valid, usable main function. The old machinery
could select one sort of at random (technically it selected the first
overload declared in the source file) if an error occurred. Errors that
resulted in this behavior included a missing valid function, or an
ambiguous overload. In the case of the missing valid function, the
function returned would be from an invalid location if one existed,
which was called from `$main`. `$main` had sufficient context to realize
that the main function being called was not valid, and would emit an
error saying why. It would be better to realize that we're not getting a
valid main function earlier, and later we can emit notes saying why each
function called main could not be selected.
2022-04-26 16:30:33 -07:00

75 lines
5.1 KiB
Swift

// 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'