-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Rule request: [no-async-without-await] Functions marked async must contain an await or return statement #5082
Comments
Async functions without awaits are entirely appropriate, as they can be used to run synchronous code in the background. Barring any enclosing actor scope (isolation), your If this is added it should certainly not be enabled by default. |
@jshier you're suggesting Until Swift 5.9 and custom executors, it's not possible to use Swift Concurrency to guarantee code is run in the background. |
If defined outside an actor context, |
Execution on the default executor != execution in the background. Today that may be the case, but the way the cooperative thread pool works is an implementation detail that is not exposed and could change in the future/on more constrained systems. Swift Concurrency provides an abstraction that doesn't have a concept of "background". Currently (Until swift 5.9) if you want to guarantee code is executed off the main thread (i.e. the background) you need to drop down to GCD or Threads. If this rule is not useful, then why shouldn't every function be marked as |
Yeah, that's not a distinction Swift concurrency makes, so I think you're pretty off base on user expectations here. Why would anyone expect that when, given your definition, it's not even possible right now? In any case, I've laid out my reasoning, it's up to the maintainers now. |
I'd argue it does make that distinction by intentionally not documenting whether code is run in the background:
My response to your original comment only intended to explain why the one example you provided against this rule is invalid. Adding |
Function declaration represents interface, whereas it's content is implementation. protocol MyAsyncProtocol {
func doSomething() async
}
class ImpOne: MyAsyncProtocol {
func doSomething() async {
await useAsyncFunction() // Is Ok - using await
}
}
class ImpTwo: MyAsyncProtocol {
func doSomething() async {
useSyncFunction() // Is also Ok - not to use await if not needed
}
} |
☝️ valid |
New Issue Checklist
New rule request
Disallow
async
functions which have noawait
expression.the community thinks about this.
async
functions that don't suspend contradict the Swift Concurrency documentation which specifies they are able to suspend partway through execution.Asynchronous functions that don’t use await can cause confusion in that a programmer awaiting such a function may assume it's guaranteed to execute its work in the background. Although such an assumption is a fundamental misunderstanding of Swift Concurrency, there are plenty of examples.
Async functions without await are a common and unintentional result of refactoring.
Pass:
Fail:
Should the rule be configurable, if so what parameters should be configurable?
There may be edge cases where async without await is appropriate that I'm not thinking of.
Should the rule be opt-in or enabled by default? Why?
Enabled by default
I believe this rule would be fast, is not prone to false positives and is general consensus.
Linters for other languages have this rule:
TS Lint
ES Lint
The text was updated successfully, but these errors were encountered: