Add warning when compiler selects among multiple record type candidates
Supply a new warning when the compiler selects between multiple candidates during resolution.
F# has several good ways to control resolution: open statements, type annotations, etc. It also has clear rules on how resolution is done. But there is no feedback at the point of ambiguity that the compiler is making a choice. This can be set to "Informational" by default for backward compatibility. Some users may choose to set it to error and use this to force disambiguation via qualification or other means.
Motivation
This is one example of how this can manifest:
module Module1
type OtherThing =
{ Name: string }
module Module2
type Person =
{ Name: string
City: string }
open Module2
open Module1
let F thing =
let x = thing.Name
// Many lines of code
thing.City // Error occurs here
Since Person and OtherThings both have a Name field, the order of open statements in the calling determines how Name is resolved. Since the error occurs where the variable is used (when thing.City is called), a naïve user is likey to look for the problem near that line.
Assuming the compiler knows it is selecting from multiple items when it resolved thing, it would be desirable to have an warning at that location (when x is set and thing is resolved) that indicates that a selection was made, hopefully listing candidates. A message might be
Multiple type matches were found:
Module1.OtherThing
Module2.Person
The type Module1.OtherThing was used.
I think this makes a lot of sense (asking user to notice/remove ambiguity), it may also apply to the way DU members can shadow each others (where the error message could also be enhanced in similar fashion as this proposal).
We should precise what the suggestion ends up applying to (records and DU are the one I know are relevant); it shouldn't apply to things that can gracefully coallesce, for example, modules and types having same name and probably few other things.
Related: https://github.com/fsharp/fslang-suggestions/issues/1074 and https://github.com/fsharp/fslang-suggestions/issues/907
@dsyme @KathleenDollard I think we should consider all three of these (even if they just get done piecemeal)
@cartermp this one is related as well, I think: https://github.com/fsharp/fslang-suggestions/issues/1090
These all seem to be dancing around ways to make the user choose a name, but the user may not be aware of where the choices are being made.
Sorta related: add warning when compiler infers obj automatically for generic function call.
let getSomethingFromDatabase<'a> query = ...
let sendSomethingOverHttp value = ...
let value = getSomethingFromDatabase blabla // obj is inferred
sendSomethingOverHttp value // potentially a bug
Sometimes you forget to add type annotations which can result in runtime exceptions or unintended behaviour. I think such a warning is related to this one too.
Also, IDisposable/IAsyncDisposable in computation expressions.