Improve warning diagnostics on computed list expressions that do not yield anything or yield unit values
This is related to a gotcha related to the introduction of implicit yields into F#, https://github.com/fsharp/fslang-design/blob/main/FSharp-4.7/FS-1069-implicit-yields.md
When yields are implicit, in some cases expressions in computed list expressions can be given "statement" interpretation instead of "yield" interpretation, giving rise to computed list expressions that yield nothing.
Any useful code that does this will almost always give a later type checking error. However that error can be hard to understand.
For example, consider this code, transforming a tree labelled with integers to a tree labelled with strings:
type Tree1 = Node1 of int * Tree1 list
type Tree2 = Node2 of string * Tree2 list
let rec generateThing (Node1 (n, children)) =
let things =
[ for child in children do
generateThing child ]
Node2 (string n, things)
Here the call to generateThing in the definition of things is given statement interpretation because its return type unifies with unit, and an error is reported at the end of the function.
It would be better if we gave a warning or error in the computed list expression, e.g. any of these (the warning text can be improved)
-
Over range
generateThing child- "The expression "generateThing child" is being interpreted as a statement and will not yield any results. Consider making yields explicit in this list expression. -
Over range
[ for child in children do generateThing child ]. "This list expression doesn't yield any results. Consider making yields explicit in this list expression"
Also, we should consider giving warnings on any use of implicit yields that generate lists of type "unit list", see https://github.com/fsharp/fslang-design/blob/main/FSharp-4.7/FS-1069-implicit-yields.md#interaction-with-generating-unit-values