Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// #Conformance #ControlFlow #Sequences #Regression #InterfacesAndImplementations
// Ensure generic IEnumerable iteration calls GetEnumerator and disposes enumerators via try/finally.

open System
open System.Collections
open System.Collections.Generic

type CountingEnumerable(values: int[]) =
static let mutable getEnumeratorCalls = 0
static let mutable disposeCalls = 0

static member Reset() =
getEnumeratorCalls <- 0
disposeCalls <- 0

static member GetEnumeratorCalls = getEnumeratorCalls
static member DisposeCalls = disposeCalls

interface IEnumerable<int> with
member _.GetEnumerator() =
getEnumeratorCalls <- getEnumeratorCalls + 1
let mutable i = -1

{ new IEnumerator<int> with
member _.Current = values[i]

interface IEnumerator with
member _.Current = box values[i]
member _.MoveNext() =
i <- i + 1
i < values.Length
member _.Reset() = i <- -1

interface IDisposable with
member _.Dispose() = disposeCalls <- disposeCalls + 1 }

interface IEnumerable with
member this.GetEnumerator() =
(this :> IEnumerable<int>).GetEnumerator() :> IEnumerator

let runSuccessfulIteration () =
CountingEnumerable.Reset()

let enumerable = CountingEnumerable([| 1; 2; 3 |]) :> IEnumerable<int>
let mutable sum = 0

for x in enumerable do
sum <- sum + x

sum = 6
&& CountingEnumerable.GetEnumeratorCalls = 1
&& CountingEnumerable.DisposeCalls = 1

let runExceptionalIteration () =
CountingEnumerable.Reset()

let enumerable = CountingEnumerable([| 1; 2; 3 |]) :> IEnumerable<int>

try
for x in enumerable do
if x = 2 then
failwith "boom"
with _ ->
()

CountingEnumerable.GetEnumeratorCalls = 1
&& CountingEnumerable.DisposeCalls = 1

let ok = runSuccessfulIteration () && runExceptionalIteration ()
exit (if ok then 0 else 1)
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,37 @@ open FSharp.Test.Compiler
module SequenceIteration =

// This test was automatically generated (moved from FSharpQA suite - Conformance/Expressions/ControlFlowExpressions/SequenceIteration)


let verifyCompileAndRun compilation =
compilation
|> asExe
|> withOptions ["--nowarn:3370"]
|> compileExeAndRun

[<Theory; FileInlineData("IEnumerableIteration01.fs")>]
let ``IEnumerableIteration01_fs`` compilation =
compilation
|> getCompilation
|> asFsx
|> verifyCompileAndRun
|> shouldSucceed

[<Theory; FileInlineData("IEnumerableIterationGenericDisposal01.fs")>]
let ``IEnumerableIterationGenericDisposal01_fs`` compilation =
compilation
|> getCompilation
|> asFsx
|> verifyCompileAndRun
|> shouldSucceed

[<Theory; FileInlineData("E_BadIEnumerable01.fs")>]
let ``E_BadIEnumerable01_fs`` compilation =
compilation
|> getCompilation
|> asFsx
|> typecheck
|> shouldFail

[<Theory; FileInlineData("W_IncompleteMatchFor01.fs")>]
let ``W_IncompleteMatchFor01_fs`` compilation =
compilation
Expand All @@ -26,4 +56,3 @@ module SequenceIteration =
(Warning 25, Line 22, Col 9, Line 22, Col 17, "Incomplete pattern matches on this expression. For example, the value 'None' may indicate a case not covered by the pattern(s).")
(Warning 25, Line 27, Col 20, Line 27, Col 28, "Incomplete pattern matches on this expression. For example, the value 'None' may indicate a case not covered by the pattern(s).")
]

Loading