dart-lang / dart-lang/language
Some "reach the end" errors are not reported. Fix it, or twist the spec?
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
Here is an issue that I could have created in the SDK repository. I'm creating this issue instead because it would be a breaking change to fix the implemented behavior such that it is aligned with the specified behavior.
So, @dart-lang/language-team, should we go ahead and change the implementations to follow the spec? Or should we change the spec to match one of the specifications? (They don't agree, so we can't just specify the existing behavior.)
-----
[The following is a potential SDK issue, with labe 'area-meta' and subissues for the analyzer and for the CFE]
Consider the following library:
```dart
import 'dart:async';
void f1() {}
dynamic f2() {}
Null f3() {}
int f4() {} // Error ++
Object? f5() {} // Error -*
FutureOr? f6() {} // Error -*
FutureOr f7() {} // Error -*
FutureOr f8() {} // Error --
class A {
factory A.f4() {} // Error ++
}
Future g01() async {}
Future g02() async {}
Future g03() async {}
FutureOr g04() async {}
FutureOr g05() async {}
FutureOr g06() async {}
Future? g07() async {}
Future? g08() async {}
Future? g09() async {}
FutureOr? g10() async {}
FutureOr? g11() async {}
FutureOr? g12() async {}
void g13() async {}
dynamic g14() async {}
Future g17() async {} // Error ++
Future g18() async {} // Error -*
Future?> g19() async {} // Error -*
Future> g20() async {} // Error -*
Future> g21() async {} // Error --
FutureOr g23() async {} // Error ++
FutureOr g24() async {} // Error -*
FutureOr?> g25() async {} // Error -*
FutureOr> g26() async {} // Error -*
FutureOr> g27() async {} // Error --
Future? g29() async {} // Error -+
Future? g30() async {} // Error -*
Future?>? g31() async {} // Error -*
Future>? g32() async {} // Error -*
Future>? g33() async {} // Error --
FutureOr? g35() async {} // Error -+
FutureOr? g36() async {} // Error -*
FutureOr?>? g37() async {} // Error -*
FutureOr>? g38() async {} // Error -*
FutureOr>? g39() async {} // Error --
```
Each line marked with 'Error' [should be reported as a compile-time error](https://github.com/dart-lang/language/blob/9558905ec2151a2b6b1c5154a44db5a2deb00388/specification/dartLangSpec.tex#L1996). However, the CFE does not report the lines where the comment has a '-' immediately after `Error `, and the analyzer does not report the lines where `Error ` is followed by a `-` one position later (as in `Error x-` where `x` can be anything). Finally, the analyzer reports a warning rather than an error in lines where `Error` is followed by `*` in the same position (as in `Error x*`).
The underlying reason is that it is an error to "return nothing" when the return type isn't `void`, `dynamic`, or `Null` (for a non-`async` non-generator function), or when the future value type of the function isn't `void`, `dynamic`, or `Null` (for an `async` non-generator function).
This error does not depend on the soundness of the implied semantics (which is to return null), it is intended to give developers a heads-up even in a function whose return type is, say, `Object?`. In such a function it's perfectly sound to return null, but the assumption is that the end of the function has been reached because of a bug, not because the developer intended to return null. A remedy could be to add an explicit `return null;` at the end of the body which would eliminate the error, even though it doesn't change the behavior at run time at all.
Contributor guide
Assessment
This issue has not been assessed yet.