fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

LINQ producing incorrect runtime result with boxed ValueOptions

Open Thorium opened this issue 2 years ago • 1 comments

You cannot compare value-options directly due to #13370 Boxing them causes the LINQ compiles but does incorrect runtime result:

Repro steps, actual behaviour

let datasource1 = [1; 2].AsQueryable() // primary key
let datasource2 = [ValueSome 1; ValueSome 2].AsQueryable() //foreign key
query { 
   for d1 in datasource1 do
   for d2 in datasource2 do
   where (box(ValueSome(d1)) = box(d2))
   select (d1, d2)
} |> Seq.toList;;
// val it: (int * int voption) list = []
// Empty???

The same issue can be observed with Some:

let datasource1 = [1; 2].AsQueryable() // primary key
let datasource2 = [ValueSome 1; ValueSome 2].AsQueryable() //foreign key
query { 
   for d1 in datasource1 do
   for d2 in datasource2 do
   where (Some(ValueSome(d1)) = Some(d2))
   select (d1, d2)
} |> Seq.toList;;
// val it: (int * int voption) list = []
// Empty???

Expected behavior

If I change the = to Equals, then it produces a different result:

open System.Linq
let datasource1 = [1; 2].AsQueryable() // primary key
let datasource2 = [ValueSome 1; ValueSome 2].AsQueryable() //foreign key
query { 
   for d1 in datasource1 do
   for d2 in datasource2 do
   where (ValueSome(d1).Equals(d2))
   select (d1, d2)
} |> Seq.toList;;
// val it: (int * int voption) list = [(1, ValueSome 1); (2, ValueSome 2)]

Or with boxed:

open System.Linq
let datasource1 = [1; 2].AsQueryable() // primary key
let datasource2 = [ValueSome 1; ValueSome 2].AsQueryable() //foreign key
query { 
   for d1 in datasource1 do
   for d2 in datasource2 do
   where (box(ValueSome(d1)).Equals(box(d2)))
   select (d1, d2)
} |> Seq.toList;;

I expect this will do a method-call instead of Expression.Equals in the LINQ-tree. Which may cause the sub-expressions not visited by LINQ for any kind of transpilation, and that's why this is not a workaround. Is there maybe something wrong with StructuralComparison when using Linq?

Known workarounds

None.

Related information

Environment tested with:

  • Operating system Win 11
  • .NET Runtime kind (.NET Core, .NET Framework, Mono) 6.0.301
  • F# 6.0.5
  • Editing Tools: Visual Studio 2022

Thorium avatar Jul 12 '22 10:07 Thorium

I think this is fixed by https://github.com/dotnet/fsharp/pull/11681

Happypig375 avatar Jul 12 '22 13:07 Happypig375

This is indeed fixed by #11681

dsyme avatar Sep 21 '22 14:09 dsyme