Skip to content

Commit 9f9987f

Browse files
eernstgcommit-bot@chromium.org
authored andcommitted
It is now an error to have void foo() { return 42; }
The language team several times agreed to make it an error when a non-void expression `e` is used in `return e;` in the body of a function whose return type is `void`. When `void` is changed from a near-bottom type to a top type, the wording in the language specification (dartLangSpec.tex) does _not_ ensure that this is an error, because all types are assignable to `void`, so we need a specific rule saying that it is an error. This CL adds such a rule to the feature spec for generalized void. It also adds a rule that makes it an error to have return type `void` in a function marked `async*` or `sync*`, based on the reasoning that they "are returning a Future/Stream/Iterable semantically", and it would now be an error if they did that explicitly. Change-Id: I22fed9e9fc6097bb50100a151b964045e41ef173 Reviewed-on: https://dart-review.googlesource.com/35680 Reviewed-by: Leaf Petersen <[email protected]> Commit-Queue: Erik Ernst <[email protected]>
1 parent 90f3a60 commit 9f9987f

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

docs/language/informal/generalized-void.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,31 @@ hence ignored), except when explicitly subjected to a type cast. This
287287
open for the cases where the developer knows that the typing misrepresents
288288
the actual situation.*
289289

290+
We define void equivalent types inductively as follows: A type `T` is
291+
_void equivalent_ if `T` is `void` or `T` is a type of the form
292+
`FutureOr<S>` where `S` is a void equivalent type.
293+
294+
*The subtype rules for `FutureOr` ensure that whenever `T` is a void
295+
equivalent type we can show `T <: void` and `void <: T`. In that sense we
296+
may consider void equivalent types to be "the same type". However, we will
297+
not necessarily treat them identically for all purposes. For instance,
298+
it is useful to be able to test `if (x is Future<void>) ..` in the case
299+
where `x` is a variable of type `FutureOr<void>`, but that is not allowed
300+
when `x` has type `void`.*
301+
302+
It is a static warning (in Dart 2: a compile-time error) if a return
303+
statement `return e;` occurs such that the innermost enclosing function
304+
has return type `void` and the static type of `e` is not a void equivalent
305+
type.
306+
307+
It is a static warning (in Dart 2: a compile-time error) if a function
308+
marked `async*`, or `sync*` has return type `void`.
309+
310+
*Note that it is allowed for an `async` function to have return type
311+
`void`. This serves to indicate that said function performs a
312+
"fire-and-forget" operation, that is, it is not even useful for the caller
313+
to synchronize with the completion of that task.*
314+
290315
During bounds checking, it is possible that a bound of a formal type
291316
parameter of a generic class or function is statically known to be the type
292317
void. In this case, the bound is considered to be the built-in class

0 commit comments

Comments
 (0)