Open thinkbeforecoding opened 1 year ago
I tried building this with all the trim analysis warnings enabled, and got some warnings like this:
ILC : AOT analysis warning IL3054: Microsoft.FSharp.Core.FSharpFunc`2<String,String>.InvokeFast<Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<S
tring,String,String>>>>,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,String>>>>>>(FSharpFunc`2<String,FSha
rpFunc`2<String,FSharpFunc`2<Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,String>>>>,Tuple`3<String,String,Tuple`3<String,String
,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,String>>>>>>>>,String,String,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<S
tring,String,String>>>>): Generic expansion to 'Microsoft.FSharp.Core.OptimizedClosures.FSharpFunc`4<String,String,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<Stri
ng,String,Tuple`3<String,String,String>>>>,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,Tuple`3<String,String,String>>>>>>' was
aborted due to generic recursion. An exception will be thrown at runtime if this codepath is ever reached. Generic recursion also negatively affects compilation speed and
the size of the compilation output. It is advisable to remove the source of the generic recursion by restructuring the program around the source of recursion. The source o
f generic recursion might include: 'Microsoft.FSharp.Core.FSharpFunc`2', '<StartupCode$FSharp-Core>.$Prim-types.op_Implicit@3875', '<StartupCode$FSharp-Core>.$Prim-types.o
p_Implicit@3880-1', '<StartupCode$FSharp-Core>.$Prim-types.op_Implicit@3883-2', '<StartupCode$FSharp-Core>.$Prim-types.op_Implicit@3886-3', '<StartupCode$FSharp-Core>.$Pri
m-types.FromConverter@3889', '<StartupCode$FSharp-Core>.$Prim-types.ToConverter@3892', 'Microsoft.FSharp.Core.OptimizedClosures.FSharpFunc`3', 'Microsoft.FSharp.Core.Optim
izedClosures.FSharpFunc`4', 'Microsoft.FSharp.Core.OptimizedClosures.FSharpFunc`5', 'Microsoft.FSharp.Core.OptimizedClosures.FSharpFunc`6', 'Microsoft.FSharp.Core.Optimize
dClosures.Invoke@3756', 'Microsoft.FSharp.Core.OptimizedClosures.Adapt@3763', 'Microsoft.FSharp.Core.OptimizedClosures.Invoke@3770-1', 'Microsoft.FSharp.Core.OptimizedClos
ures.Adapt@3779-1', 'Microsoft.FSharp.Core.OptimizedClosures.Adapt@3783-2', 'Microsoft.FSharp.Core.OptimizedClosures.Adapt@3797-3', 'Microsoft.FSharp.Core.OptimizedClosure
s.Adapt@3802-4', 'Microsoft.FSharp.Core.OptimizedClosures.Adapt@3806-5', 'Microsoft.FSharp.Core.OptimizedClosures.Invoke@3809-2', 'Microsoft.FSharp.Core.OptimizedClosures.
Invoke@3817-3', 'Microsoft.FSharp.Core.OptimizedClosures.Adapt@3827-6', 'Microsoft.FSharp.Core.OptimizedClosures.Adapt@3832-7', 'Microsoft.FSharp.Core.OptimizedClosures.Ad
apt@3837-8', 'Microsoft.FSharp.Core.OptimizedClosures.Adapt@3841-9' [S:\DevTest\ce_test\ce_test.fsproj]
Which makes it sound like the issue is that there are too many layers of nested tuples and the AOT compiler is giving up?
A quick test makes it seem like the issue can be alleviated to a degree by implementing MergeSourcesN
- e.g. if I add an implementation of MergeSources3
to IdentityBuilder
the it works with 10 bindings and fails with 11.
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:
Here this is a simple Identity functor implementing
map2
.Compile it with AOT:
And run it. It fails:
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:
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.