dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.94k stars 788 forks source link

Copy and update record expression doesn't compile when the record comes from a function #18062

Open mlaily opened 2 days ago

mlaily commented 2 days ago

In some cases, I can't use the with keyword to copy and update a record with the F# 7 nested records shortcut syntax, when the source record comes from a function call (but in some situations it compiles fine).

It seems the compiler gets somehow confused... (?)

Repro steps

The following code doesn't compile:

type MyCustomer =
    { FirstName: string
      LastName: string
      Comment: string option }

type MyBooking =
    { Reference: string
      Customer: MyCustomer }

type MyParentObject = { Booking: MyBooking }

module MyParentObject =
    let Sample =
        { Booking =
            { Reference = "reference"
              Customer =
                { FirstName = "firstname"
                  LastName = "lastname"
                  Comment = Some "comment" } } }

let okTest =
    let value = MyParentObject.Sample

    { value with
        MyParentObject.Booking.Customer.Comment = None }

let failingTest =
    let func () = MyParentObject.Sample

    { func () with
        MyParentObject.Booking.Customer.Comment = None }

More precisely, the okTest compiles ok, but the failingTest does not.

Expected behavior

I would expect the failingTest to work.

Related information

Provide any related information (optional):

I'm using Visual Studio 17.12 on Windows, with .NET 9 installed.

I reproduced the issue when targeting .NET 8 and .NET 6 too, and also from VS Code.


Did I stumble on a real issue, or am I misunderstanding something?

T-Gro commented 1 day ago

It is a real issue. The compiler has a bug and mismatches the types on the cascade of nesting. Even when you try to eliminate access path from the left, it always comes with a different error message instead.

Also, in this case, even putting parens arond the "func()" invocation does not help.

When reducing this down to a smallest repro, this only appears when having a 3 or mor records. When reducing the sample down to 2 records only, the nested syntax works without issues even with function invocation.

https://sharplab.io/#v2:DYLgZgzgNALiCGEC2AfA9gBwKYDsAEAygJ4QxZICwAUNdTEdngJI45YBOeAvHgN4AaIAJY4YAXzoMseALJCAJvODSevJiBZt2EqvUYB5AK5lOqmSDmLlO6spiF4SDMu58ZrtR/6uArGP+2WPYA5kEEjs5YABQAlK7hTsq0VHZ4aADWACpYpB4JkXgA7kIwABayAHRMFd48ACwATDqp8MAQaPoA0q7UeH14qWCGOADGsfERyhUyvf28Q6N448VlzDWudQDMYn2zuylBeGDwQsAiwdm5PHsDhwsjS3E8+UlU/Xz3j0Ul5TJV6/Vtu8gA==