From b8c983e91b5a073675c5e61ec7bc2a88679aa9ad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 19 Apr 2026 13:11:38 +0000 Subject: [PATCH] Add regression test for #3783: Mutually recursive computation expression NullReferenceException Test both function-scoped and type-constructor-scoped variants of mutually recursive sequence expressions to verify the NullReferenceException no longer occurs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ComputationExpressions.fs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ComputationExpressions/ComputationExpressions.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ComputationExpressions/ComputationExpressions.fs index 1aec462abf9..087370134d7 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ComputationExpressions/ComputationExpressions.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ComputationExpressions/ComputationExpressions.fs @@ -321,3 +321,46 @@ module LetUseBangTests = (Error 748, Line 4, Col 13, Line 4, Col 20, "This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'.") ] + +// https://github.com/dotnet/fsharp/issues/3783 +[] +let ``Issue 3783 - Mutually recursive computation expression should not raise NullReferenceException`` () = + FSharp """ +#nowarn "40" +#nowarn "21" + +let x () = + let rec a = seq { + yield 0 + yield! b () } + and b () = seq { + yield 1 + yield! a } + Seq.take 10 a |> Seq.toList + +type A () = + let test = + let rec a = seq { + yield 0 + yield! b () } + and b () = seq { + yield 1 + yield! a } + Seq.take 10 a |> Seq.toList + member _.Test = test + +[] +let main _ = + let result1 = x () + if result1 <> [0; 1; 0; 1; 0; 1; 0; 1; 0; 1] then + failwithf "Function variant failed: %A" result1 + + let a = A() + if a.Test <> [0; 1; 0; 1; 0; 1; 0; 1; 0; 1] then + failwithf "Type constructor variant failed: %A" a.Test + + 0 + """ + |> asExe + |> compileExeAndRun + |> shouldSucceed