Skip to content

NNBD: Analyzer throws a compile error when async function returns dynamic #41266

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

Closed
iarkh opened this issue Mar 31, 2020 · 4 comments
Closed
Labels
legacy-area-analyzer Use area-devexp instead. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@iarkh
Copy link
Contributor

iarkh commented Mar 31, 2020

Dart VM version: 2.8.0-dev.18.0 (dev) (Fri Mar 27 11:10:52 2020 +0100) on "windows_x64"

The following sample code example fails with analyzer on the line 3 and passes with dart:

dynamic getNull() => null;

Future<bool> test1() async => await getNull();
Future<bool> test2() => getNull();
bool test3() => getNull();

main() {}

Seems like there should not be compile error here.

Please note that analyzer is OK with the lines 4 and 5.

Sample output is:

$> dartanalyzer --enable-experiment=non-nullable test.dart
Analyzing test.dart...
error - A value of type 'dynamic' can't be returned from function 'test1' because it has a return type of 'bool'. - test.dart:3:31 - return_of_invalid_type
1 error found.

$> dart --enable-experiment=non-nullable test.dart
$

@eernstg eernstg added legacy-area-analyzer Use area-devexp instead. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels Mar 31, 2020
@eernstg
Copy link
Member

eernstg commented Mar 31, 2020

Right, something happened to the checks in the analyzer for a returned expression of type dynamic in an async (=> or {}) function around version 2.3 (where n018.dart contains the example given here):

> /usr/local/google/home/eernst/bin/dart-sdk-2.2.1-dev.3.0/bin/dartanalyzer --enable-experiment=non-nullable n018.dart
Analyzing n018.dart...
No issues found!
> /usr/local/google/home/eernst/bin/dart-sdk-2.3.3-dev.0.0/bin/dartanalyzer --enable-experiment=non-nullable n018.dart
Analyzing n018.dart...
  error • The return type 'dynamic' isn't a 'Future<bool>', as defined by the method 'test1' at n018.dart:3:31 • return_of_invalid_type
1 error found.

One more thing happened in 2.8, because it now claims that the return type is bool in a situation where the declaration explicitly says Future<bool>.

@eernstg
Copy link
Member

eernstg commented Apr 6, 2020

There is a clear issue with the wording of the error message here: The return type of test1 is not bool.

With respect to the treatment of returned expressions of type dynamic in an async function, note that some discussions are taking place here: dart-lang/language#914.

@stereotype441
Copy link
Member

There is a clear issue with the wording of the error message here: The return type of test1 is not bool.

With respect to the treatment of returned expressions of type dynamic in an async function, note that some discussions are taking place here: dart-lang/language#914.

@eernstg @leafpetersen it sounds like the discussions taking place there are about the possibility of changing the specified return rules. Can you clarify whether @iarkh's code snippet above ought to produce a compile time error under the current rules? As I understand it, currently the analyzer produces an error, and the co19 tests expect no error, so we are seeing co19 failures. It would be nice if in the short term (while we wait for a decision on dart-lang/language#914), we could change either the analyzer implementation or the co19 tests to match the current spec. But it's not clear to me from the discussion here which is correct under the current spec rules.

Thanks!

@leafpetersen
Copy link
Member

The analyzer behavior is correct. Section 9 of the spec says that it is a compile time error if:

The function is asynchronous, flatten(T) is not void, and it would
have been a compile-time error to declare the function with the body
async { return e; } rather than async => e

and the relevant passage of section 17.12 is:

 It is a compile-time
error if s is return e;, flatten(S) is not void, and Future<flatten(S)> is not
assignable to T

here flatten(S) is dynamic and Future<dynamic> is not assignable to Future<bool> when the nnbd flag is enabled.

If any changes are forthcoming in the spec we will open issues for implementation when needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
legacy-area-analyzer Use area-devexp instead. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

4 participants