-
Notifications
You must be signed in to change notification settings - Fork 831
Description
Description
When using --langversion:5.0 (the default in F# 5.0), taking the quotation of a use of List.sum on a non-primitive type causes a compilation exception related to generating the witness for the Zero property.
This will apply to a quotation of any code calling let inline SRTP code which uses a constraint on a get_Foo property method or any SRTP constraint that takes no arguments member M : unit -> ...
Repro
type Point =
{ x: int; y: int }
static member Zero = { x=0; y=0 }
static member (+) (p1, p2) = { x= p1.x + p2.x; y = p1.y + p2.y }
let p1 = {x=1; y=10}
<@ List.sum [p1] @>gives
stdin(0,1): error FS0073: internal error: The lists had different lengths.
list2 is 1 element shorter than list1
Parameter name: list2 (ArgumentException)
Stack Trace
FSharp.Compiler.ErrorLogger+InternalError: The lists had different lengths.
list2 is 1 element shorter than list1
Parameter name: list2 (ArgumentException)stdin (0,0--0,0) IsSynthetic=false
Another repro is
#r "System.Numerics.Vectors.dll";;
<@ List.sum [System.Numerics.Vector4.Zero] @>;;Workarounds
One workaround is to use --langversion:4.7
Another possible workaround is to define a non-inlined helper function outside the quotation, e.g. as follows. If necessary label the function as ReflectedDefinition. This may not work if the quotation is being processed requires access to the full quotation tree.
type Point =
{ x: int; y: int }
static member Zero = { x=0; y=0 }
static member (+) (p1, p2) = { x= p1.x + p2.x; y = p1.y + p2.y }
let p1 = {x=1; y=10}
let sumPoints (points: Point list) = List.sum points
<@ sumPoints [p1] @>Severity
This bug has not yet been seen in actual user code, but was instead noticed as part of #9510, which applies witness generation to a much broader range of code (all code going through Fable).
However it's likely to affect some user code.
Since a workaround is to use --langversion:4.7 it is likely that the actual severity in practice will be low.