Description
Cf. dart-lang/sdk#41324.
We may wish to revisit the rules about return e;
because the rules in the language specification mention Null
specifically in one case, and may need to treat Never
specifically in other cases).
For instance, Future<Never> f() async => null as dynamic;
is a compile-time error with the current rules, with null-safety. But this is because Future<dynamic>
is no longer assignable to Future<Never>
(so the wrapping with Future
gives the new assignability a distinction that the old assignability did not have). In contrast, Never f1() => null as dynamic;
is OK (with null-safety as well as without) because dynamic
is assignable to Never
.
In both cases we could argue that an expression of type dynamic
can be trusted to throw or loop (that is, to not complete, with or without a value) just as well as it could be trusted to return an object of an arbitrary type which is required by the context, or to some type that has a specific member with a specific signature. And we do trust the dynamic
expression for all those purposes.
So it seems consistent to allow return e;
when e
has type dynamic
, both in a synchronous non-generator function and in an asynchronous non-generator function.
If we do this then we'd need to adjust the language specification to avoid the wrapping in Future<...>
. This change should be a no-op semantically for now (same meaning), but it should ensure that the rules are still specifying the intended behavior when we introduce null-safety into the language specification.
@munificent, @lrhn, @leafpetersen, WDYT?