dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.25k stars 1.58k forks source link

Confusing error message when a `void` value is used #56992

Open sgrekhov opened 2 weeks ago

sgrekhov commented 2 weeks ago
FutureOr<void> foo() => print(""); // print() returns void

The code above produces an error in both analyzer and VM. Analyzer error message is A value of type 'void' can't be returned from the function 'foo' because it has a return type of 'FutureOr<void>' and VM error is Error: A value of type 'void' can't be returned from a function with return type 'FutureOr<void>'.

This error message is confusing. void is assignable to FutureOr<void>, the problem here is that a void value returned by print() is used. Please update the error message accordingly.

cc @eernstg

Dart SDK version: 3.7.0-71.0.dev (dev) (Fri Oct 25 17:06:43 2024 -0700) on "windows_x64"

dart-github-bot commented 2 weeks ago

Summary: The error message "A value of type 'void' can't be returned from the function 'foo' because it has a return type of 'FutureOr'." is confusing because void is assignable to FutureOr<void>. The actual issue is that the void value returned by print() is being used, not the type itself. The error message should be updated to reflect this.

eernstg commented 2 weeks ago

Right. I adjusted the labels to indicate that this is concerned with the diagnostics from both tools. I removed type-bug because i think improve-diagnostics is usually specified alone, and it is taken to imply some kind of a type-bug treatment.

The error message sounds like there was a subtype test void <: FutureOr<void>, and it failed (so we can't return that value because it isn't type correct). However, as @sgrekhov mentions, that subtype relation does hold.

The actual reason why there is an error is that the allowlist for using the result from evaluation of an expression of type void (https://github.com/dart-lang/language/blob/9dc3737010f3ccac5ef54bf63b402d8e86b9115c/specification/dartLangSpec.tex#L22666) doesn't contain any items that match return print("");.

So I'd expect an error message saying something like "This expression has a type of 'void' so its value can't be used" or "This expression has type 'void' and can't be used".