The following triggers an analysis warning in 2.0.0-dev.32.0:
import 'dart:async';
void returnNothing() {
return; // OK
}
Future<void> returnNothingInTheFuture() async {
return; // ERROR: Expecting return.
}
FutureOr<void> returnNothingMaybeInTheFuture() async {
return; // ERROR: Expecting return.
}
I can silence it with return null; ... but can't that be automatic?
Agreed, when return expressionOfTypeT; is allowed in a function Future<T> foo() async .., it is very natural to allow return; in a function Future<void> foo() async ...
We would need a special exception for this, of course, and there may be other cases. We have had some discussions in #32177, and I've added a reference to this issue there.
These are tricky cases, and I don't think we agree entirely on what to say about it.
My personal guiding rules are that:
return; and return voidExpression; must be valid in the same cases (if we allow the latter at all, which we have historically done) ...return; is really just equivalent to return null as void; (if we allow ... as void) ...return voidExpression; says that it's allowed in an async function if Future<void> is assignable to the return type of the function.The third entry is the general rule for return e;. A return e; is type-correct if Future<flatten(typeOf(e))> is assignable to the return type of the surrounding function. We know that the actual return value is a Future<flatten(returnType)>, so in the async cases here, the actual return object is a Future<void>, and the Future<flatten(typeOf(e))> thing is really a way of saying that the value of e can be used to complete the actually returned future.
So, I would want the second and third examples to be valid, because they would be for return voidFunction();.
We don't currently have a Dart 2 compatible specification for the return; case, so the law is still open.
The current situation is clearly just wrong:
import 'dart:async';
void foo1() {
return;
}
Null foo2() {
return;
}
Future<void> foo3() async {
return; // warning • Missing return value after 'return' at test.dart:12:3 • return_without_value
}
Future<Null> foo4() async {
return;
}
void main() { }
I think you can use like this:
import 'dart:async';
void foo1() {
return;
}
Null foo2() {
return;
}
Future<void> foo3() async {
return Future<void>(() {});
}
Future<Null> foo4() async {
return Future<Null>(() {});
}
With recent updates to the rules about returning (esp. https://github.com/dart-lang/language/pull/941), there are no errors in the following:
import 'dart:async';
void foo1() {
return;
}
Null foo2() {
return;
}
Future<void> foo3() async {
return;
}
Future<Null> foo4() async {
return;
}
Most helpful comment
The current situation is clearly just wrong: