-
Notifications
You must be signed in to change notification settings - Fork 1.7k
consider an annotation to tag async members as not needing await #46218
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
Comments
Do we want something fairly specific, like |
Excellent question. My gut says we want the specificity of something like |
In another thread where this was discussed (#58348) Hixie suggested |
Which leads to the next question: are there any static checks associated with For example, I could imagine checking some or all of the following:
|
I think order of execution is more of a concern with missing 'await' than exception handling? At least, in web and web test code that was the concern. I don't remember anything specifically about exception handling. So what I was expecting is:
and for that I'm not sure about the requirement to not throw; it seems to me like it's a valid design to have unawaited futures that throw, and rely on the zone exception handler to catch them? |
Also, it's quite possible that you have a method that can never throw that you always want to await, e.g.
So I don't think that works by itself. |
Just noted this issue, and I can't help mentioning a thing: A fire-and-forget async function can be expressed by using the return type void fireAndForget() async { ... }
void main() async {
fireAndForget(); // No complaints about unawaited futures.
} |
Thanks @eernstg! I've wondered this too and it's exactly why I think some specific API examples would be handy. |
In dart-lang/core#742, @goderbauer mentioned https://api.flutter.dev/flutter/animation/AnimationController/forward.html In this and related cases a |
These methods return Futures because sometimes you do want to await them (although that's rare), but in the most common cases you should be able to just drop them on the floor without having to litter your code with |
@goderbauer: I'm curious how you'd feel about adopting an |
|
I would like to see For example: Map.remove called on a |
See also: #58348. |
/fyi @lrhn @leafpetersen @natebosch @jakemac53 If this is something we agree we want to do, it will suggest the annotation living in core (not EDIT: pragmatically, if there are only a few core library declarations we want to tag, we could bake that awareness into the lint and sidestep the challenge of landing a new annotation in the SDK. (Not tidy but there's certainly precedent. 😬 ) |
As for @jacob314's example, I do wonder if that might not be better addressed in the lint. That one feels like a false positive to me. |
Another request that came up for this would be that if a @awaitNotRequired
Future<void> doNotAwaitMe() async {
print('ok');
}
Future<void> awaitMe() async {
print('I sure hope you awaited this');
}
// Should be transitively @awaitNotRequired
Future<void> someFunction() async {
await doNotAwaitMe(); // or don't await it, shouldn't matter.
print('hi');
}
// Lint error to not await this function
Future<void> someOtherFunction() async {
await awaitMe();
print('hi');
}
|
@dnfield Do we have an actual use case for that in the framework? |
I think that request means that such a function is treated as if it had been explicitly annotated without requiring an explicit annotation. If so, I'm not positive, but I suspect that that's something we can't efficiently implement. (The only implementation I'm currently thinking of would be to create and incrementally maintain the call graph for all the code being analyzed, or at least for What we could do is add a lint to flag any such functions that aren't explicitly annotated as needing to be annotated, but such a lint might produce a lot of noise. |
@Hixie was suggesting this. My impression is that we'd want to avoid needing to go up the chain of every function in the framework that calls annotated functions and avoiding awaiting them. As I think about it, I wonder why that wouldn't be a good thing - we'd explicitly make choices about whether we really meant for a specific function to be awaited or not. But maybe @Hixie has some example I'm not thinking of. |
Adding inference for this behavior would make it too fragile - local edits could have unpredictable consequences. |
A Likewise, a function only calling I don't particularly want lint-related annotations in the platform libraries. A Ignoring methods which happen to return a future due to generics, but which aren't inherently asynchronous seems somewhat reasonable, but also risky. It is a future, and it's impossible to know whether someone waited for it or not. |
Hi, is there any updates :) |
Hi @bsutton I can't tell from your link where the annotation would go or where the |
Here is a typical use case: body: FutureBuilderEx(
// ignore: discarded_futures
future: _signin(context),
waitingBuilder:
(context) => const Center(child: CircularProgressIndicator()),
builder:
(context, auth) => Center(
Note the need to ignore the discarded future. In FutureBuilderEx I want to annotate the future param so that the discarded_futures lint is suppressed at all call sites. class FutureBuilderEx<T> extends StatefulWidget {
const FutureBuilderEx({
@unawaited /// suppress the discarded_futures lint wherever FutureBuilderEx is called.
required this.future,
required this.builder,
super.key,
this.initialData,
this.waitingBuilder,
this.errorBuilder,
this.debugLabel = '',
}); |
I'm not certain that I like the 'unawaited' variants of the lint name as in my case it's not that the future is unawaited, it's just that it is handled/managed by the called function. Maybe: @managed_future @owned_future The parameter use case feels different to the examples that call a function that never want to be awaited. |
Oh, this should be fixed by https://dart-review.googlesource.com/c/sdk/+/403901 - passing a Future as an argument that expects a Future is a valid 'use'. |
@srawlins I sent a PR suggesting some doc changes for |
Quick correction: "my PR" is written by @FMorschel |
Oh, my mistake, thanks @FMorschel :) |
OK latest question to resolve is the name. @lrhn , above, suggests Previously the discussion was |
I personally am fine with recommending something that requires package:meta. In an ideal world the annotation would live in a core lib probably, but if we can't do that for whatever reason then we shouldn't allow that to block anything. I don't think |
The annotation also isn't necessary for clients of annotated libraries, so most people won't need About the name, if |
I like |
@awaitNotRequired seems more informative.
Given the low use the additional length isn't offensive.
…On Wed, 26 Mar 2025, 3:28 am Kate Lovett, ***@***.***> wrote:
Previously the discussion was @awaitNotRequired vs @doesNotThrow, and we
went with @awaitNotRequired. I'd like folks to weigh in again re:
unawaited. [...] : who should I ping on the Flutter Framework team
regarding this lint rule and annotation name?
I like @awaitNotRequired over @unawaited. As I understand this, the
option to await or not await is still up to the typer. The
@awaitNotRequired seems more directive to me, while @unawaited sounds
like it already might be handled for me.
—
Reply to this email directly, view it on GitHub
<#46218 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAG32OEFI3IEJAPN7D4EXJL2WF72BAVCNFSM6AAAAABZBV6J36VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONJRHA2DGMZYGA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
[image: Piinks]*Piinks* left a comment (dart-lang/sdk#46218)
<#46218 (comment)>
Previously the discussion was @awaitNotRequired vs @doesNotThrow, and we
went with @awaitNotRequired. I'd like folks to weigh in again re:
unawaited. [...] : who should I ping on the Flutter Framework team
regarding this lint rule and annotation name?
I like @awaitNotRequired over @unawaited. As I understand this, the
option to await or not await is still up to the typer. The
@awaitNotRequired seems more directive to me, while @unawaited sounds
like it already might be handled for me.
—
Reply to this email directly, view it on GitHub
<#46218 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAG32OEFI3IEJAPN7D4EXJL2WF72BAVCNFSM6AAAAABZBV6J36VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDONJRHA2DGMZYGA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
+1 for |
💯 +1 from me too. |
Do we want to warn users if they're using the |
We could do that. An |
Yes
…On Thu, 24 Apr 2025, 12:38 am Brian Wilkerson, ***@***.***> wrote:
*bwilkerson* left a comment (dart-lang/sdk#46218)
<#46218 (comment)>
Do we want to warn users if they're using the unawaited method on an
expression covered by @awaitNotRequired? Seems like the call to unawaited
is unnecessary at that point.
—
Reply to this email directly, view it on GitHub
<#46218 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAG32OCCGPY6OMZAKGUB5GT226QWTAVCNFSM6AAAAABZBV6J36VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQMRUGUZTSMBUHA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Work towards #46218 This implements the bulk of the `@awaitNotRequired` support as specified here: #46218 (comment) Remaining work: * implement inheritence * report a badly-placed annotation * add the annotation to the real meta package Change-Id: Ida16018746704d0baa165ab9be95187b52a79061 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423923 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
I think it might be reasonable to make it a warning so that users don't need to enable it to get the benefit. The questions are:
|
There can be false positives when the function in question comes from a dependency, and the function is annotated for some releases of that dependency, and not annotated for others, in the accepted version constraint of the dependency. |
Oh, yuck. I suppose we could have an |
Work towards #46218 Change-Id: I9e356ab28996351d2ebfb15f655816f35a825339 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/424480 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]>
Work towards #46218 Change-Id: I41391cc317dec625f0b34afbf5f5a3402d8b08b4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/424261 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]>
Work towards #46218 Change-Id: I0c6953463d053205cc1110f554578e6b85eac0db Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426240 Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
Follow-up from conversation in dart-lang/core#742.
The idea is to add an annotation that allows API authors to mark declarations as not requiring an
await
at call sites. This could greatly reduce the number of uses of functions likeunawaited
to silence theunawaited_futures
lint.The text was updated successfully, but these errors were encountered: