Analysis of discarded_futures
and unawaited_futures
does not work for tearoffs used as arguments and, in closures, is dependent on whether enclosing function is async
#56921
Labels
analyzer-linter
Issues with the analyzer's support for the linter package
area-analyzer
Use area-analyzer for Dart analyzer issues, including the analysis server and code completion.
P3
A lower priority bug or feature request
type-bug
Incorrect behavior (everything from a crash to more subtle misbehavior)
Issue description
As the title says the analysis of the
discarded_futures
andunawaited_futures
does not work for tearoffs used as arguments. Futhermore, in closures, the reporting of issues is dependent on whether the enclosing function isasync
or not (instead of evaluating that for the closure itself). Finally,unawaited
completely disables issue reporting for all futures used inside it, even if they are discarded in closures, which can lead to errors.The following examples were analyzed using
dart analyze
, with the rulesdiscarded_futures
andunawaited_futures
enabled.I have created a gist here, which contains the execution logs of these examples, along with some print statements, to show that this incomplete analysis can lead to errors in real-world applications.
Example 1 (analysis does not work for tearoffs used as arguments + in closures, is dependent on whether enclosing function is
async
)In this example,
loadFromRemote
is a function that returns aFuture<void>
.execute
accepts acallback
which is a function that returns a void. Therefore, by callingcallback
, the future returned byloadFromRemote
is discarded, without the use ofunawaited
orignore
[unexpected].Notes:
loadFromRemote
is called inside a closure, with() => loadFromRemote()
, thediscarded_futures
lint rule creates an issue [expected]. If, after this change,load
is modified to beasync
, the issue disappears [unexpected].Example 2 (in closures, is dependent on whether enclosing function is
async
)In this example, there are two functions,
tryLoadFromRemote
andtryLoadFromCache
that both returnFuture<void>
. Then, there is a function,load
, that also returnsFuture<void>
and isasync
.tryLoadFromCache
is used inload
and is awaited, buttryLoadFromRemote
, which is used inside a sync closure inthen
, is not awaited and, because of that, is discarded. No issue is reported on thetryLoadFromCache
call [expected], but thetryLoadFromRemote
call does not report any issues [unexpected].Notes:
If the signature of
load
is changed tovoid load()
and theawait
keyword is removed, both calls report issues [expected]. If the code is wrapped inunawaited
(see below), no issues are reported on thetryLoadFromCache
call [expected] and on thetryLoadFromRemote
call [unexpected].General info
#1
SMP PREEMPT_DYNAMIC Thu Oct 10 22:31:19 UTC 2024Process info
The text was updated successfully, but these errors were encountered: