It appears roslyn is able to determine when different methods would have identical IL bodies, and just emit one IL stream for the methods. This breaks the recursion detection done in the jit, which relies on the IL address.
Here after inlining A into B, the call to C looks like a recursive call, and so we block inlining:
usingSystem;classX{intA()=>C();intB()=>A();intC()=>A();}Inlinesinto06000002[viaExtendedDefaultPolicy]X:B():int:this[1IL=0001TR=00000106000001][belowALWAYS_INLINE size]X:A():int:this[0IL=0001TR=00000406000003][FAILED:recursive]X:C():int:thiscategory:correctness
theme:inlining
skill-level:intermediate
cost:medium
impact:small
It appears roslyn is able to determine when different methods would have identical IL bodies, and just emit one IL stream for the methods. This breaks the recursion detection done in the jit, which relies on the IL address.
Here after inlining A into B, the call to C looks like a recursive call, and so we block inlining:
category:correctness
theme:inlining
skill-level:intermediate
cost:medium
impact:small