Improve error message when need to annotate all record fields
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 144
Description
I just got a report in https://github.com/fsharp/FAKE/issues/2080
And I felt like there might be a issue for newcomers here, so I'd like to report this as bug here as I'd like to see the error message improved if possible.
Consider code like:
```fsharp
namespace Test1
type MyRecord =
{ Label1 : string
Label2 : string }
namespace Test2
module Program =
[]
let main argv =
ignore (fun _ ->
{
Test1.Label1 = ""
Label2 = ""
}
()
)
0
```
I guess most people expect this code to compile with a warning, but instead it doesn't compile and complain about `Label2`:

I guess this is especially confusing if the label-name is a wide-spread identifier.
I'd assume there is enough information for the compiler to figure out what `Label2` means. In fact I think the confusion did occur because FAKE documentation only shows the following usage (which works):
```fsharp
namespace Test1
type MyRecord =
{ Label1 : string
Label2 : string }
module M =
let f (i:MyRecord) = ()
namespace Test2
module Program =
[]
let main argv =
ignore (fun _ ->
Test1.M.f
{ Label1 = ""
Label2 = "" }
()
)
0
```
So this is a pitfall for newcomers.
#### Spec
Relevant seem to be:
- 6.3.5 Record Expressions
- 14.1 Name Resolution
Which specifies that that the compiler should emit an error.
#### Expected behavior
As the error is according to spec. I'd suggest to improve the error message. My suggestion would be (in this particular scenario where one label is fully referenced):
`the record label 'Label2' is not defined. Either reference all labels with a long identifier 'Test1.MyRecord.Label2' or add a type annotation '({ ... } : Test1.MyRecord)'.`
If someone things this should compile, please feel free to open a language suggestion in a addition to this issue.
#### Actual behavior
See above.
#### Known workarounds
In order to not annotate all fields:
```fsharp
namespace Test1
type MyRecord =
{ Label1 : string
Label2 : string }
namespace Test2
module Program =
[]
let main argv =
ignore (fun _ ->
({ Label1 = ""
Label2 = "" } : Test1.MyRecord)
()
)
0
```
Contributor guide
Assessment
This issue has not been assessed yet.