Closed StachuDotNet closed 2 years ago
That's bad, @StachuDotNet do you, by any chance, have produced assemblies? It seems I can't reproduce it on preview3.
Would be good to know
Does it require optimized or debug code (sounds like debug?)
It does sound like a likely runtime bug, but we need to get to the bottom of it
@vzarytovskii attached is a .zip including the resultant obj
and bin
folders.
Interestingly, I was also failing to reproduce yesterday - dotnet run
somehow ran fine yesterday. I decided to sleep on it and try again today. This morning, the error is back consistently. Mysterious.
@dsyme I'm able to produce this in both debug and release mode.
Okay, I was able to reproduce it locally.
Both Release and Debug, .NET 6.0.200 and .NET 7 preview 3 used:
Target Framework | SDK used to for build | Runtime | Result |
---|---|---|---|
.NET 6 | .NET 6 | .NET 6 | Success |
.NET 6 | .NET 6 | .NET 7 | Success |
.NET 6 | .NET 7 | .NET 6 | Failure (NRE) |
.NET 7 | .NET 7 | .NET 7 | Failure (NRE) |
Codegen: Debug, .NET 6 TFM, .NET 6 SDK, .NET 6 Runtime - Success:
.class /* 02000002 */ public auto ansi abstract sealed Program
extends [System.Runtime]System.Object
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
01 00 07 00 00 00 00 00
)
// Nested Types
.class /* 02000003 */ nested assembly auto ansi sealed serializable beforefieldinit f@6
extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>
{
// Fields
.field /* 04000001 */ public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> condition
// Methods
.method /* 06000005 */ assembly specialname rtspecialname
instance void .ctor (
class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> condition
) cil managed
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
.custom instance void [System.Runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2084
// Header size: 1
// Code size: 14 (0xe)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>::.ctor() /* 0A00000D */
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> Program/f@6::condition /* 04000001 */
IL_000d: ret
} // end of method f@6::.ctor
.method /* 06000006 */ public strict virtual
instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> Invoke (
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> _arg1
) cil managed
{
// Method begins at RVA 0x2094
// Header size: 12
// Code size: 62 (0x3e)
.maxstack 6
.locals /* 11000005 */ init (
[0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>,
[1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>,
[2] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> tail,
[3] int32 head
)
// loop start
// sequence point: hidden
IL_0000: ldarg.1
IL_0001: stloc.0
// sequence point: hidden
IL_0002: ldloc.0
IL_0003: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull() /* 0A000010 */
IL_0008: brfalse.s IL_000c
IL_000a: br.s IL_0012
// sequence point: (line 7, col 13) to (line 7, col 15) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_000c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_Empty() /* 0A000011 */
IL_0011: ret
// sequence point: hidden
IL_0012: ldloc.0
IL_0013: stloc.1
IL_0014: ldloc.1
IL_0015: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull() /* 0A000010 */
IL_001a: stloc.2
IL_001b: ldloc.1
IL_001c: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_HeadOrDefault() /* 0A000012 */
IL_0021: stloc.3
// sequence point: (line 9, col 7) to (line 9, col 32) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0022: nop
// sequence point: hidden
IL_0023: ldarg.0
IL_0024: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> Program/f@6::condition /* 04000001 */
IL_0029: ldloc.3
IL_002a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>::Invoke(!0) /* 0A000013 */
IL_002f: brfalse.s IL_0036
// sequence point: (line 10, col 17) to (line 10, col 23) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0031: ldloc.2
IL_0032: starg.s _arg1
IL_0034: br.s IL_0000
// end loop
// sequence point: (line 11, col 18) to (line 11, col 30) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0036: ldloc.3
IL_0037: ldloc.2
IL_0038: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0>) /* 0A000014 */
IL_003d: ret
} // end of method f@6::Invoke
} // end of class f@6
.class /* 02000004 */ nested assembly auto ansi sealed serializable beforefieldinit functionResult@15
extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>
{
// Fields
.field /* 04000002 */ assembly static initonly class Program/functionResult@15 @_instance
// Methods
.method /* 06000007 */ assembly specialname rtspecialname
instance void .ctor () cil managed
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
.custom instance void [System.Runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x20e0
// Header size: 1
// Code size: 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>::.ctor() /* 0A000015 */
IL_0006: ret
} // end of method functionResult@15::.ctor
.method /* 06000008 */ public strict virtual
instance bool Invoke (
int32 n
) cil managed
{
// Method begins at RVA 0x20e8
// Header size: 1
// Code size: 7 (0x7)
.maxstack 8
// sequence point: (line 15, col 44) to (line 15, col 53) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0000: ldarg.1
IL_0001: call bool Program::condition(int32) /* 06000002 */
IL_0006: ret
} // end of method functionResult@15::Invoke
.method /* 06000009 */ private specialname rtspecialname static
void .cctor () cil managed
{
// Method begins at RVA 0x20f0
// Header size: 12
// Code size: 11 (0xb)
.maxstack 10
IL_0000: newobj instance void Program/functionResult@15::.ctor() /* 06000007 */
IL_0005: stsfld class Program/functionResult@15 Program/functionResult@15::@_instance /* 04000002 */
IL_000a: ret
} // end of method functionResult@15::.cctor
} // end of class functionResult@15
// Methods
.method /* 06000001 */ public specialname static
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> get_list () cil managed
{
// Method begins at RVA 0x2050
// Header size: 1
// Code size: 6 (0x6)
.maxstack 8
IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> '<StartupCode$function-rec-fsharp-dotnet7-bug-demo>.$Program'::list@1 /* 04000003 */
IL_0005: ret
} // end of method Program::get_list
.method /* 06000002 */ public static
bool condition (
int32 n
) cil managed
{
// Method begins at RVA 0x2058
// Header size: 1
// Code size: 5 (0x5)
.maxstack 8
// sequence point: (line 2, col 19) to (line 2, col 24) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0000: ldarg.0
IL_0001: ldc.i4.3
IL_0002: clt
IL_0004: ret
} // end of method Program::condition
.method /* 06000003 */ public static
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> dropWhileWithFunction (
class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> condition,
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> list
) cil managed
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = (
01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00
)
// Method begins at RVA 0x2060
// Header size: 12
// Code size: 15 (0xf)
.maxstack 4
.locals /* 11000002 */ init (
[0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> f
)
// sequence point: hidden
IL_0000: ldarg.0
IL_0001: newobj instance void Program/f@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>) /* 06000005 */
IL_0006: stloc.0
// sequence point: (line 13, col 3) to (line 13, col 9) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0007: ldloc.0
IL_0008: ldarg.1
IL_0009: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>::Invoke(!0) /* 0A00000B */
IL_000e: ret
} // end of method Program::dropWhileWithFunction
.method /* 06000004 */ public specialname static
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> get_functionResult () cil managed
{
// Method begins at RVA 0x207c
// Header size: 1
// Code size: 6 (0x6)
.maxstack 8
IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> '<StartupCode$function-rec-fsharp-dotnet7-bug-demo>.$Program'::functionResult@15 /* 04000004 */
IL_0005: ret
} // end of method Program::get_functionResult
// Properties
.property /* 17000001 */ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> list()
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
01 00 09 00 00 00 00 00
)
.get class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> Program::get_list()
}
.property /* 17000002 */ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> functionResult()
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
01 00 09 00 00 00 00 00
)
.get class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> Program::get_functionResult()
}
} // end of class Program
Debug, .NET 6 TFM, .NET 7 SDK, .NET 6 Runtime - Fails with NRE:
.class /* 02000002 */ public auto ansi abstract sealed Program
extends [System.Runtime]System.Object
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
01 00 07 00 00 00 00 00
)
// Nested Types
.class /* 02000003 */ nested assembly auto ansi sealed serializable beforefieldinit f@6
extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>
{
// Fields
.field /* 04000001 */ public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> condition
.field /* 04000002 */ public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> f
// Methods
.method /* 06000005 */ assembly specialname rtspecialname
instance void .ctor (
class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> condition,
class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> f
) cil managed
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
.custom instance void [System.Runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2084
// Header size: 1
// Code size: 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>::.ctor() /* 0A00000D */
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> Program/f@6::condition /* 04000001 */
IL_000d: ldarg.0
IL_000e: ldarg.2
IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> Program/f@6::f /* 04000002 */
IL_0014: ret
} // end of method f@6::.ctor
.method /* 06000006 */ public strict virtual
instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> Invoke (
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> _arg1
) cil managed
{
// Method begins at RVA 0x209c
// Header size: 12
// Code size: 70 (0x46)
.maxstack 6
.locals /* 11000005 */ init (
[0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>,
[1] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>,
[2] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> tail,
[3] int32 head
)
// sequence point: hidden
IL_0000: ldarg.1
IL_0001: stloc.0
// sequence point: hidden
IL_0002: ldloc.0
IL_0003: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull() /* 0A000010 */
IL_0008: brfalse.s IL_000c
IL_000a: br.s IL_0012
// sequence point: (line 7, col 13) to (line 7, col 15) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_000c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_Empty() /* 0A000011 */
IL_0011: ret
// sequence point: hidden
IL_0012: ldloc.0
IL_0013: stloc.1
IL_0014: ldloc.1
IL_0015: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull() /* 0A000010 */
IL_001a: stloc.2
IL_001b: ldloc.1
IL_001c: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_HeadOrDefault() /* 0A000012 */
IL_0021: stloc.3
// sequence point: (line 9, col 7) to (line 9, col 32) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0022: nop
// sequence point: hidden
IL_0023: ldarg.0
IL_0024: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> Program/f@6::condition /* 04000001 */
IL_0029: ldloc.3
IL_002a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>::Invoke(!0) /* 0A000013 */
IL_002f: brfalse.s IL_003e
// sequence point: (line 10, col 17) to (line 10, col 23) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0031: ldarg.0
IL_0032: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> Program/f@6::f /* 04000002 */
IL_0037: ldloc.2
IL_0038: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>::Invoke(!0) /* 0A00000B */
IL_003d: ret
// sequence point: (line 11, col 18) to (line 11, col 30) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_003e: ldloc.3
IL_003f: ldloc.2
IL_0040: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0>) /* 0A000014 */
IL_0045: ret
} // end of method f@6::Invoke
} // end of class f@6
.class /* 02000004 */ nested assembly auto ansi sealed serializable beforefieldinit functionResult@15
extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>
{
// Fields
.field /* 04000003 */ assembly static initonly class Program/functionResult@15 @_instance
// Methods
.method /* 06000007 */ assembly specialname rtspecialname
instance void .ctor () cil managed
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
.custom instance void [System.Runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x20f0
// Header size: 1
// Code size: 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>::.ctor() /* 0A000015 */
IL_0006: ret
} // end of method functionResult@15::.ctor
.method /* 06000008 */ public strict virtual
instance bool Invoke (
int32 n
) cil managed
{
// Method begins at RVA 0x20f8
// Header size: 1
// Code size: 7 (0x7)
.maxstack 8
IL_0000: ldarg.1
IL_0001: call bool Program::condition(int32) /* 06000002 */
IL_0006: ret
} // end of method functionResult@15::Invoke
.method /* 06000009 */ private specialname rtspecialname static
void .cctor () cil managed
{
// Method begins at RVA 0x2100
// Header size: 12
// Code size: 11 (0xb)
.maxstack 10
IL_0000: newobj instance void Program/functionResult@15::.ctor() /* 06000007 */
IL_0005: stsfld class Program/functionResult@15 Program/functionResult@15::@_instance /* 04000003 */
IL_000a: ret
} // end of method functionResult@15::.cctor
} // end of class functionResult@15
// Methods
.method /* 06000001 */ public specialname static
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> get_list () cil managed
{
// Method begins at RVA 0x2050
// Header size: 1
// Code size: 6 (0x6)
.maxstack 8
IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> '<StartupCode$function-rec-fsharp-dotnet7-bug-demo>.$Program'::list@1 /* 04000004 */
IL_0005: ret
} // end of method Program::get_list
.method /* 06000002 */ public static
bool condition (
int32 n
) cil managed
{
// Method begins at RVA 0x2058
// Header size: 1
// Code size: 5 (0x5)
.maxstack 8
// sequence point: (line 2, col 19) to (line 2, col 24) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0000: ldarg.0
IL_0001: ldc.i4.3
IL_0002: clt
IL_0004: ret
} // end of method Program::condition
.method /* 06000003 */ public static
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> dropWhileWithFunction (
class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> condition,
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> list
) cil managed
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = (
01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00
)
// Method begins at RVA 0x2060
// Header size: 12
// Code size: 16 (0x10)
.maxstack 4
.locals /* 11000002 */ init (
[0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> f
)
// sequence point: (line 6, col 5) to (line 11, col 30) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0000: ldarg.0
IL_0001: ldloc.0
IL_0002: newobj instance void Program/f@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>) /* 06000005 */
IL_0007: stloc.0
// sequence point: (line 13, col 3) to (line 13, col 9) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0008: ldloc.0
IL_0009: ldarg.1
IL_000a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>::Invoke(!0) /* 0A00000B */
IL_000f: ret
} // end of method Program::dropWhileWithFunction
.method /* 06000004 */ public specialname static
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> get_functionResult () cil managed
{
// Method begins at RVA 0x207c
// Header size: 1
// Code size: 6 (0x6)
.maxstack 8
IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> '<StartupCode$function-rec-fsharp-dotnet7-bug-demo>.$Program'::functionResult@15 /* 04000005 */
IL_0005: ret
} // end of method Program::get_functionResult
// Properties
.property /* 17000001 */ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> list()
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
01 00 09 00 00 00 00 00
)
.get class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> Program::get_list()
}
.property /* 17000002 */ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> functionResult()
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
01 00 09 00 00 00 00 00
)
.get class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> Program::get_functionResult()
}
} // end of class Program
Codegen difference:
diff --git "1/.\\net6.codegen" "2/.\\net7.codegen"
index 5d9bede..02d8462 100644
--- "1/.\\net6.codegen"
+++ "2/.\\net7.codegen"
@@ -10,11 +10,13 @@
{
// Fields
.field /* 04000001 */ public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> condition
+ .field /* 04000002 */ public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> f
// Methods
.method /* 06000005 */ assembly specialname rtspecialname
instance void .ctor (
- class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> condition
+ class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> condition,
+ class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> f
) cil managed
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
@@ -25,7 +27,7 @@
)
// Method begins at RVA 0x2084
// Header size: 1
- // Code size: 14 (0xe)
+ // Code size: 21 (0x15)
.maxstack 8
IL_0000: ldarg.0
@@ -33,7 +35,10 @@
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> Program/f@6::condition /* 04000001 */
- IL_000d: ret
+ IL_000d: ldarg.0
+ IL_000e: ldarg.2
+ IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> Program/f@6::f /* 04000002 */
+ IL_0014: ret
} // end of method f@6::.ctor
.method /* 06000006 */ public strict virtual
@@ -41,9 +46,9 @@
class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> _arg1
) cil managed
{
- // Method begins at RVA 0x2094
+ // Method begins at RVA 0x209c
// Header size: 12
- // Code size: 62 (0x3e)
+ // Code size: 70 (0x46)
.maxstack 6
.locals /* 11000005 */ init (
[0] class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>,
@@ -52,50 +57,50 @@
[3] int32 head
)
- // loop start
- // sequence point: hidden
- IL_0000: ldarg.1
- IL_0001: stloc.0
- // sequence point: hidden
- IL_0002: ldloc.0
- IL_0003: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull() /* 0A000010 */
- IL_0008: brfalse.s IL_000c
+ // sequence point: hidden
+ IL_0000: ldarg.1
+ IL_0001: stloc.0
+ // sequence point: hidden
+ IL_0002: ldloc.0
+ IL_0003: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull() /* 0A000010 */
+ IL_0008: brfalse.s IL_000c
- IL_000a: br.s IL_0012
+ IL_000a: br.s IL_0012
- // sequence point: (line 7, col 13) to (line 7, col 15) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
- IL_000c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_Empty() /* 0A000011 */
- IL_0011: ret
+ // sequence point: (line 7, col 13) to (line 7, col 15) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
+ IL_000c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_Empty() /* 0A000011 */
+ IL_0011: ret
- // sequence point: hidden
- IL_0012: ldloc.0
- IL_0013: stloc.1
- IL_0014: ldloc.1
- IL_0015: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull() /* 0A000010 */
- IL_001a: stloc.2
- IL_001b: ldloc.1
- IL_001c: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_HeadOrDefault() /* 0A000012 */
- IL_0021: stloc.3
- // sequence point: (line 9, col 7) to (line 9, col 32) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
- IL_0022: nop
- // sequence point: hidden
- IL_0023: ldarg.0
- IL_0024: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> Program/f@6::condition /* 04000001 */
- IL_0029: ldloc.3
- IL_002a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>::Invoke(!0) /* 0A000013 */
- IL_002f: brfalse.s IL_0036
+ // sequence point: hidden
+ IL_0012: ldloc.0
+ IL_0013: stloc.1
+ IL_0014: ldloc.1
+ IL_0015: call instance class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_TailOrNull() /* 0A000010 */
+ IL_001a: stloc.2
+ IL_001b: ldloc.1
+ IL_001c: call instance !0 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::get_HeadOrDefault() /* 0A000012 */
+ IL_0021: stloc.3
+ // sequence point: (line 9, col 7) to (line 9, col 32) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
+ IL_0022: nop
+ // sequence point: hidden
+ IL_0023: ldarg.0
+ IL_0024: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool> Program/f@6::condition /* 04000001 */
+ IL_0029: ldloc.3
+ IL_002a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>::Invoke(!0) /* 0A000013 */
+ IL_002f: brfalse.s IL_003e
- // sequence point: (line 10, col 17) to (line 10, col 23) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
- IL_0031: ldloc.2
- IL_0032: starg.s _arg1
- IL_0034: br.s IL_0000
- // end loop
-
- // sequence point: (line 11, col 18) to (line 11, col 30) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
- IL_0036: ldloc.3
+ // sequence point: (line 10, col 17) to (line 10, col 23) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
+ IL_0031: ldarg.0
+ IL_0032: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> Program/f@6::f /* 04000002 */
IL_0037: ldloc.2
- IL_0038: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0>) /* 0A000014 */
+ IL_0038: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>::Invoke(!0) /* 0A00000B */
IL_003d: ret
+
+ // sequence point: (line 11, col 18) to (line 11, col 30) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
+ IL_003e: ldloc.3
+ IL_003f: ldloc.2
+ IL_0040: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0> class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>::Cons(!0, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<!0>) /* 0A000014 */
+ IL_0045: ret
} // end of method f@6::Invoke
} // end of class f@6
@@ -104,7 +109,7 @@
extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>
{
// Fields
- .field /* 04000002 */ assembly static initonly class Program/functionResult@15 @_instance
+ .field /* 04000003 */ assembly static initonly class Program/functionResult@15 @_instance
// Methods
.method /* 06000007 */ assembly specialname rtspecialname
@@ -116,7 +121,7 @@
.custom instance void [System.Runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = (
01 00 00 00
)
- // Method begins at RVA 0x20e0
+ // Method begins at RVA 0x20f0
// Header size: 1
// Code size: 7 (0x7)
.maxstack 8
@@ -131,12 +136,11 @@
int32 n
) cil managed
{
- // Method begins at RVA 0x20e8
+ // Method begins at RVA 0x20f8
// Header size: 1
// Code size: 7 (0x7)
.maxstack 8
- // sequence point: (line 15, col 44) to (line 15, col 53) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0000: ldarg.1
IL_0001: call bool Program::condition(int32) /* 06000002 */
IL_0006: ret
@@ -145,13 +149,13 @@
.method /* 06000009 */ private specialname rtspecialname static
void .cctor () cil managed
{
- // Method begins at RVA 0x20f0
+ // Method begins at RVA 0x2100
// Header size: 12
// Code size: 11 (0xb)
.maxstack 10
IL_0000: newobj instance void Program/functionResult@15::.ctor() /* 06000007 */
- IL_0005: stsfld class Program/functionResult@15 Program/functionResult@15::@_instance /* 04000002 */
+ IL_0005: stsfld class Program/functionResult@15 Program/functionResult@15::@_instance /* 04000003 */
IL_000a: ret
} // end of method functionResult@15::.cctor
@@ -167,7 +171,7 @@
// Code size: 6 (0x6)
.maxstack 8
- IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> '<StartupCode$function-rec-fsharp-dotnet7-bug-demo>.$Program'::list@1 /* 04000003 */
+ IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> '<StartupCode$function-rec-fsharp-dotnet7-bug-demo>.$Program'::list@1 /* 04000004 */
IL_0005: ret
} // end of method Program::get_list
@@ -199,21 +203,22 @@
)
// Method begins at RVA 0x2060
// Header size: 12
- // Code size: 15 (0xf)
+ // Code size: 16 (0x10)
.maxstack 4
.locals /* 11000002 */ init (
[0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>> f
)
- // sequence point: hidden
+ // sequence point: (line 6, col 5) to (line 11, col 30) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
IL_0000: ldarg.0
- IL_0001: newobj instance void Program/f@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>) /* 06000005 */
- IL_0006: stloc.0
+ IL_0001: ldloc.0
+ IL_0002: newobj instance void Program/f@6::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32, bool>, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>) /* 06000005 */
+ IL_0007: stloc.0
// sequence point: (line 13, col 3) to (line 13, col 9) in C:\Users\vlza\Downloads\function-rec-bug-report\Program.fs
- IL_0007: ldloc.0
- IL_0008: ldarg.1
- IL_0009: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>::Invoke(!0) /* 0A00000B */
- IL_000e: ret
+ IL_0008: ldloc.0
+ IL_0009: ldarg.1
+ IL_000a: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>, class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32>>::Invoke(!0) /* 0A00000B */
+ IL_000f: ret
} // end of method Program::dropWhileWithFunction
.method /* 06000004 */ public specialname static
@@ -224,7 +229,7 @@
// Code size: 6 (0x6)
.maxstack 8
- IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> '<StartupCode$function-rec-fsharp-dotnet7-bug-demo>.$Program'::functionResult@15 /* 04000004 */
+ IL_0000: ldsfld class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> '<StartupCode$function-rec-fsharp-dotnet7-bug-demo>.$Program'::functionResult@15 /* 04000005 */
IL_0005: ret
} // end of method Program::get_functionResult
@@ -244,4 +249,4 @@
.get class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1<int32> Program::get_functionResult()
}
-} // end of class Program
\ No newline at end of file
+} // end of class Program
I'm able to reproduce it on 6.0.300-preview.22154.4 too. There is an IL diff between stable and preview versions: stable (6.0.104) : both functions have effectively identical il https://www.diffchecker.com/Av9sdqwx
preview: IL of "function" is very different. It is on the left.
It seems that compiler is now trying to make "f" an object instead of function.
So it tries to get "f" from field which is somehow null and fails on "f tail" call. You can check that by printfn ReferenceEquals(f, null) before the call.
Funnily, removing type annotation from "let rec f : List
Side note: I wonder why compiler doesn't emit a warning when rec function results in closure instead of a while loop. I would really like to see a warning. Some things are really better expressed as rec's but it's always a manual check that assures, not compiler.
https://www.diffchecker.com/eAcGUo5B
Oh, @vzarytovskii was faster than me :)
Huh, it seems that we've introduced some bug in codegen somewhere between 6.0.200 and 6.0.300 (17.1 and 17.2 ?).
@vzarytovskii We have to get a fix in the works for this.
I think part of the problem may be that the use of function ...
is locating an Expr.DebugPoint
differently and resulting in a different arity analysis for the inner let rec f ...
. However the NRE should not be happening even if that's the case.
@vzarytovskii We have to get a fix in the works for this.
I think part of the problem may be that the use of
function ...
is locating anExpr.DebugPoint
differently and resulting in a different arity analysis for the innerlet rec f ...
. However the NRE should not be happening even if that's the case.
Shall we skip emitting sequence point before lambdas altogether? Only on args?
@vzarytovskii , we probably need to evaluate the debugging experience more deeply, before we do that. This change, makes no difference in the debugging as far as I can tell.
Using
function
within a recursive function iterating over a list results in a null reference exception when matching against the empty list[]
.Repro steps
A sample repo has been made: https://github.com/StachuDotNet/function-rec-fsharp-dotnet7-bug-demo/blob/main/Program.fs
The sample repo includes a devcontainer set up for simple testing - just
dotnet run
.Related information
Provide any related information (optional):
I suspect this issue will be eventually closed in favor of a
runtime
issue, but know too little to report there appropriately.