Skip to content
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

[SR-13538] Improve diagnostics in *current* Swift compilers when async keyword is used #55975

Open
beccadax opened this issue Sep 10, 2020 · 1 comment
Labels
compiler The Swift compiler in itself improvement parser Area → compiler: The legacy C++ parser

Comments

@beccadax
Copy link
Contributor

Previous ID SR-13538
Radar rdar://problem/68665815
Original Reporter @beccadax
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement, Parser
Assignee None
Priority Medium

md5: 8baa712ca988a4f748590accc728d8ce

Issue Description:

It is likely that a future version of Swift will support an async keyword where we would expect throws to be. That means we can anticipate that, in the future, current Swift compilers will accidentally be fed code using the async keyword in this way.

If you feed code like that to Swift 5.3:

func fn1() async {}
func fn2() async -> Void {}
func fn3() async throws {}
func fn4() async throws -> Void {}
func fn5<T>(_: T) async where T: AnyObject {}

You get a spew of 27 terrible diagnostics:

<stdin>:1:11: error: consecutive statements on a line must be separated by ';'
func fn1() async {}
          ^
          ;
<stdin>:2:11: error: consecutive statements on a line must be separated by ';'
func fn2() async -> Void {}
          ^
          ;
<stdin>:3:11: error: consecutive statements on a line must be separated by ';'
func fn3() async throws {}
          ^
          ;
<stdin>:3:18: error: 'throws' may only occur before '->'
func fn3() async throws {}
                 ^
<stdin>:3:25: error: top-level statement cannot begin with a closure expression
func fn3() async throws {}
                        ^
<stdin>:4:11: error: consecutive statements on a line must be separated by ';'
func fn4() async throws -> Void {}
          ^
          ;
<stdin>:5:18: error: consecutive statements on a line must be separated by ';'
func fn5<T>(_: T) async where T: AnyObject {}
                 ^
                 ;
<stdin>:5:24: error: consecutive statements on a line must be separated by ';'
func fn5<T>(_: T) async where T: AnyObject {}
                       ^
                       ;
<stdin>:5:25: error: expected expression
func fn5<T>(_: T) async where T: AnyObject {}
                        ^
<stdin>:5:44: error: top-level statement cannot begin with a closure expression
func fn5<T>(_: T) async where T: AnyObject {}
                                           ^
<stdin>:1:6: error: expected '{' in body of function declaration
func fn1() async {}
     ^
<stdin>:1:12: error: cannot find 'async' in scope
func fn1() async {}
           ^~~~~
<stdin>:2:6: error: expected '{' in body of function declaration
func fn2() async -> Void {}
     ^
<stdin>:2:12: error: cannot find 'async' in scope
func fn2() async -> Void {}
           ^~~~~
<stdin>:2:12: error: expected type before '->'
func fn2() async -> Void {}
           ^
<stdin>:2:21: error: expected type after '->'
func fn2() async -> Void {}
                    ^
<stdin>:3:6: error: expected '{' in body of function declaration
func fn3() async throws {}
     ^
<stdin>:3:25: error: closure expression is unused
func fn3() async throws {}
                        ^
<stdin>:3:25: note: did you mean to use a 'do' statement?
func fn3() async throws {}
                        ^
                        do 
<stdin>:4:6: error: expected '{' in body of function declaration
func fn4() async throws -> Void {}
     ^
<stdin>:4:12: error: cannot find 'async' in scope
func fn4() async throws -> Void {}
           ^~~~~
<stdin>:4:12: error: expected type before '->'
func fn4() async throws -> Void {}
           ^
<stdin>:4:28: error: expected type after '->'
func fn4() async throws -> Void {}
                           ^
<stdin>:5:6: error: expected '{' in body of function declaration
func fn5<T>(_: T) async where T: AnyObject {}
     ^
<stdin>:5:19: error: cannot find 'async' in scope
func fn5<T>(_: T) async where T: AnyObject {}
                  ^~~~~
<stdin>:5:44: error: closure expression is unused
func fn5<T>(_: T) async where T: AnyObject {}
                                           ^
<stdin>:5:44: note: did you mean to use a 'do' statement?
func fn5<T>(_: T) async where T: AnyObject {}
                                           ^
                                           do 

We could tailor a diagnostic specifically for async, but honestly, it might be better to design a more general recovery behavior that's more intelligent than the current one. For instance, the parser might look past an unknown identifier and, if it sees that the next token is throws, rethrows, ->, {, or where, diagnose the unknown identifier and resume parsing normally.

@typesanitizer
Copy link

@swift-ci create

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself improvement parser Area → compiler: The legacy C++ parser
Projects
None yet
Development

No branches or pull requests

2 participants