' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.

Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Roslyn.Test.Utilities

Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
    Public Class CodeGenIterators
        Inherits BasicTestBase

        <Fact>
        <WorkItem(1081584, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1081584")>
        Public Sub TestYieldInSelectCase()
            CompileAndVerify(
<compilation>
    <file name="a.vb">
Option Strict On

Imports System
Imports System.Collections.Generic

Module A
    Public Sub Main()
        For Each s In YieldString()
            Console.WriteLine(s)
        Next
    End Sub

    Public Iterator Function YieldString() As IEnumerable(Of String)
      For Each b In { True, False }
          Select Case True
            Case b
              Yield "True"
            Case Not b
              Yield "False"
          End Select
      Next
    End Function
End Module
    </file>
</compilation>, expectedOutput:="True
False").VerifyIL("A.VB$StateMachine_1_YieldString.MoveNext", "
{
  // Code size      184 (0xb8)
  .maxstack  5
  .locals init (Integer V_0,
                Boolean V_1, //b
                Boolean V_2)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""A.VB$StateMachine_1_YieldString.$State As Integer""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  switch    (
        IL_001b,
        IL_0067,
        IL_008f)
  IL_0019:  ldc.i4.0
  IL_001a:  ret
  IL_001b:  ldarg.0
  IL_001c:  ldc.i4.m1
  IL_001d:  dup
  IL_001e:  stloc.0
  IL_001f:  stfld      ""A.VB$StateMachine_1_YieldString.$State As Integer""
  IL_0024:  ldarg.0
  IL_0025:  ldc.i4.2
  IL_0026:  newarr     ""Boolean""
  IL_002b:  dup
  IL_002c:  ldc.i4.0
  IL_002d:  ldc.i4.1
  IL_002e:  stelem.i1
  IL_002f:  stfld      ""A.VB$StateMachine_1_YieldString.$S0 As Boolean()""
  IL_0034:  ldarg.0
  IL_0035:  ldc.i4.0
  IL_0036:  stfld      ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
  IL_003b:  br.s       IL_00a6
  IL_003d:  ldarg.0
  IL_003e:  ldfld      ""A.VB$StateMachine_1_YieldString.$S0 As Boolean()""
  IL_0043:  ldarg.0
  IL_0044:  ldfld      ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
  IL_0049:  ldelem.u1
  IL_004a:  stloc.1
  IL_004b:  ldc.i4.1
  IL_004c:  stloc.2
  IL_004d:  ldloc.2
  IL_004e:  ldloc.1
  IL_004f:  bne.un.s   IL_0072
  IL_0051:  ldarg.0
  IL_0052:  ldstr      ""True""
  IL_0057:  stfld      ""A.VB$StateMachine_1_YieldString.$Current As String""
  IL_005c:  ldarg.0
  IL_005d:  ldc.i4.1
  IL_005e:  dup
  IL_005f:  stloc.0
  IL_0060:  stfld      ""A.VB$StateMachine_1_YieldString.$State As Integer""
  IL_0065:  ldc.i4.1
  IL_0066:  ret
  IL_0067:  ldarg.0
  IL_0068:  ldc.i4.m1
  IL_0069:  dup
  IL_006a:  stloc.0
  IL_006b:  stfld      ""A.VB$StateMachine_1_YieldString.$State As Integer""
  IL_0070:  br.s       IL_0098
  IL_0072:  ldloc.2
  IL_0073:  ldloc.1
  IL_0074:  ldc.i4.0
  IL_0075:  ceq
  IL_0077:  bne.un.s   IL_0098
  IL_0079:  ldarg.0
  IL_007a:  ldstr      ""False""
  IL_007f:  stfld      ""A.VB$StateMachine_1_YieldString.$Current As String""
  IL_0084:  ldarg.0
  IL_0085:  ldc.i4.2
  IL_0086:  dup
  IL_0087:  stloc.0
  IL_0088:  stfld      ""A.VB$StateMachine_1_YieldString.$State As Integer""
  IL_008d:  ldc.i4.1
  IL_008e:  ret
  IL_008f:  ldarg.0
  IL_0090:  ldc.i4.m1
  IL_0091:  dup
  IL_0092:  stloc.0
  IL_0093:  stfld      ""A.VB$StateMachine_1_YieldString.$State As Integer""
  IL_0098:  ldarg.0
  IL_0099:  ldarg.0
  IL_009a:  ldfld      ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
  IL_009f:  ldc.i4.1
  IL_00a0:  add.ovf
  IL_00a1:  stfld      ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
  IL_00a6:  ldarg.0
  IL_00a7:  ldfld      ""A.VB$StateMachine_1_YieldString.$S1 As Integer""
  IL_00ac:  ldarg.0
  IL_00ad:  ldfld      ""A.VB$StateMachine_1_YieldString.$S0 As Boolean()""
  IL_00b2:  ldlen
  IL_00b3:  conv.i4
  IL_00b4:  blt.s      IL_003d
  IL_00b6:  ldc.i4.0
  IL_00b7:  ret
}
").VerifyIL("A.VB$StateMachine_1_YieldString.IEnumerable.GetEnumerator", "
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       ""Function A.VB$StateMachine_1_YieldString.GetEnumerator() As System.Collections.Generic.IEnumerator(Of String)""
  IL_0006:  ret
}")
        End Sub

        <Fact>
        Public Sub SingletonIterator()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        For Each i In Goo
            Console.WriteLine(i)
        Next
    End Sub

    iterator function Goo as IEnumerable(of Integer)
        Yield 42
    End Function

End Module

    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
  // Code size       55 (0x37)
  .maxstack  3
  .locals init (Integer V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  brfalse.s  IL_0010
  IL_000a:  ldloc.0
  IL_000b:  ldc.i4.1
  IL_000c:  beq.s      IL_002c
  IL_000e:  ldc.i4.0
  IL_000f:  ret
  IL_0010:  ldarg.0
  IL_0011:  ldc.i4.m1
  IL_0012:  dup
  IL_0013:  stloc.0
  IL_0014:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0019:  ldarg.0
  IL_001a:  ldc.i4.s   42
  IL_001c:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
  IL_0021:  ldarg.0
  IL_0022:  ldc.i4.1
  IL_0023:  dup
  IL_0024:  stloc.0
  IL_0025:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_002a:  ldc.i4.1
  IL_002b:  ret
  IL_002c:  ldarg.0
  IL_002d:  ldc.i4.m1
  IL_002e:  dup
  IL_002f:  stloc.0
  IL_0030:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0035:  ldc.i4.0
  IL_0036:  ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
  IL_0006:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub TwoVarsSameName()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic

Module Module1

    Sub Main()
        For Each i In Goo
            Console.Write(i)
        Next
    End Sub

    Iterator Function Goo() As IEnumerable(Of Integer)
        Dim arr(1) As Integer
        arr(0) = 42

        For Each x In arr
            Yield x
            Yield x
        Next

        For Each x In "abc"
            Yield System.Convert.ToInt32(x)
            Yield System.Convert.ToInt32(x)
        Next

    End Function

End Module

    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="424200979798989999").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
  // Code size      340 (0x154)
  .maxstack  3
  .locals init (Integer V_0,
                Integer() V_1) //arr
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  switch    (
        IL_0023,
        IL_0072,
        IL_0092,
        IL_0100,
        IL_0125)
  IL_0021:  ldc.i4.0
  IL_0022:  ret
  IL_0023:  ldarg.0
  IL_0024:  ldc.i4.m1
  IL_0025:  dup
  IL_0026:  stloc.0
  IL_0027:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_002c:  ldc.i4.2
  IL_002d:  newarr     "Integer"
  IL_0032:  stloc.1
  IL_0033:  ldloc.1
  IL_0034:  ldc.i4.0
  IL_0035:  ldc.i4.s   42
  IL_0037:  stelem.i4
  IL_0038:  ldarg.0
  IL_0039:  ldloc.1
  IL_003a:  stfld      "Module1.VB$StateMachine_1_Goo.$S0 As Integer()"
  IL_003f:  ldarg.0
  IL_0040:  ldc.i4.0
  IL_0041:  stfld      "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
  IL_0046:  br.s       IL_00a9
  IL_0048:  ldarg.0
  IL_0049:  ldarg.0
  IL_004a:  ldfld      "Module1.VB$StateMachine_1_Goo.$S0 As Integer()"
  IL_004f:  ldarg.0
  IL_0050:  ldfld      "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
  IL_0055:  ldelem.i4
  IL_0056:  stfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$1 As Integer"
  IL_005b:  ldarg.0
  IL_005c:  ldarg.0
  IL_005d:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$1 As Integer"
  IL_0062:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
  IL_0067:  ldarg.0
  IL_0068:  ldc.i4.1
  IL_0069:  dup
  IL_006a:  stloc.0
  IL_006b:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0070:  ldc.i4.1
  IL_0071:  ret
  IL_0072:  ldarg.0
  IL_0073:  ldc.i4.m1
  IL_0074:  dup
  IL_0075:  stloc.0
  IL_0076:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_007b:  ldarg.0
  IL_007c:  ldarg.0
  IL_007d:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$1 As Integer"
  IL_0082:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
  IL_0087:  ldarg.0
  IL_0088:  ldc.i4.2
  IL_0089:  dup
  IL_008a:  stloc.0
  IL_008b:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0090:  ldc.i4.1
  IL_0091:  ret
  IL_0092:  ldarg.0
  IL_0093:  ldc.i4.m1
  IL_0094:  dup
  IL_0095:  stloc.0
  IL_0096:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_009b:  ldarg.0
  IL_009c:  ldarg.0
  IL_009d:  ldfld      "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
  IL_00a2:  ldc.i4.1
  IL_00a3:  add.ovf
  IL_00a4:  stfld      "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
  IL_00a9:  ldarg.0
  IL_00aa:  ldfld      "Module1.VB$StateMachine_1_Goo.$S2 As Integer"
  IL_00af:  ldarg.0
  IL_00b0:  ldfld      "Module1.VB$StateMachine_1_Goo.$S0 As Integer()"
  IL_00b5:  ldlen
  IL_00b6:  conv.i4
  IL_00b7:  blt.s      IL_0048
  IL_00b9:  ldarg.0
  IL_00ba:  ldstr      "abc"
  IL_00bf:  stfld      "Module1.VB$StateMachine_1_Goo.$S3 As String"
  IL_00c4:  ldarg.0
  IL_00c5:  ldc.i4.0
  IL_00c6:  stfld      "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
  IL_00cb:  br.s       IL_013c
  IL_00cd:  ldarg.0
  IL_00ce:  ldarg.0
  IL_00cf:  ldfld      "Module1.VB$StateMachine_1_Goo.$S3 As String"
  IL_00d4:  ldarg.0
  IL_00d5:  ldfld      "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
  IL_00da:  callvirt   "Function String.get_Chars(Integer) As Char"
  IL_00df:  stfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$4 As Char"
  IL_00e4:  ldarg.0
  IL_00e5:  ldarg.0
  IL_00e6:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$4 As Char"
  IL_00eb:  call       "Function System.Convert.ToInt32(Char) As Integer"
  IL_00f0:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
  IL_00f5:  ldarg.0
  IL_00f6:  ldc.i4.3
  IL_00f7:  dup
  IL_00f8:  stloc.0
  IL_00f9:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_00fe:  ldc.i4.1
  IL_00ff:  ret
  IL_0100:  ldarg.0
  IL_0101:  ldc.i4.m1
  IL_0102:  dup
  IL_0103:  stloc.0
  IL_0104:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0109:  ldarg.0
  IL_010a:  ldarg.0
  IL_010b:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$4 As Char"
  IL_0110:  call       "Function System.Convert.ToInt32(Char) As Integer"
  IL_0115:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
  IL_011a:  ldarg.0
  IL_011b:  ldc.i4.4
  IL_011c:  dup
  IL_011d:  stloc.0
  IL_011e:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0123:  ldc.i4.1
  IL_0124:  ret
  IL_0125:  ldarg.0
  IL_0126:  ldc.i4.m1
  IL_0127:  dup
  IL_0128:  stloc.0

  IL_0129:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_012e:  ldarg.0
  IL_012f:  ldarg.0
  IL_0130:  ldfld      "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
  IL_0135:  ldc.i4.1
  IL_0136:  add.ovf
  IL_0137:  stfld      "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
  IL_013c:  ldarg.0
  IL_013d:  ldfld      "Module1.VB$StateMachine_1_Goo.$S5 As Integer"
  IL_0142:  ldarg.0
  IL_0143:  ldfld      "Module1.VB$StateMachine_1_Goo.$S3 As String"
  IL_0148:  callvirt   "Function String.get_Length() As Integer"
  IL_014d:  blt        IL_00cd
  IL_0152:  ldc.i4.0
  IL_0153:  ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
  IL_0006:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub ReadonlyProperty()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System
Imports System.Collections.Generic

Module Module1
    Sub Main()
        For Each x In p1
            Console.Write(x)
        Next
    End Sub

    Public ReadOnly Iterator Property p1 As IEnumerable(Of Integer)
        Get
            Yield 42
        End Get
    End Property
End Module
    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_2_get_p1.MoveNext()", <![CDATA[
{
  // Code size       55 (0x37)
  .maxstack  3
  .locals init (Integer V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_2_get_p1.$State As Integer"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  brfalse.s  IL_0010
  IL_000a:  ldloc.0
  IL_000b:  ldc.i4.1
  IL_000c:  beq.s      IL_002c
  IL_000e:  ldc.i4.0
  IL_000f:  ret
  IL_0010:  ldarg.0
  IL_0011:  ldc.i4.m1
  IL_0012:  dup
  IL_0013:  stloc.0
  IL_0014:  stfld      "Module1.VB$StateMachine_2_get_p1.$State As Integer"
  IL_0019:  ldarg.0
  IL_001a:  ldc.i4.s   42
  IL_001c:  stfld      "Module1.VB$StateMachine_2_get_p1.$Current As Integer"
  IL_0021:  ldarg.0
  IL_0022:  ldc.i4.1
  IL_0023:  dup
  IL_0024:  stloc.0
  IL_0025:  stfld      "Module1.VB$StateMachine_2_get_p1.$State As Integer"
  IL_002a:  ldc.i4.1
  IL_002b:  ret
  IL_002c:  ldarg.0
  IL_002d:  ldc.i4.m1
  IL_002e:  dup
  IL_002f:  stloc.0
  IL_0030:  stfld      "Module1.VB$StateMachine_2_get_p1.$State As Integer"
  IL_0035:  ldc.i4.0
  IL_0036:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub ReadWriteProperty()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic

Module Module1
    Sub Main()

        System.Console.Write(save Is Nothing)

        p1 = p1

        For Each x In save
            Console.Write(x)
        Next
    End Sub

    Private save As IEnumerable(Of Integer)

    Public Iterator Property p1 As IEnumerable(Of Integer)
        Get
            Yield 42
        End Get
        Set(value As IEnumerable(Of Integer))
            save = value
        End Set
    End Property
End Module

    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="True42")
        End Sub

        <Fact>
        Public Sub ParamCapture()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        For Each i In Goo(42)
            Console.WriteLine(i)
        Next
    End Sub

    iterator function Goo(x as integer) as IEnumerable(of Integer)
        Yield x
    End Function

End Module

    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
  // Code size       59 (0x3b)
  .maxstack  3
  .locals init (Integer V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  brfalse.s  IL_0010
  IL_000a:  ldloc.0
  IL_000b:  ldc.i4.1
  IL_000c:  beq.s      IL_0030
  IL_000e:  ldc.i4.0
  IL_000f:  ret
  IL_0010:  ldarg.0
  IL_0011:  ldc.i4.m1
  IL_0012:  dup
  IL_0013:  stloc.0
  IL_0014:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0019:  ldarg.0
  IL_001a:  ldarg.0
  IL_001b:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$Local_x As Integer"
  IL_0020:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
  IL_0025:  ldarg.0
  IL_0026:  ldc.i4.1
  IL_0027:  dup
  IL_0028:  stloc.0
  IL_0029:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_002e:  ldc.i4.1
  IL_002f:  ret
  IL_0030:  ldarg.0
  IL_0031:  ldc.i4.m1
  IL_0032:  dup
  IL_0033:  stloc.0
  IL_0034:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0039:  ldc.i4.0
  IL_003a:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub NestedForeach()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        For Each i In Goo({1,2,3,4,5})
            Console.Write(i)
        Next
    End Sub

    iterator function Goo(x As IEnumerable(of Integer)) as IEnumerable(of Integer)
        For Each i In x
            Yield i
        Next
    End Function

End Module


    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="12345").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
  // Code size      175 (0xaf)
  .maxstack  3
  .locals init (Boolean V_0,
                Integer V_1,
                Integer V_2) //i
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0006:  stloc.1
  IL_0007:  ldloc.1
  IL_0008:  ldc.i4.s   -3
  IL_000a:  sub
  IL_000b:  switch    (
        IL_002f,
        IL_0024,
        IL_0024,
        IL_0026,
        IL_002f)
  IL_0024:  ldc.i4.0
  IL_0025:  ret
  IL_0026:  ldarg.0
  IL_0027:  ldc.i4.m1
  IL_0028:  dup
  IL_0029:  stloc.1
  IL_002a:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_002f:  nop
  .try
  {
    IL_0030:  ldloc.1
    IL_0031:  ldc.i4.s   -3
    IL_0033:  beq.s      IL_003b
    IL_0035:  ldloc.1
    IL_0036:  ldc.i4.1
    IL_0037:  beq.s      IL_007b
    IL_0039:  br.s       IL_0048
    IL_003b:  ldarg.0
    IL_003c:  ldc.i4.m1
    IL_003d:  dup
    IL_003e:  stloc.1
    IL_003f:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
    IL_0044:  ldc.i4.1
    IL_0045:  stloc.0
    IL_0046:  leave.s    IL_00ad
    IL_0048:  ldarg.0
    IL_0049:  ldarg.0
    IL_004a:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$Local_x As System.Collections.Generic.IEnumerable(Of Integer)"
    IL_004f:  callvirt   "Function System.Collections.Generic.IEnumerable(Of Integer).GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
    IL_0054:  stfld      "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
    IL_0059:  br.s       IL_0084
    IL_005b:  ldarg.0
    IL_005c:  ldfld      "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
    IL_0061:  callvirt   "Function System.Collections.Generic.IEnumerator(Of Integer).get_Current() As Integer"
    IL_0066:  stloc.2
    IL_0067:  ldarg.0
    IL_0068:  ldloc.2
    IL_0069:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
    IL_006e:  ldarg.0
    IL_006f:  ldc.i4.1
    IL_0070:  dup
    IL_0071:  stloc.1
    IL_0072:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
    IL_0077:  ldc.i4.1
    IL_0078:  stloc.0
    IL_0079:  leave.s    IL_00ad
    IL_007b:  ldarg.0
    IL_007c:  ldc.i4.m1
    IL_007d:  dup
    IL_007e:  stloc.1
    IL_007f:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
    IL_0084:  ldarg.0
    IL_0085:  ldfld      "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
    IL_008a:  callvirt   "Function System.Collections.IEnumerator.MoveNext() As Boolean"
    IL_008f:  brtrue.s   IL_005b
    IL_0091:  leave.s    IL_00ab
  }
  finally
  {
    IL_0093:  ldloc.1
    IL_0094:  ldc.i4.0
    IL_0095:  bge.s      IL_00aa
    IL_0097:  ldarg.0
    IL_0098:  ldfld      "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
    IL_009d:  brfalse.s  IL_00aa
    IL_009f:  ldarg.0
    IL_00a0:  ldfld      "Module1.VB$StateMachine_1_Goo.$S0 As System.Collections.Generic.IEnumerator(Of Integer)"
    IL_00a5:  callvirt   "Sub System.IDisposable.Dispose()"
    IL_00aa:  endfinally
  }
  IL_00ab:  ldc.i4.0
  IL_00ac:  ret
  IL_00ad:  ldloc.0
  IL_00ae:  ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
  IL_0006:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub NestedFor()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        For Each i In Goo()
            Console.Write(i)
        Next
    End Sub

    iterator function Goo() as IEnumerable(of Integer)
        For i = 1 to 5
            Yield i
        Next
    End Function

End Module


    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="12345").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
  // Code size       89 (0x59)
  .maxstack  3
  .locals init (Integer V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  brfalse.s  IL_0010
  IL_000a:  ldloc.0
  IL_000b:  ldc.i4.1
  IL_000c:  beq.s      IL_0037
  IL_000e:  ldc.i4.0
  IL_000f:  ret
  IL_0010:  ldarg.0
  IL_0011:  ldc.i4.m1
  IL_0012:  dup
  IL_0013:  stloc.0
  IL_0014:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0019:  ldarg.0
  IL_001a:  ldc.i4.1
  IL_001b:  stfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
  IL_0020:  ldarg.0
  IL_0021:  ldarg.0
  IL_0022:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
  IL_0027:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
  IL_002c:  ldarg.0
  IL_002d:  ldc.i4.1
  IL_002e:  dup
  IL_002f:  stloc.0
  IL_0030:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0035:  ldc.i4.1
  IL_0036:  ret
  IL_0037:  ldarg.0
  IL_0038:  ldc.i4.m1
  IL_0039:  dup
  IL_003a:  stloc.0
  IL_003b:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0040:  ldarg.0
  IL_0041:  ldarg.0
  IL_0042:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
  IL_0047:  ldc.i4.1
  IL_0048:  add.ovf
  IL_0049:  stfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
  IL_004e:  ldarg.0
  IL_004f:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_i$0 As Integer"
  IL_0054:  ldc.i4.5
  IL_0055:  ble.s      IL_0020
  IL_0057:  ldc.i4.0
  IL_0058:  ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
  IL_0006:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub LocalsInDispose()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        For Each i In Goo()
            Console.Write(i)
        Next
    End Sub

    iterator function Goo() as IEnumerable(of Integer)
        Dim x = 1
        Try
            x += 1
            Yield x
            Exit Function
        Finally
            x += 1
            Dim y = x
            Console.Write(x)
            Console.Write(y.ToString())
        End Try
    End Function

End Module


    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="233").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
  // Code size      182 (0xb6)
  .maxstack  3
  .locals init (Boolean V_0,
                Integer V_1,
                Integer V_2) //y
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0006:  stloc.1
  IL_0007:  ldloc.1
  IL_0008:  ldc.i4.s   -3
  IL_000a:  sub
  IL_000b:  switch    (
        IL_0036,
        IL_0024,
        IL_0024,
        IL_0026,
        IL_0036)
  IL_0024:  ldc.i4.0
  IL_0025:  ret
  IL_0026:  ldarg.0
  IL_0027:  ldc.i4.m1
  IL_0028:  dup
  IL_0029:  stloc.1
  IL_002a:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_002f:  ldarg.0
  IL_0030:  ldc.i4.1
  IL_0031:  stfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
  IL_0036:  nop
  .try
  {
    IL_0037:  ldloc.1
    IL_0038:  ldc.i4.s   -3
    IL_003a:  beq.s      IL_0042
    IL_003c:  ldloc.1
    IL_003d:  ldc.i4.1
    IL_003e:  beq.s      IL_0076
    IL_0040:  br.s       IL_004f
    IL_0042:  ldarg.0
    IL_0043:  ldc.i4.m1
    IL_0044:  dup
    IL_0045:  stloc.1
    IL_0046:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
    IL_004b:  ldc.i4.1
    IL_004c:  stloc.0
    IL_004d:  leave.s    IL_00b4
    IL_004f:  ldarg.0
    IL_0050:  ldarg.0
    IL_0051:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
    IL_0056:  ldc.i4.1
    IL_0057:  add.ovf
    IL_0058:  stfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
    IL_005d:  ldarg.0
    IL_005e:  ldarg.0
    IL_005f:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
    IL_0064:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
    IL_0069:  ldarg.0
    IL_006a:  ldc.i4.1
    IL_006b:  dup
    IL_006c:  stloc.1
    IL_006d:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
    IL_0072:  ldc.i4.1
    IL_0073:  stloc.0
    IL_0074:  leave.s    IL_00b4
    IL_0076:  ldarg.0
    IL_0077:  ldc.i4.m1
    IL_0078:  dup
    IL_0079:  stloc.1
    IL_007a:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
    IL_007f:  leave.s    IL_00b2
  }
  finally
  {
    IL_0081:  ldloc.1
    IL_0082:  ldc.i4.0
    IL_0083:  bge.s      IL_00b1
    IL_0085:  ldarg.0
    IL_0086:  ldarg.0
    IL_0087:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
    IL_008c:  ldc.i4.1
    IL_008d:  add.ovf
    IL_008e:  stfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
    IL_0093:  ldarg.0
    IL_0094:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
    IL_0099:  stloc.2
    IL_009a:  ldarg.0
    IL_009b:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$ResumableLocal_x$0 As Integer"
    IL_00a0:  call       "Sub System.Console.Write(Integer)"
    IL_00a5:  ldloca.s   V_2
    IL_00a7:  call       "Function Integer.ToString() As String"
    IL_00ac:  call       "Sub System.Console.Write(String)"
    IL_00b1:  endfinally
  }
  IL_00b2:  ldc.i4.0
  IL_00b3:  ret
  IL_00b4:  ldloc.0
  IL_00b5:  ret
}
]]>).VerifyIL("Module1.VB$StateMachine_1_Goo.IEnumerable.GetEnumerator", <![CDATA[
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  call       "Function Module1.VB$StateMachine_1_Goo.GetEnumerator() As System.Collections.Generic.IEnumerator(Of Integer)"
  IL_0006:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub TryCatch()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        For Each i In Goo()
            Console.Write(i.Message)
        Next
    End Sub

    iterator function Goo() as IEnumerable(of Exception)

        Dim ex As exception = nothing

        Try
            yield New Exception("1")
            Throw New Exception("2")
        Catch ex           
        End Try

        Yield ex

    End Function

End Module


    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="12").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
  // Code size      172 (0xac)
  .maxstack  3
  .locals init (Boolean V_0,
                Integer V_1,
                System.Exception V_2) //ex
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0006:  stloc.1
  IL_0007:  ldloc.1
  IL_0008:  ldc.i4.s   -3
  IL_000a:  sub
  IL_000b:  switch    (
        IL_0035,
        IL_0028,
        IL_0028,
        IL_002a,
        IL_0035,
        IL_009f)
  IL_0028:  ldc.i4.0
  IL_0029:  ret
  IL_002a:  ldarg.0
  IL_002b:  ldc.i4.m1
  IL_002c:  dup
  IL_002d:  stloc.1
  IL_002e:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0033:  ldnull
  IL_0034:  stloc.2
  IL_0035:  nop
  .try
  {
    IL_0036:  ldloc.1
    IL_0037:  ldc.i4.s   -3
    IL_0039:  beq.s      IL_0041
    IL_003b:  ldloc.1
    IL_003c:  ldc.i4.1
    IL_003d:  beq.s      IL_006b
    IL_003f:  br.s       IL_004e
    IL_0041:  ldarg.0
    IL_0042:  ldc.i4.m1
    IL_0043:  dup
    IL_0044:  stloc.1
    IL_0045:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
    IL_004a:  ldc.i4.1
    IL_004b:  stloc.0
    IL_004c:  leave.s    IL_00aa
    IL_004e:  ldarg.0
    IL_004f:  ldstr      "1"
    IL_0054:  newobj     "Sub System.Exception..ctor(String)"
    IL_0059:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As System.Exception"
    IL_005e:  ldarg.0
    IL_005f:  ldc.i4.1
    IL_0060:  dup
    IL_0061:  stloc.1
    IL_0062:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
    IL_0067:  ldc.i4.1
    IL_0068:  stloc.0
    IL_0069:  leave.s    IL_00aa
    IL_006b:  ldarg.0
    IL_006c:  ldc.i4.m1
    IL_006d:  dup
    IL_006e:  stloc.1
    IL_006f:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
    IL_0074:  ldstr      "2"
    IL_0079:  newobj     "Sub System.Exception..ctor(String)"
    IL_007e:  throw
  }
  catch System.Exception
  {
    IL_007f:  dup
    IL_0080:  call       "Sub Microsoft.VisualBasic.CompilerServices.ProjectData.SetProjectError(System.Exception)"
    IL_0085:  stloc.2
    IL_0086:  call       "Sub Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()"
    IL_008b:  leave.s    IL_008d
  }
  IL_008d:  ldarg.0
  IL_008e:  ldloc.2
  IL_008f:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As System.Exception"
  IL_0094:  ldarg.0
  IL_0095:  ldc.i4.2
  IL_0096:  dup
  IL_0097:  stloc.1
  IL_0098:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_009d:  ldc.i4.1
  IL_009e:  ret
  IL_009f:  ldarg.0
  IL_00a0:  ldc.i4.m1
  IL_00a1:  dup
  IL_00a2:  stloc.1
  IL_00a3:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_00a8:  ldc.i4.0
  IL_00a9:  ret
  IL_00aa:  ldloc.0
  IL_00ab:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub TryFinally()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        For Each i In Goo()
            Console.Write(i.Message)
        Next
    End Sub

    iterator function Goo() as IEnumerable(of Exception)

        Dim ex As exception = nothing

        Try
            yield New Exception("1")
        Finally
            ex = New Exception("2")          
        End Try

        Yield ex

        Try
            Try
                yield New Exception("3")
                Throw New Exception()
            Finally
                ex = New Exception("4")          
            End Try
        Catch ex1 As Exception
        End Try

        Yield ex
    End Function

End Module


    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="1234")
        End Sub

        <Fact>
        Public Sub TryYieldFinally()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        For Each i In Goo()
            Console.Write(i)
        Next
    End Sub

    iterator function Goo() as IEnumerable(of integer)
            Dim j as String = ""
            Dim i = 1

            Try
                Try
                    throw new exception

                Catch ex as exception
                    j = j + "#" + i.ToString() + "#"
                End try

                Yield i
            Finally
                Console.Write(j)
            End Try
    End Function

End Module

    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="1#1#")
        End Sub

        <Fact>
        Public Sub TryInLoop()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections

Module Module1

    Sub Main()
        For Each i In f()
            Console.Write(i)  
        Next
    End Sub

    Iterator Function f() As IEnumerable
        For i = 1 To 3
            Dim j as String = ""
            Try
                Try
                    Yield i

                    throw new exception

                Catch ex as exception
                    j = j + "#" + i.ToString() + "#"
                End try

                Yield i
            Finally
                Console.Write(j)
            End Try
        Next
    End Function
End Module

    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="11#1#22#2#33#3#")
        End Sub

        <Fact>
        Public Sub InStruct()
            Dim source =
    <compilation>
        <file name="a.vb">

Imports System
Imports System.Collections
Imports System.Collections.Generic

Module Module1
    Sub Main()
        Dim s As New S1

        For Each i In s.f
            Console.Write(i)
        Next
        For Each i In s.f
            Console.Write(i)
        Next

        s.x = 42
        For Each i In s.f
            Console.Write(i)
        Next
    End Sub

    Structure S1
        Public x As integer

        public Iterator Function f() As IEnumerable(of Integer)
            Yield x
            x += 1

            Yield x
        End Function
    End Structure

End Module

    </file>
    </compilation>

            CompileAndVerify(source, expectedOutput:="01014243")
        End Sub

        <Fact>
        Public Sub UnusedParams()
            Dim source =
    <compilation>
        <file name="a.vb">

Imports System
Imports System.Collections
Imports System.Collections.Generic

Module Module1
    Sub Main()
        Dim s As New cls1

        For Each i In s.f(Nothing, Nothing)
            Console.Write(i)
        Next
    End Sub

    class cls1
        public Iterator Function f(x As Guid, y As Guid) As IEnumerable(of Integer)
            Yield 1
            Yield 2
        End Function
    End class

End Module

    </file>
    </compilation>

            CompileAndVerify(source, expectedOutput:="12").VerifyIL("Module1.cls1.VB$StateMachine_1_f.GetEnumerator()", <![CDATA[
{
  // Code size       84 (0x54)
  .maxstack  2
  .locals init (Module1.cls1.VB$StateMachine_1_f V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.cls1.VB$StateMachine_1_f.$State As Integer"
  IL_0006:  ldc.i4.s   -2
  IL_0008:  bne.un.s   IL_0027
  IL_000a:  ldarg.0
  IL_000b:  ldfld      "Module1.cls1.VB$StateMachine_1_f.$InitialThreadId As Integer"
  IL_0010:  call       "Function System.Threading.Thread.get_CurrentThread() As System.Threading.Thread"
  IL_0015:  callvirt   "Function System.Threading.Thread.get_ManagedThreadId() As Integer"
  IL_001a:  bne.un.s   IL_0027
  IL_001c:  ldarg.0
  IL_001d:  ldc.i4.0
  IL_001e:  stfld      "Module1.cls1.VB$StateMachine_1_f.$State As Integer"
  IL_0023:  ldarg.0
  IL_0024:  stloc.0
  IL_0025:  br.s       IL_003a
  IL_0027:  ldc.i4.0
  IL_0028:  newobj     "Sub Module1.cls1.VB$StateMachine_1_f..ctor(Integer)"
  IL_002d:  stloc.0
  IL_002e:  ldloc.0
  IL_002f:  ldarg.0
  IL_0030:  ldfld      "Module1.cls1.VB$StateMachine_1_f.$VB$Me As Module1.cls1"
  IL_0035:  stfld      "Module1.cls1.VB$StateMachine_1_f.$VB$Me As Module1.cls1"
  IL_003a:  ldloc.0
  IL_003b:  ldarg.0
  IL_003c:  ldfld      "Module1.cls1.VB$StateMachine_1_f.$P_x As System.Guid"
  IL_0041:  stfld      "Module1.cls1.VB$StateMachine_1_f.$VB$Local_x As System.Guid"
  IL_0046:  ldloc.0
  IL_0047:  ldarg.0
  IL_0048:  ldfld      "Module1.cls1.VB$StateMachine_1_f.$P_y As System.Guid"
  IL_004d:  stfld      "Module1.cls1.VB$StateMachine_1_f.$VB$Local_y As System.Guid"
  IL_0052:  ldloc.0
  IL_0053:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub InferredEnumerable()
            Dim source =
    <compilation>
        <file name="a.vb">

Imports System
Imports System.Collections.Generic

Module Module1
    Sub Main()
        Dim i = Iterator Function()
                    yield 123
                End Function

        goo(i)

        Dim i1 = Iterator Function()
                End Function

        goo(i1)

        Dim i2 as Func(Of IEnumerator(of integer)) = Iterator Function()
                                                         Yield 1
                                                         Yield "aa"
                                                    End Function

        goo(i2)
    End Sub

    Public Sub goo(Of T)(x As Func(of T))
        Console.WriteLine(GetType(T))
    End Sub
End Module

    </file>
    </compilation>

            CompileAndVerify(source, expectedOutput:=<![CDATA[
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Object]
System.Collections.Generic.IEnumerator`1[System.Int32]
]]>)
        End Sub

        <Fact>
        Public Sub EnumeratorWithParameter()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        Dim e = Goo(42)

        While e.MoveNext
            Console.WriteLine(e.Current)
        End While
    End Sub

    iterator function Goo(x as integer) as IEnumerator(of Integer)
        Yield x
    End Function

End Module

    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_1_Goo.MoveNext", <![CDATA[
{
  // Code size       59 (0x3b)
  .maxstack  3
  .locals init (Integer V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  brfalse.s  IL_0010
  IL_000a:  ldloc.0
  IL_000b:  ldc.i4.1
  IL_000c:  beq.s      IL_0030
  IL_000e:  ldc.i4.0
  IL_000f:  ret
  IL_0010:  ldarg.0
  IL_0011:  ldc.i4.m1
  IL_0012:  dup
  IL_0013:  stloc.0
  IL_0014:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0019:  ldarg.0
  IL_001a:  ldarg.0
  IL_001b:  ldfld      "Module1.VB$StateMachine_1_Goo.$VB$Local_x As Integer"
  IL_0020:  stfld      "Module1.VB$StateMachine_1_Goo.$Current As Integer"
  IL_0025:  ldarg.0
  IL_0026:  ldc.i4.1
  IL_0027:  dup
  IL_0028:  stloc.0
  IL_0029:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_002e:  ldc.i4.1
  IL_002f:  ret
  IL_0030:  ldarg.0
  IL_0031:  ldc.i4.m1
  IL_0032:  dup
  IL_0033:  stloc.0
  IL_0034:  stfld      "Module1.VB$StateMachine_1_Goo.$State As Integer"
  IL_0039:  ldc.i4.0
  IL_003a:  ret
}
]]>).VerifyIL("Module1.Goo", <![CDATA[
{
  // Code size       14 (0xe)
  .maxstack  3
  IL_0000:  ldc.i4.0
  IL_0001:  newobj     "Sub Module1.VB$StateMachine_1_Goo..ctor(Integer)"
  IL_0006:  dup
  IL_0007:  ldarg.0
  IL_0008:  stfld      "Module1.VB$StateMachine_1_Goo.$VB$Local_x As Integer"
  IL_000d:  ret
}
]]>)
        End Sub

        <Fact>
        Public Sub GenericEnumerator()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic
        
Module Module1

    Sub Main()
        Dim e = Goo(42)

        While e.MoveNext
            Console.WriteLine(e.Current)
        End While
    End Sub

    iterator function Goo(of T)(x as T) as IEnumerator(of T)
        Yield x
    End Function

End Module

    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="42").VerifyIL("Module1.VB$StateMachine_1_Goo(Of SM$T).MoveNext", <![CDATA[
{
  // Code size       59 (0x3b)
  .maxstack  3
  .locals init (Integer V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      "Module1.VB$StateMachine_1_Goo(Of SM$T).$State As Integer"
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  brfalse.s  IL_0010
  IL_000a:  ldloc.0
  IL_000b:  ldc.i4.1
  IL_000c:  beq.s      IL_0030
  IL_000e:  ldc.i4.0
  IL_000f:  ret
  IL_0010:  ldarg.0
  IL_0011:  ldc.i4.m1
  IL_0012:  dup
  IL_0013:  stloc.0
  IL_0014:  stfld      "Module1.VB$StateMachine_1_Goo(Of SM$T).$State As Integer"
  IL_0019:  ldarg.0
  IL_001a:  ldarg.0
  IL_001b:  ldfld      "Module1.VB$StateMachine_1_Goo(Of SM$T).$VB$Local_x As SM$T"
  IL_0020:  stfld      "Module1.VB$StateMachine_1_Goo(Of SM$T).$Current As SM$T"
  IL_0025:  ldarg.0
  IL_0026:  ldc.i4.1
  IL_0027:  dup
  IL_0028:  stloc.0
  IL_0029:  stfld      "Module1.VB$StateMachine_1_Goo(Of SM$T).$State As Integer"
  IL_002e:  ldc.i4.1
  IL_002f:  ret
  IL_0030:  ldarg.0
  IL_0031:  ldc.i4.m1
  IL_0032:  dup
  IL_0033:  stloc.0
  IL_0034:  stfld      "Module1.VB$StateMachine_1_Goo(Of SM$T).$State As Integer"
  IL_0039:  ldc.i4.0
  IL_003a:  ret
}
]]>).VerifyIL("Module1.Goo", <![CDATA[
{
  // Code size       14 (0xe)
  .maxstack  3
  IL_0000:  ldc.i4.0
  IL_0001:  newobj     "Sub Module1.VB$StateMachine_1_Goo(Of T)..ctor(Integer)"
  IL_0006:  dup
  IL_0007:  ldarg.0
  IL_0008:  stfld      "Module1.VB$StateMachine_1_Goo(Of T).$VB$Local_x As T"
  IL_000d:  ret
}
]]>)
        End Sub
        <Fact>
        <WorkItem(703361, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/703361")>
        Public Sub VerifyHelpers()
            Dim source = <compilation>
                             <file name="a.vb"><![CDATA[
Imports System.Collections.Generic
Public Class Program
    Public Shared Iterator Function Goo() As IEnumerable(Of Integer)
        Yield 1
    End Function
End Class]]></file>
                         </compilation>
            Dim comp = CreateEmptyCompilationWithReferences(source, {MscorlibRef_v4_0_30316_17626}, New VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
            Dim verifier = Me.CompileAndVerify(comp)
            Dim il = verifier.VisualizeIL("Program.VB$StateMachine_1_Goo.GetEnumerator()")
            Assert.Contains("System.Environment.get_CurrentManagedThreadId()", il, StringComparison.Ordinal)
        End Sub

        <WorkItem(835430, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/835430")>
        <Fact>
        Public Sub YieldInWith()
            Dim source =
<compilation>
    <file name="a.vb">

Imports System
Imports System.Collections.Generic

Public Structure MyStruct
    Public a As Long
End Structure

Module Module1

    Public MyStructs As MyStruct() = New MyStruct() {Nothing}

    Sub Main()
        For Each i In Goo()
            Console.Write(i)
        Next
    End Sub

    Iterator Function Goo() As IEnumerable(Of Integer)
        For k = 1 To 2
            With MyStructs(0)
                Yield 42

                System.Console.Write( .a)
            End With
        Next
    End Function

End Module

    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="420420")
        End Sub

        <Fact, WorkItem(9167, "https://github.com/dotnet/roslyn/issues/9167")>
        Public Sub IteratorShouldCompileWithoutOptionalAttributes()

#Region "IL For corlib without CompilerGeneratedAttribute Or DebuggerNonUserCodeAttribute"
            Dim corlib = "
Namespace System
    Public Class [Object]
    End Class
    Public Class [Int32]
    End Class
    Public Class [Boolean]
    End Class
    Public Class [String]
    End Class
    Public Class Exception
    End Class
    Public Class NotSupportedException
        Inherits Exception
    End Class
    Public Class ValueType
    End Class
    Public Class [Enum]
    End Class
    Public Class Void
    End Class
    Public Interface IDisposable
        Sub Dispose()
    End Interface
End Namespace
Namespace System.Collections
    Public Interface IEnumerable
        Function GetEnumerator() As IEnumerator
    End Interface
    Public Interface IEnumerator
        Function MoveNext() As Boolean
        Property Current As Object
        Sub Reset()
    End Interface
    Namespace Generic
        Public Interface IEnumerable(Of T)
            Inherits IEnumerable
            Overloads Function GetEnumerator() As IEnumerator(Of T)
        End Interface
        Public Interface IEnumerator(Of T)
            Inherits IEnumerator
            Overloads Property Current As T
        End Interface
    End Namespace
End Namespace
Namespace System.Threading
    Public Class Thread
        Shared Property CurrentThread As Thread
        Property ManagedThreadId As Integer
    End Class
End Namespace
"
#End Region

            Dim source = "
Class C
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
        Yield Nothing
    End Function
End Class
"
            ' The compilation succeeds even though CompilerGeneratedAttribute and DebuggerNonUserCodeAttribute are not available.
            Dim compilation = CompilationUtils.CreateEmptyCompilation({Parse(source), Parse(corlib)})
            Dim verifier = CompileAndVerify(compilation, verify:=Verification.Fails)
            verifier.VerifyDiagnostics()
        End Sub

        <Fact, WorkItem(9463, "https://github.com/dotnet/roslyn/issues/9463")>
        Public Sub IEnumerableIteratorReportsDiagnosticsWhenCoreTypesAreMissing()
            ' Note that IDisposable.Dispose, IEnumerator.Current and other types are missing
            ' Also, IEnumerator(Of T) doesn't have a get accessor
            Dim source = "
Namespace System
    Public Class [Object]
    End Class
    Public Class [Int32]
    End Class
    Public Class [Boolean]
    End Class
    Public Class [String]
    End Class
    Public Class Exception
    End Class
    Public Class ValueType
    End Class
    Public Class [Enum]
    End Class
    Public Class Void
    End Class
    Public Interface IDisposable
    End Interface
End Namespace

Namespace System.Collections
    Public Interface IEnumerable
    End Interface
    Public Interface IEnumerator
    End Interface
End Namespace

Namespace System.Collections.Generic
    Public Interface IEnumerator(Of T)
        WriteOnly Property Current As T
    End Interface
End Namespace

Class C
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
        Yield Nothing
    End Function
End Class
"
            Dim compilation = CreateEmptyCompilation({Parse(source)})

            compilation.AssertTheseEmitDiagnostics(<expected>
BC30002: Type 'System.Collections.Generic.IEnumerable' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC30524: Property 'System.Collections.Generic.IEnumerator(Of T).Current' is 'WriteOnly'.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.Generic.IEnumerable`1.GetEnumerator' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerable.GetEnumerator' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.Current' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.MoveNext' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.Reset' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.IDisposable.Dispose' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                </expected>)
        End Sub

        <Fact, WorkItem(9463, "https://github.com/dotnet/roslyn/issues/9463")>
        Public Sub IEnumeratorIteratorReportsDiagnosticsWhenCoreTypesAreMissing()
            ' Note that IDisposable.Dispose and other types are missing
            ' Also IEnumerator.Current lacks a get accessor
            Dim source = "
Namespace System
    Public Class [Object]
    End Class
    Public Class [Int32]
    End Class
    Public Class [Boolean]
    End Class
    Public Class [String]
    End Class
    Public Class Exception
    End Class
    Public Class ValueType
    End Class
    Public Class [Enum]
    End Class
    Public Class Void
    End Class
    Public Interface IDisposable
    End Interface
End Namespace

Namespace System.Collections
    Public Interface IEnumerable
    End Interface
    Public Interface IEnumerator
        WriteOnly Property Current As Object
    End Interface
End Namespace

Class C
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
        Yield Nothing
    End Function
End Class
"
            Dim compilation = CreateEmptyCompilation({Parse(source)})

            ' No error about IEnumerable
            compilation.AssertTheseEmitDiagnostics(<expected>
BC30002: Type 'System.Collections.Generic.IEnumerator' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC30524: Property 'System.Collections.IEnumerator.Current' is 'WriteOnly'.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.Generic.IEnumerator`1.Current' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.MoveNext' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.Collections.IEnumerator.Reset' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC35000: Requested operation is not available because the runtime library function 'System.IDisposable.Dispose' is not defined.
    Public Iterator Function SomeNumbers() As System.Collections.IEnumerator
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                </expected>)
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_YieldReturn()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        enumerator.Dispose()
        Console.Write("disposed ")

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of String)
        Yield " one "
        Yield " two "
    End Function
End Class
    </file>
</compilation>

            Dim verifier = CompileAndVerify(source, expectedOutput:="True one disposed False one")
            verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.Dispose()", "
{
  // Code size        9 (0x9)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.s   -2
  IL_0003:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0008:  ret
}
")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_YieldReturn_IEnumerable()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.Produce().GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        enumerator.Dispose()
        Console.Write("disposed ")

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce() As System.Collections.Generic.IEnumerable(Of String)
        Yield " one "
        Yield " two "
    End Function
End Class
    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="True one disposed False one")

            ' Verify GetEnumerator
            Dim source2 =
<compilation>
    <file name="a2.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerable = C.Produce()
        Dim enumerator = enumerable.GetEnumerator()

        Console.Write(Object.ReferenceEquals(enumerable, enumerator))
        Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))

        Console.Write(enumerator.MoveNext())
        Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))

        enumerator.Dispose()

        Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))

        enumerator.Dispose()
        enumerator.Dispose()

        Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce() As System.Collections.Generic.IEnumerable(Of Integer)
        Yield 42
        Yield 43
    End Function
End Class
    </file>
</compilation>

            CompileAndVerify(source2, expectedOutput:="TrueTrueTrueTrueTrueTrue")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_DisposeTwice()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        enumerator.Dispose()
        Console.Write("disposed ")

        enumerator.Dispose()
        Console.Write("disposed2 ")

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of String)
        Dim local As String = ""
        Yield " one "
        local.ToString()
    End Function
End Class
    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="True one disposed disposed2 False one")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_YieldBreak()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator(True)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
        Yield " one "
        If b Then
            Return
        End If
        Yield " two "
    End Function
End Class
    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="True one False one False one")

            ' Verify GetEnumerator
            Dim source2 =
<compilation>
    <file name="a2.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerable = C.Produce(True)
        Dim enumerator = enumerable.GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))

        Console.Write(Not enumerator.MoveNext())
        Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce(b As Boolean) As System.Collections.Generic.IEnumerable(Of Integer)
        Yield 42
        If b Then
            Return
        End If
        Yield 43
    End Function
End Class
    </file>
</compilation>

            ' We're not setting the state to "after"/"finished"
            ' Tracked by https://github.com/dotnet/roslyn/issues/76089
            CompileAndVerify(source2, expectedOutput:="TrueTrueTrueFalse")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_EndOfBody()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator(True)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
        Yield " one "
        Console.Write("done ")
    End Function
End Class
    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="True one done False one False one")

            ' Verify GetEnumerator
            Dim source2 =
<compilation>
    <file name="a2.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerable = C.Produce(True)
        Dim enumerator = enumerable.GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))

        Console.Write(Not enumerator.MoveNext())
        Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce(b As Boolean) As System.Collections.Generic.IEnumerable(Of Integer)
        Yield 42
    End Function
End Class
    </file>
</compilation>

            ' We're not setting the state to "after"/"finished"
            ' Tracked by https://github.com/dotnet/roslyn/issues/76089
            CompileAndVerify(source2, expectedOutput:="TrueTrueTrueFalse")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_ThrowException()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator(True)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Try
            Console.Write(enumerator.MoveNext())
        Catch e As Exception
            Console.Write(e.Message)
        End Try

        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
        Yield " one "
        Throw New Exception("exception")
    End Function
End Class
    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="True one exception one False one")

            ' Verify GetEnumerator
            Dim source2 =
<compilation>
    <file name="a2.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerable = C.Produce()
        Dim enumerator = enumerable.GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))

        Try
            enumerator.MoveNext()
        Catch
            Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
        End Try
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce() As System.Collections.Generic.IEnumerable(Of Integer)
        Yield 42
        Throw New Exception("exception")
    End Function
End Class
    </file>
</compilation>

            ' We're not setting the state to "after"/"finished"
            ' Tracked by https://github.com/dotnet/roslyn/issues/76089
            CompileAndVerify(source2, expectedOutput:="TrueTrueFalse")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_YieldReturn_InTryFinally()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Console.Write("disposing ")
        Try
            enumerator.Dispose()
        Catch e As Exception
            Console.Write(e.Message)
        End Try
        Console.Write(" disposed ")

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of String)
        Try
            Yield " one "
        Finally
            Throw New Exception("exception")
        End Try
    End Function
End Class
    </file>
</compilation>

            Dim verifier = CompileAndVerify(source, expectedOutput:="True one disposing exception disposed False one")
            verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.Dispose()", "
{
  // Code size       44 (0x2c)
  .maxstack  2
  .locals init (Integer V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.1
  IL_0009:  bne.un.s   IL_0015
  IL_000b:  ldarg.0
  IL_000c:  ldc.i4.s   -3
  IL_000e:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0013:  br.s       IL_001c
  IL_0015:  ldarg.0
  IL_0016:  ldc.i4.m1
  IL_0017:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_001c:  ldarg.0
  IL_001d:  call       ""Function C.VB$StateMachine_1_GetEnumerator.MoveNext() As Boolean""
  IL_0022:  pop
  IL_0023:  ldarg.0
  IL_0024:  ldc.i4.s   -2
  IL_0026:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_002b:  ret
}
")

            ' Verify GetEnumerator
            Dim source2 =
<compilation>
    <file name="a2.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerable = C.Produce()
        Dim enumerator = enumerable.GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))

        Try
            enumerator.Dispose()
        Catch
            Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
        End Try
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce() As System.Collections.Generic.IEnumerable(Of Integer)
        Try
            Yield 42
        Finally
            Throw New Exception("exception")
        End Try
    End Function
End Class
    </file>
</compilation>

            ' We're not setting the state to "after"/"finished"
            ' Tracked by https://github.com/dotnet/roslyn/issues/76089
            CompileAndVerify(source2, expectedOutput:="TrueTrueFalse")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_YieldBreak_InTryFinally()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator(True)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
        Yield " one "
        Try
            If b Then
                Return
            End If
        Finally
            Console.Write("finally ")
        End Try
        Yield " two "
    End Function
End Class
    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="True one finally False one False one")

            ' Verify GetEnumerator
            Dim source2 =
<compilation>
    <file name="a2.vb">
Imports System
Imports System.Collections.Generic

Module Program
    Sub Main()
        Dim enumerable = C.Produce(True)
        Dim enumerator = enumerable.GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(Not Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))

        Console.Write(Not enumerator.MoveNext())
        Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce(b As Boolean) As IEnumerable(Of Integer)
        Yield 42
        Try
            If b Then
                Exit Function
            End If
        Finally
            Console.Write(" finally ")
        End Try
        Yield 43
    End Function
End Class
    </file>
</compilation>

            ' We're not setting the state to "after"/"finished"
            ' Tracked by https://github.com/dotnet/roslyn/issues/76089
            CompileAndVerify(source2, expectedOutput:="TrueTrue finally TrueFalse")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_ThrowException_InTryFinally()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator(True)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Try
            Console.Write(enumerator.MoveNext())
        Catch e As Exception
            Console.Write(e.Message)
        End Try

        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        enumerator.Dispose()

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
        Yield " one "
        Try
            Throw New Exception("exception")
        Finally
            Console.Write("finally ")
        End Try
    End Function
End Class
    </file>
</compilation>

            CompileAndVerify(source, expectedOutput:="True one finally exception one False one False one")

            ' Verify GetEnumerator
            Dim source2 =
<compilation>
    <file name="a2.vb">
Imports System
Imports System.Collections.Generic

Module Program
    Sub Main()
        Dim enumerable = C.Produce()
        Dim enumerator = enumerable.GetEnumerator()

        Console.Write(enumerator.MoveNext())

        Try
            enumerator.MoveNext()
        Catch ex As Exception
            Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
        End Try

        enumerator.Dispose()
        Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce() As IEnumerable(Of Integer)
        Yield 42
        Try
            Throw New Exception("exception")
        Finally
            Console.Write(" finally ")
        End Try
    End Function
End Class
    </file>
</compilation>

            ' We're not setting the state to "after"/"finished"
            ' Tracked by https://github.com/dotnet/roslyn/issues/76089
            CompileAndVerify(source2, expectedOutput:="True finally FalseTrue")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_ThrowException_InTryFinally_WithYieldInTry()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator(True)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Try
            Console.Write(enumerator.MoveNext())
        Catch e As Exception
            Console.Write(e.Message)
        End Try

        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator(b As Boolean) As System.Collections.Generic.IEnumerator(Of String)
        Try
            Yield " one "
            If b Then
                Throw New Exception("exception")
            End If
        Finally
            Console.Write("finally ")
        End Try
    End Function
End Class
    </file>
</compilation>

            Dim verifier = CompileAndVerify(source, expectedOutput:="True one finally exception one False one")
            verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.Dispose()", "
{
  // Code size       44 (0x2c)
  .maxstack  2
  .locals init (Integer V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.1
  IL_0009:  bne.un.s   IL_0015
  IL_000b:  ldarg.0
  IL_000c:  ldc.i4.s   -3
  IL_000e:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0013:  br.s       IL_001c
  IL_0015:  ldarg.0
  IL_0016:  ldc.i4.m1
  IL_0017:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_001c:  ldarg.0
  IL_001d:  call       ""Function C.VB$StateMachine_1_GetEnumerator.MoveNext() As Boolean""
  IL_0022:  pop
  IL_0023:  ldarg.0
  IL_0024:  ldc.i4.s   -2
  IL_0026:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_002b:  ret
}
")

            ' Verify GetEnumerator
            Dim source2 =
<compilation>
    <file name="a2.vb">
Imports System
Imports System.Collections.Generic

Module Program
    Sub Main()
        Dim enumerable = C.Produce()
        Dim enumerator = enumerable.GetEnumerator()

        Console.Write(enumerator.MoveNext())

        Try
            enumerator.MoveNext()
        Catch ex As Exception
            Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
        End Try
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce() As IEnumerable(Of Integer)
        Try
            Yield 42
            Throw New Exception("exception")
        Finally
            Console.Write(" finally ")
        End Try
    End Function
End Class
    </file>
</compilation>

            ' We're not setting the state to "after"/"finished"
            ' Tracked by https://github.com/dotnet/roslyn/issues/76089
            CompileAndVerify(source2, expectedOutput:="True finally False")
        End Sub

        <Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76078")>
        Public Sub StateAfterMoveNext_YieldReturn_AfterTryFinally()
            Dim source =
<compilation>
    <file name="a.vb">
Imports System
Imports System.Collections.Generic

Module Program
    Sub Main()
        Dim enumerator = C.GetEnumerator(True)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)

        enumerator.Dispose()

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.Current)
    End Sub
End Module

Class C
    Public Shared Iterator Function GetEnumerator(b As Boolean) As IEnumerator(Of String)
        Try
            Yield " one "
        Finally
            Console.Write("finally ")
        End Try

        Yield " two "
        Console.Write("not executed after disposal")
    End Function
End Class
    </file>
</compilation>
            Dim verifier = CompileAndVerify(source, expectedOutput:="True one finally True two False two")
            verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.MoveNext()", "
{
  // Code size      171 (0xab)
  .maxstack  3
  .locals init (Boolean V_0,
                Integer V_1)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0006:  stloc.1
  IL_0007:  ldloc.1
  IL_0008:  ldc.i4.s   -3
  IL_000a:  sub
  IL_000b:  switch    (
        IL_0033,
        IL_0028,
        IL_0028,
        IL_002a,
        IL_0033,
        IL_0094)
  IL_0028:  ldc.i4.0
  IL_0029:  ret
  IL_002a:  ldarg.0
  IL_002b:  ldc.i4.m1
  IL_002c:  dup
  IL_002d:  stloc.1
  IL_002e:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0033:  nop
  .try
  {
    IL_0034:  ldloc.1
    IL_0035:  ldc.i4.s   -3
    IL_0037:  beq.s      IL_003f
    IL_0039:  ldloc.1
    IL_003a:  ldc.i4.1
    IL_003b:  beq.s      IL_0064
    IL_003d:  br.s       IL_004c
    IL_003f:  ldarg.0
    IL_0040:  ldc.i4.m1
    IL_0041:  dup
    IL_0042:  stloc.1
    IL_0043:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
    IL_0048:  ldc.i4.1
    IL_0049:  stloc.0
    IL_004a:  leave.s    IL_00a9
    IL_004c:  ldarg.0
    IL_004d:  ldstr      "" one ""
    IL_0052:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$Current As String""
    IL_0057:  ldarg.0
    IL_0058:  ldc.i4.1
    IL_0059:  dup
    IL_005a:  stloc.1
    IL_005b:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
    IL_0060:  ldc.i4.1
    IL_0061:  stloc.0
    IL_0062:  leave.s    IL_00a9
    IL_0064:  ldarg.0
    IL_0065:  ldc.i4.m1
    IL_0066:  dup
    IL_0067:  stloc.1
    IL_0068:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
    IL_006d:  leave.s    IL_007e
  }
  finally
  {
    IL_006f:  ldloc.1
    IL_0070:  ldc.i4.0
    IL_0071:  bge.s      IL_007d
    IL_0073:  ldstr      ""finally ""
    IL_0078:  call       ""Sub System.Console.Write(String)""
    IL_007d:  endfinally
  }
  IL_007e:  ldarg.0
  IL_007f:  ldstr      "" two ""
  IL_0084:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$Current As String""
  IL_0089:  ldarg.0
  IL_008a:  ldc.i4.2
  IL_008b:  dup
  IL_008c:  stloc.1
  IL_008d:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0092:  ldc.i4.1
  IL_0093:  ret
  IL_0094:  ldarg.0
  IL_0095:  ldc.i4.m1
  IL_0096:  dup
  IL_0097:  stloc.1
  IL_0098:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_009d:  ldstr      ""not executed after disposal""
  IL_00a2:  call       ""Sub System.Console.Write(String)""
  IL_00a7:  ldc.i4.0
  IL_00a8:  ret
  IL_00a9:  ldloc.0
  IL_00aa:  ret
}
")
            verifier.VerifyIL("C.VB$StateMachine_1_GetEnumerator.Dispose()", "
{
  // Code size       44 (0x2c)
  .maxstack  2
  .locals init (Integer V_0)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.1
  IL_0009:  bne.un.s   IL_0015
  IL_000b:  ldarg.0
  IL_000c:  ldc.i4.s   -3
  IL_000e:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_0013:  br.s       IL_001c
  IL_0015:  ldarg.0
  IL_0016:  ldc.i4.m1
  IL_0017:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_001c:  ldarg.0
  IL_001d:  call       ""Function C.VB$StateMachine_1_GetEnumerator.MoveNext() As Boolean""
  IL_0022:  pop
  IL_0023:  ldarg.0
  IL_0024:  ldc.i4.s   -2
  IL_0026:  stfld      ""C.VB$StateMachine_1_GetEnumerator.$State As Integer""
  IL_002b:  ret
}
")

            ' Verify GetEnumerator
            Dim source2 =
<compilation>
    <file name="a2.vb">
Imports System
Imports System.Collections.Generic

Module Program
    Sub Main()
        Dim enumerable = C.Produce()
        Dim enumerator = enumerable.GetEnumerator()

        Console.Write(enumerator.MoveNext())
        Console.Write(enumerator.MoveNext())

        enumerator.Dispose()
        Console.Write(Object.ReferenceEquals(enumerable, enumerable.GetEnumerator()))
    End Sub
End Module

Class C
    Public Shared Iterator Function Produce() As IEnumerable(Of Integer)
        Try
            Yield 42
        Finally
            Console.Write(" finally ")
        End Try

        Yield 43
        Console.Write("not executed after disposal")
    End Function
End Class
    </file>
</compilation>

            CompileAndVerify(source2, expectedOutput:="True finally TrueTrue")
        End Sub
    End Class
End Namespace
