Skip to content

Commit 943812c

Browse files
committed
Update main resolution tests
The async main resolution has dropped the custom availability checking, so I am able to collapse the resolution checking into a single test (deleting the macos-specific one). Selection of an asynchronous main vs a synchronous main is dependent on an `-async-main` flag. Due to the scoring mechanism, and that the specificity of a given resolution doesn't affect the score, a more general synchronous main will be selected over a more specific asynchronous main when the `-async-main` flag is not passed. If the flag is not passed and the program only contains an asynchronous main, or the asynchronous main is the only main function that is available given the constraints, then it will be selected. Conversely, if the flag is set and no valid asynchronous main functions exist, the main function will resolve to a synchronous main. This is the same behavior that is used to resolve an synchronous and asynchronous static function.
1 parent da0a331 commit 943812c

File tree

3 files changed

+57
-123
lines changed

3 files changed

+57
-123
lines changed

test/Concurrency/async_main_resolution.swift

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
1-
// Non-apple platforms don't need to worry about the version number as much
2-
// because they can pull in the concurrency libraries with the swift
3-
// installation.
4-
51
// async main is nested deeper in protocols than sync, use sync
62
// sync main is nested deeper in protocols than async, use async
73
// async and sync are same level, use async
84

9-
// REQUIRES: rdar89500797
10-
115
// REQUIRES: concurrency
12-
// UNSUPPORTED: VENDOR=apple
13-
14-
// Async is deeper in the protocol chain from `MyMain`, use sync
15-
// RUN: %target-swift-frontend -DASYNC_NESTED -DINHERIT_SYNC -typecheck -dump-ast -parse-as-library %s | %FileCheck %s --check-prefix=CHECK-IS-SYNC
16-
17-
// Sync is deeper in the protocol chain from `MyMain`, use async
18-
// RUN: %target-swift-frontend -typecheck -dump-ast -parse-as-library %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
196

20-
// Async and sync are the same level, use async
21-
// RUN: %target-swift-frontend -DBOTH -DINHERIT_SYNC -typecheck -dump-ast -parse-as-library %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
7+
// ASYNC_NESTED: async is nested more deeply than sync main in protocol chain
8+
// NO_ASYNC: no async main function
9+
// NO_SYNC: no sync main function
10+
// BOTH: MainProtocol has both sync and async main
11+
// INHERIT_SYNC: main type directly conforms to synchronous main protocol
12+
13+
// | async flag | has async main | has sync main | both | inherits sync | nested async | Result | Run |
14+
// | | | | | | | Error | RUN: not %target-swift-frontend -disable-availability-checking -DNO_ASYNC -DNO_SYNC -parse-as-library -typecheck -dump-ast %s 2>&1 | %FileCheck %s --check-prefix=CHECK-IS-ERROR
15+
// | | x | | | | | Async Main | RUN: %target-swift-frontend -disable-availability-checking -DNO_SYNC -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
16+
// | x | | x | | | | Sync Main | RUN: %target-swift-frontend -disable-availability-checking -DNO_ASYNC -async-main -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-SYNC
17+
// | x | x | x | | | | Async Main | RUN: %target-swift-frontend -disable-availability-checking -async-main -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
18+
// | | x | x | | | | Sync Main | RUN: %target-swift-frontend -disable-availability-checking -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-SYNC
19+
// | | x | x | | | x | Async Main | RUN: %target-swift-frontend -disable-availability-checking -DASYNC_NESTED -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
20+
// | | x | x | | x | x | Sync Main | 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
21+
// | x | x | x | | x | x | Async Main | RUN: %target-swift-frontend -disable-availability-checking -DINHERIT_SYNC -DASYNC_NESTED -async-main -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
22+
// | x | | x | | x | x | Sync Main | RUN: %target-swift-frontend -disable-availability-checking -DNO_ASYNC -DINHERIT_SYNC -DASYNC_NESTED -async-main -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-SYNC
23+
// | | | x | x | | | Sync Main | RUN: %target-swift-frontend -disable-availability-checking -DBOTH -DNO_ASYNC -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-SYNC
24+
// | x | | x | x | | | Async Main | RUN: %target-swift-frontend -disable-availability-checking -DBOTH -DNO_ASYNC -async-main -parse-as-library -typecheck -dump-ast %s | %FileCheck %s --check-prefix=CHECK-IS-ASYNC
25+
26+
// tldr;
27+
// If async flag is set, will pick an asynchronous main function if one is available and related. If none exist, will fall back on synchronous main.
28+
// If async flag is not set, will pick a asynchronous main function if one is available and related. If none exist, will fall back on an asynchronous main
29+
// If neither are available; error
2230

2331
#if ASYNC_NESTED
2432
protocol AsyncMainProtocol { }
@@ -55,8 +63,6 @@ extension MainProtocol {
5563
@main struct MyMain : AsyncMainProtocol {}
5664
#endif
5765

58-
59-
6066
// CHECK-IS-SYNC-LABEL: "MyMain" interface type='MyMain.Type'
6167
// CHECK-IS-SYNC: (func_decl implicit "$main()" interface type='(MyMain.Type) -> () -> ()'
6268
// CHECK-IS-SYNC: (declref_expr implicit type='(MyMain.Type) -> () -> ()'
@@ -65,6 +71,4 @@ extension MainProtocol {
6571
// CHECK-IS-ASYNC: (func_decl implicit "$main()" interface type='(MyMain.Type) -> () async -> ()'
6672
// CHECK-IS-ASYNC: (declref_expr implicit type='(MyMain.Type) -> () async -> ()'
6773

68-
// CHECK-IS-ERROR: error: 'MyMain' is annotated with @main and must provide a main static function of type () -> Void or () throws -> Void
69-
70-
// CHECK-IS-ERROR-ASYNC: error: 'MyMain' is annotated with @main and must provide a main static function of type () -> Void, () throws -> Void, () async -> Void, or () async throws -> Void
74+
// CHECK-IS-ERROR: 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}}

test/Concurrency/async_main_resolution_macos.swift

Lines changed: 0 additions & 95 deletions
This file was deleted.

test/Concurrency/where_clause_main_resolution.swift

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
// RUN: %target-swift-frontend -disable-availability-checking -D CONFIG1 -dump-ast -parse-as-library %s | %FileCheck %s --check-prefix=CHECK-CONFIG1
2-
// RUN: %target-swift-frontend -disable-availability-checking -D CONFIG2 -dump-ast -parse-as-library %s | %FileCheck %s --check-prefix=CHECK-CONFIG2
3-
// RUN: %target-swift-frontend -disable-availability-checking -D CONFIG3 -dump-ast -parse-as-library %s | %FileCheck %s --check-prefix=CHECK-CONFIG3
1+
// RUN: %target-swift-frontend -disable-availability-checking -D CONFIG1 -dump-ast -parse-as-library %s | %FileCheck %s --check-prefixes=CHECK,CHECK-CONFIG1
2+
// RUN: %target-swift-frontend -disable-availability-checking -D CONFIG1 -dump-ast -parse-as-library -async-main %s | %FileCheck %s --check-prefixes=CHECK,CHECK-CONFIG1-ASYNC
3+
// RUN: %target-swift-frontend -disable-availability-checking -D CONFIG2 -dump-ast -parse-as-library %s | %FileCheck %s --check-prefixes=CHECK,CHECK-CONFIG2
4+
// RUN: %target-swift-frontend -disable-availability-checking -D CONFIG2 -dump-ast -parse-as-library -async-main %s | %FileCheck %s --check-prefixes=CHECK,CHECK-CONFIG2-ASYNC
5+
// RUN: %target-swift-frontend -disable-availability-checking -D CONFIG3 -dump-ast -parse-as-library %s | %FileCheck %s --check-prefixes=CHECK,CHECK-CONFIG3
6+
// RUN: %target-swift-frontend -disable-availability-checking -D CONFIG3 -dump-ast -parse-as-library -async-main %s | %FileCheck %s --check-prefixes=CHECK,CHECK-CONFIG3-ASYNC
47

58
// REQUIRES: concurrency
69

@@ -14,22 +17,44 @@ protocol App {
1417
associatedtype Configuration: AppConfiguration
1518
}
1619

20+
// Load in the source file name and grab line numbers for default main funcs
21+
// CHECK: (source_file "[[SOURCE_FILE:[^"]+]]"
22+
// CHECK: (extension_decl range={{\[}}[[SOURCE_FILE]]:{{[0-9]+}}:{{[0-9]+}} - line:{{[0-9]+}}:{{[0-9]+}}{{\]}} App where
23+
// CHECK: (extension_decl range={{\[}}[[SOURCE_FILE]]:{{[0-9]+}}:{{[0-9]+}} - line:{{[0-9]+}}:{{[0-9]+}}{{\]}} App where
24+
// CHECK: (extension_decl range={{\[}}[[SOURCE_FILE]]:{{[0-9]+}}:{{[0-9]+}} - line:{{[0-9]+}}:{{[0-9]+}}{{\]}}
25+
// CHECK-NOT: where
26+
// CHECK-NEXT: (func_decl range={{\[}}[[SOURCE_FILE]]:[[DEFAULT_ASYNCHRONOUS_MAIN_LINE:[0-9]+]]:{{[0-9]+}} - line:{{[0-9]+}}:{{[0-9]+}}{{\]}} "main()"
27+
// CHECK-SAME: interface type='<Self where Self : App> (Self.Type) -> () async -> ()'
28+
// CHECK: (func_decl range={{\[}}[[SOURCE_FILE]]:[[DEFAULT_SYNCHRONOUS_MAIN_LINE:[0-9]+]]:{{[0-9]+}} - line:{{[0-9]+}}:{{[0-9]+}}{{\]}} "main()"
29+
// CHECK-SAME: interface type='<Self where Self : App> (Self.Type) -> () -> ()'
30+
31+
1732
extension App where Configuration == Config1 {
1833
// CHECK-CONFIG1: (func_decl implicit "$main()" interface type='(MainType.Type) -> () -> ()'
19-
// CHECK-CONFIG1: where_clause_main_resolution.swift:[[# @LINE+1 ]]
34+
// CHECK-CONFIG1: [[SOURCE_FILE]]:[[# @LINE+1 ]]
2035
static func main() { }
36+
37+
// CHECK-CONFIG1-ASYNC: (func_decl implicit "$main()" interface type='(MainType.Type) -> () async -> ()'
38+
// CHECK-CONFIG1-ASYNC: [[SOURCE_FILE]]:[[DEFAULT_ASYNCHRONOUS_MAIN_LINE]]
2139
}
2240

2341
extension App where Configuration == Config2 {
24-
// CHECK-CONFIG2: (func_decl implicit "$main()" interface type='(MainType.Type) -> () async -> ()'
25-
// CHECK-CONFIG2: where_clause_main_resolution.swift:[[# @LINE+1 ]]
42+
// CHECK-CONFIG2: (func_decl implicit "$main()" interface type='(MainType.Type) -> () -> ()'
43+
// CHECK-CONFIG2: [[SOURCE_FILE]]:[[DEFAULT_SYNCHRONOUS_MAIN_LINE]]
44+
45+
// CHECK-CONFIG2-ASYNC: (func_decl implicit "$main()" interface type='(MainType.Type) -> () async -> ()'
46+
// CHECK-CONFIG2-ASYNC: [[SOURCE_FILE]]:[[# @LINE+1 ]]
2647
static func main() async { }
2748
}
2849

2950
extension App {
30-
// CHECK-CONFIG3: (func_decl implicit "$main()" interface type='(MainType.Type) -> () async -> ()'
31-
// CHECK-CONFIG3: where_clause_main_resolution.swift:[[# @LINE+1 ]]
51+
// CHECK-CONFIG3-ASYNC: (func_decl implicit "$main()" interface type='(MainType.Type) -> () async -> ()'
52+
// CHECK-CONFIG3-ASYNC: [[SOURCE_FILE]]:[[# @LINE+1 ]]
3253
static func main() async { }
54+
55+
// CHECK-CONFIG3: (func_decl implicit "$main()" interface type='(MainType.Type) -> () -> ()'
56+
// CHECK-CONFIG3: [[SOURCE_FILE]]:[[# @LINE+1 ]]
57+
static func main() { }
3358
}
3459

3560
@main

0 commit comments

Comments
 (0)