Skip to content

Conversation

Copy link

Copilot AI commented Jan 26, 2026

Using Implies with Replay threw NullReferenceException when the condition evaluated to false, as Replay mode produces single-element sequences that exposed a bug in takeWhilePlusLast.

Root Cause

takeWhilePlusLast had independent conditionals for MoveNext() and the predicate check:

if en.MoveNext() then
    yield en.Current
if predicate en.Current then  // ❌ executes even when MoveNext() = false
    yield! loop en

After the sequence exhausts, MoveNext() returns false, but the code still evaluates predicate en.Current, accessing the enumerator in an undefined state.

Changes

  • Internals.Common.fs: Nested predicate check inside MoveNext() conditional to ensure en.Current is only accessed when valid
  • Runner.fs: Moved OnArguments invocation into Passed/Failed branches (rejected tests have no meaningful arguments to report)
  • PropertyExamples.fs: Added regression test for Implies with Replay

The bug manifested specifically with Replay because it forces single-test execution, guaranteeing the sequence exhausts on the first iteration.

Original prompt

This section details on the original issue you should resolve

<issue_title>Implies leads to target invokation exception</issue_title>
<issue_description>Hi, i think there is a problem with Implies method.

When used together with the Replay functionality A.Implies(B) leads to a TargetInvokationException if A is false.

Steps to reproduce:

  • Create an NUnit Test Project
  • Create a Property:
   [Property(Replay="(123, 127, 123")]
   public Property MinimalExampleProperty1()
   {
       return false.Implies(true);
   }

System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
----> System.NullReferenceException : Object reference not set to an instance of an object.
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span1 copyOfArgs, BindingFlags invokeAttr) at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) at FsCheck.Runner.checkMethod(Config config, MethodInfo m, FSharpOption1 target) in C:\Users\kurts\Projects\FsCheck\src\FsCheck\Runner.fs:line 600
at FsCheck.Check.Method(Config config, MethodInfo methodInfo, FSharpOption1 target) in C:\Users\kurts\Projects\FsCheck\src\FsCheck\Runner.fs:line 673 at FsCheck.NUnit.FsCheckTestMethod.RunTestMethod(TestExecutionContext context, TestResult testResult) in C:\Users\kurts\Projects\FsCheck\src\FsCheck.NUnit\FsCheckPropertyAttribute.fs:line 275 at FsCheck.NUnit.FsCheckTestMethod.RunTestCase(TestExecutionContext context, TestResult testResult) in C:\Users\kurts\Projects\FsCheck\src\FsCheck.NUnit\FsCheckPropertyAttribute.fs:line 229 --NullReferenceException at FsCheck.Runner.runner@432-1.Invoke(TestStep step) in C:\Users\kurts\Projects\FsCheck\src\FsCheck\Runner.fs:line 433 at FsCheck.Internals.Common.loop@51-1.GenerateNext(IEnumerable1& next) in C:\Users\kurts\Projects\FsCheck\src\FsCheck\Internals.Common.fs:line 54
at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.MoveNextImpl() in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\seqcore.fs:line 368 at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.System.Collections.IEnumerator.MoveNext() in D:\workspace_work\1\s\src\fsharp\FSharp.Core\seqcore.fs:line 400
at FsCheck.Internals.Common.takeWhilePlusLast@59.GenerateNext(IEnumerable1& next) in C:\Users\kurts\Projects\FsCheck\src\FsCheck\Internals.Common.fs:line 60 at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.MoveNextImpl() in D:\workspace_work\1\s\src\fsharp\FSharp.Core\seqcore.fs:line 368
at Microsoft.FSharp.Core.CompilerServices.GeneratedSequenceBase1.System.Collections.IEnumerator.MoveNext() in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\seqcore.fs:line 400 at Microsoft.FSharp.Collections.SeqModule.Fold[T,TState](FSharpFunc2 folder, TState state, IEnumerable1 source) in D:\workspace\_work\1\s\src\fsharp\FSharp.Core\seq.fs:line 730 at FsCheck.Runner.runner[a](Config config, a prop) in C:\Users\kurts\Projects\FsCheck\src\FsCheck\Runner.fs:line 415 at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor) at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span1 copyOfArgs, BindingFlags invokeAttr)


One or more child tests had errors
Exception doesn't have a stacktrace

I have also created a minimal example

https://github.com/marha333/FsCheckTests

Any Help is appreciated,

Kind Regards

Harry

</issue_description>

<agent_instructions>Add a repro of this issue to FsCheck.NUnit, debug and fix it.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…th Replay

Co-authored-by: kurtschelfthout <164917+kurtschelfthout@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix TargetInvocationException in Implies method Fix NullReferenceException in takeWhilePlusLast with single-element sequences Jan 26, 2026
Copilot AI requested a review from kurtschelfthout January 26, 2026 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implies leads to target invokation exception

2 participants