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

Sometimes lint discarded_futures does not recognize unawaited. #3801

Open
polina-c opened this issue Oct 29, 2022 · 9 comments
Open

Sometimes lint discarded_futures does not recognize unawaited. #3801

polina-c opened this issue Oct 29, 2022 · 9 comments
Labels
false-positive P3 A lower priority bug or feature request set-none Does not affect any rules in a defined rule set (e.g., core, recommended, flutter) type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@polina-c
Copy link

polina-c commented Oct 29, 2022

Dor example, the file
devtools_app/lib/src/screens/performance/performance_controller.dart
in the PR: flutter/devtools#4659

Screen Shot 2022-10-28 at 7 56 20 PM

@lrhn lrhn changed the title Sometimes lint discarded_features does not recognize unwaited. Sometimes lint discarded_futures does not recognize unwaited. Oct 31, 2022
@lrhn
Copy link
Member

lrhn commented Oct 31, 2022

The lint, as described by itself, does not make exceptions for unawaited. It asks you to make the surrounding function async because you are calling an async function. If you do that, then you can use unawaited to avoid the unawaited_futures lint, which only applies to async functions.

Maybe discarded_futures lint should make an exception for futures which are not discarded. That is, it could use the same rules as unawaited_futures, only in a non-async function, and only complain if the future is actually discarded. If the future is used in a way that does not create a new future, then forcing the surrounding function to be async won't actually do anything useful. It will just force callers of that function to do the same thing.

(It's not a lint I'd ever consider enabling myself, because there are plenty of reasons to make non-async functions calling async functions when you are writing library code which works with futures.
For application code, it's more likely that you will only be consuming futures created by other code.)

@polina-c polina-c changed the title Sometimes lint discarded_futures does not recognize unwaited. Sometimes lint discarded_futures does not recognize unawaited. Oct 31, 2022
@bwilkerson bwilkerson added P3 A lower priority bug or feature request false-positive set-none Does not affect any rules in a defined rule set (e.g., core, recommended, flutter) labels Nov 7, 2022
@oprypin
Copy link
Contributor

oprypin commented May 9, 2023

Disregarding high-level considerations, I think there can't be any argument made that this lint is better by still complaining even after one adds unawaited. This is a false positive and should be fixed.

@lrhn
Copy link
Member

lrhn commented May 9, 2023

If the lint is intended to disregard future-returning invocations inside an unawaited(...) invocation, then not disregarding is definitely a bug.

I'm saying that the description of the lint does not suggest that to be the case.

Looking at the implementation CL, and the tests, they do suggest that unawaited should be recognized, so the description should probably be updated or expanded.

(So yes, false positive, and description needs to be improved.)

It's also still an overly broad lint, IMO. Passing a future as an argument to a function which expects a future as argument, should probably be considered as "not discarded", not matter which function it is. (Like #3739). Or calling a method on the future, like .ignore().

I'd prefer if it only warned in the same places where unawaited_future would warn inside an async function, where a future is actually about to be discarded, but the idea seems to be to force most uses of futures to be inside async functions, even those that don't actually need to be awaited immediately. (And that's also a valid goal for a lint, just not one I'd enable.)

(@pq : The implementation seems a little eager to bail out. It stops recursing subexpression when it sees an invocation of unawaited, so if you have unwaited(foo(voidParameter: asyncFunction())), it won't recognize the future being assigned to void as discarded.)

@oprypin
Copy link
Contributor

oprypin commented May 9, 2023

Regarding the implementation, I'm guessing the check for unawaited is written just so the lint doesn't complain about unawaited itself, seeing as it is in fact a function that returns Future.

@oprypin
Copy link
Contributor

oprypin commented May 9, 2023

Actually never mind, I'm not sure what actually happens with the interaction with RecursiveAstVisitor

@lrhn
Copy link
Member

lrhn commented May 9, 2023

Yup, the unawaited function returns void, so that's not an issue. (https://api.dart.dev/stable/2.14.1/dart-async/unawaited.html).

There is nothing magical about the unawaited function, the unawaited_futures lint doesn't need to recognize it, because that lint just looks for futures which are not processed in some way. Calling unawaited function counts as processing the argument, and since it returns void, there is nothing more to check for.

That's another reason this lint worries me, it has to recognize unawaited explicitly, and therefore won't work with other, equally valid, ways to process a future (like Future.ignore()).

@oprypin
Copy link
Contributor

oprypin commented May 9, 2023

That's another reason this lint worries me, it has to recognize unawaited explicitly, and therefore won't work with other, equally valid, ways to process a future (like Future.ignore()).

@pq
Copy link
Member

pq commented May 9, 2023

@oprypin: I agree 100% and would love to see @awaitNotRequired or similar implemented. Maybe time to revisit dart-lang/sdk#46218?

@lrhn
Copy link
Member

lrhn commented May 9, 2023

Such an annotation would be introduced by the analyzer and likely be in package:meta.

If we want to get the functionality for platform declarations, we can use a @pragma("analyzer:await_not_required") annotation.
(Heck, the declaration of awaitNotRequired could be just const awaitNotRequired = pragma('analyzer:await_not_required');, then everyone can use the same value as annotation.)

@srawlins srawlins added the type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) label Apr 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
false-positive P3 A lower priority bug or feature request set-none Does not affect any rules in a defined rule set (e.g., core, recommended, flutter) type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

6 participants