SwensenSoftware/unquote

NotSupportedException in eval

marklam opened this issue · 3 comments

The following test throws a NotSupportedException

let inline sq x = 
    x * x

let inline fsq x =
    sq (float x)

[<Test>]
let ``fsq converts the argument to float and then squares it`` () =
    test <@ fsq 25uy = 625.0 @>

produces

TestMath.fsq 25uy = 625.0
System.NotSupportedException: Specified method is not supported.
   at TestMath.fsq[a](a x) 
   at Swensen.Unquote.Evaluation.eval(FSharpList`1 env, FSharpExpr expr)
   at Swensen.Unquote.Reduction.reduce(FSharpList`1 env, FSharpExpr expr)
   at Microsoft.FSharp.Primitives.Basics.List.map[T,TResult](FSharpFunc`2 mapping, FSharpList`1 x)
   at Swensen.Unquote.Reduction.reduce(FSharpList`1 env, FSharpExpr expr)
   at Swensen.Unquote.Reduction.loop@126(FSharpList`1 env, FSharpExpr expr, FSharpList`1 acc)```

Thanks for reporting @marklam - I was able to reproduce and am digging deeper into it.

@marklam turns out this is a limitation of certain inline functions (with statically resolved type parameters) not being dynamically invokable (in this case the float function is the culprit). Since Unquote evaluation is based on reflection, I don't think it can be overcome. See https://stackoverflow.com/a/40853727/236255 for a little more insight.

You can, of course, avoid this issue by evaluating fsq 25uy outside of a quotation:

let actual = fsq 25uy
test <@ actual = 625.0 @>

Thanks for taking the time to look into it.
I was particularly interested in evaluating inline functions in the quotation to get coverage tools to mark inlined functions' definitions as covered, but I guess that won't work for SRTP functions.