Description
Please provide a succinct description of the issue.
When using applicatives CE (let! and!) with 6 or more bindings, the code generated fails one compiled with AOT. Everything is fine with 5 bindings or less.
Provide the steps required to reproduce the problem:
Implement a Computation Expression with applicative and use it with 6 or more bindings:
type Identity<'t> = Identity of 't
let ret x = Identity x
let map f (Identity x) = Identity (f x)
let map2 f (Identity x) (Identity y) = Identity(f x y)
type IdentityBuilder() =
member _.Return(x) = ret x
member _.BindReturn(x, f) = map f x
member _.MergeSources(x,y) = map2 (fun a b -> a,b) x y
let ident = IdentityBuilder()
[<EntryPoint>]
let main (args: string[]) =
let (Identity(a,b,c,d,e,f)) =
ident {
let! a = ret "a"
and! b = ret "b"
and! c = ret "c"
and! d = ret "d"
and! e = ret "e"
and! f = ret "f"
return a,b,c,d,e,f
}
printfn $"{a}{b}{c}{d}{e}{f}"
0
Here this is a simple Identity functor implementing map2
.
Compile it with AOT:
dotnet publish -c Release -p:SelfContained=true -p:PublishAot=true -o .\dist\
And run it. It fails:
Unhandled Exception: System.TypeLoadException: Attempted to load a type that was not created during ahead of time compilation.
at Internal.Runtime.CompilerHelpers.ThrowHelpers.ThrowUnavailableType() + 0x33
at Microsoft.FSharp.Core.FSharpFunc`2.InvokeFast[V](FSharpFunc`2, T, TResult) + 0x1a
at Program.main(String[]) + 0x227
at tstconsole!<BaseAddress>+0x1c779b
Expected behavior
The application should print "abcdef".
Actual behavior
The application fails at runtime with a TypeLoadException
.
Known workarounds
It is possible to workaround by splitting the bindings in smaller chunks:
let (Identity(a,b,c,d,e,f)) =
ident {
let! a = ret "a"
and! b = ret "b"
and! c = ret "c"
and! (d,e,f) =
ident {
let! d = ret "d"
and! e = ret "e"
and! f = ret "f"
return d,e,f
}
return a,b,c,d,e,f
}
Related information
I discovered this while working on an applicative command line argument parser that is not using reflection to make it work nicely with AOT. However, this bug - while having a workaround - makes it likely to break weirdly when the code is modified.
The way CE works should not produce dynamically loaded types that are not compatible with AOT.
- Operating system: Windows / Linux
- .NET Runtime kind: net6.0+
- Editing Tools: VS / VSCode
Metadata
Metadata
Assignees
Labels
Type
Projects
Status