Structs referenced from other projects have a significant optimisation failure whereby an instance of the struct cannot be passed to functions - it is always re-instantiated to empty just before the function call.
Repro steps
Imagine you have the following C# project with a single file:
namespace ClassLibrary1
{
public struct SomeStruct
{
private string _value;
public string Value => _value;
public void Set(string value)
{
_value = value;
}
}
}
The above project is referenced from F#:
open ClassLibrary1
let someFunc (s : SomeStruct) =
printfn "From inner: %A" s.Value
[<EntryPoint>]
let main argv =
let s = SomeStruct()
s.Set("there")
printfn "Pre call: %A" s.Value
someFunc s
printfn "Post call: %A" s.Value
0
Expected behavior
Output of the program is:
Pre call: "there"
From inner: "there"
Post call: "there"
Actual behavior
With optimisations enabled (e.g. Release mode), the output is:
Pre call: "there"
From inner: <null>
Post call: "there"
Known workarounds
No known workaround.
Related information
Severe bug, stopping me from using a C# library that uses structs.
The IL for the main function looks like:
.method public static int32 main(string[] argv) cil managed
{
.entrypoint
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.EntryPointAttribute::.ctor() = ( 01 00 00 00 )
// Code size 40 (0x28)
.maxstack 4
.locals init ([0] valuetype [ClassLibrary1]ClassLibrary1.SomeStruct s,
[1] valuetype [ClassLibrary1]ClassLibrary1.SomeStruct V_1)
IL_0000: nop
IL_0001: ldloca.s V_1
IL_0003: initobj [ClassLibrary1]ClassLibrary1.SomeStruct
IL_0009: ldloc.1
IL_000a: stloc.0
IL_000b: ldloca.s s
IL_000d: ldstr "there"
IL_0012: call instance void [ClassLibrary1]ClassLibrary1.SomeStruct::Set(string)
IL_0017: ldloca.s V_1 // WHY IS THIS HERE?
IL_0019: initobj [ClassLibrary1]ClassLibrary1.SomeStruct // WHY IS THIS HERE?
IL_001f: ldloc.1
IL_0020: call void Program::someFunc(valuetype [ClassLibrary1]ClassLibrary1.SomeStruct)
IL_0025: nop
IL_0026: ldc.i4.0
IL_0027: ret
} // end of method Program::main
IL_0017 and IL_0019 have been added by the optimiser - in Debug mode these instructions are not here, and the bad behaviour is not present.
Thanks
Structs referenced from other projects have a significant optimisation failure whereby an instance of the struct cannot be passed to functions - it is always re-instantiated to empty just before the function call.
Repro steps
Imagine you have the following C# project with a single file:
The above project is referenced from F#:
Expected behavior
Output of the program is:
Actual behavior
With optimisations enabled (e.g. Release mode), the output is:
Known workarounds
No known workaround.
Related information
Severe bug, stopping me from using a C# library that uses structs.
The IL for the main function looks like:
IL_0017 and IL_0019 have been added by the optimiser - in Debug mode these instructions are not here, and the bad behaviour is not present.
Thanks