/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenIfOperator.vb
2 017 строк
56 KB
Tomáš Matoušek
Refactoring of extension methods in source packages (#78620) - take 2 (#78894)
26 июн 2025, 18:42
Не верифицирован
26 июн 2025, 18:42
05fc006
Код
Авторство
О чём код?
' 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 Roslyn.Test.Utilities Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests Public Class CodeGenIfOperator Inherits BasicTestBase <Fact, WorkItem(61483, "https://github.com/dotnet/roslyn/issues/61483")> Public Sub Branchless_Compare() Dim source = <compilation> <file name="a.vb"><![CDATA[ Imports System.Console Module C Sub Main() WriteLine(Comp(1, 2)) WriteLine(Comp(3, 3)) WriteLine(Comp(5, 4)) End Sub Function Comp(x As Integer, y As Integer) As Integer Dim tmp1 As Integer = If(x > y, 1, 0) Dim tmp2 As Integer = If(x < y, 1, 0) Return tmp1 - tmp2 End Function End Module ]]></file> </compilation> Dim expectedOutput = <![CDATA[ -1 0 1 ]]> Dim verifier = CompileAndVerify(source, expectedOutput, options:=TestOptions.DebugExe) verifier.VerifyDiagnostics() verifier.VerifyMethodBody("C.Comp", <![CDATA[ { // Code size 27 (0x1b) .maxstack 2 .locals init (Integer V_0, //Comp Integer V_1, //tmp1 Integer V_2) //tmp2 // sequence point: Function Comp(x As Integer, y As Integer) As Integer IL_0000: nop // sequence point: tmp1 As Integer = If(x > y, 1, 0) IL_0001: ldarg.0 IL_0002: ldarg.1 IL_0003: bgt.s IL_0008 IL_0005: ldc.i4.0 IL_0006: br.s IL_0009 IL_0008: ldc.i4.1 IL_0009: stloc.1 // sequence point: tmp2 As Integer = If(x < y, 1, 0) IL_000a: ldarg.0 IL_000b: ldarg.1 IL_000c: blt.s IL_0011 IL_000e: ldc.i4.0 IL_000f: br.s IL_0012 IL_0011: ldc.i4.1 IL_0012: stloc.2 // sequence point: Return tmp1 - tmp2 IL_0013: ldloc.1 IL_0014: ldloc.2 IL_0015: sub.ovf IL_0016: stloc.0 IL_0017: br.s IL_0019 // sequence point: End Function IL_0019: ldloc.0 IL_001a: ret } ]]>.Value) verifier = CompileAndVerify(source, expectedOutput, options:=TestOptions.ReleaseExe) verifier.VerifyDiagnostics() verifier.VerifyMethodBody("C.Comp", <![CDATA[ { // Code size 12 (0xc) .maxstack 3 .locals init (Integer V_0) //tmp2 // sequence point: tmp1 As Integer = If(x > y, 1, 0) IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: cgt // sequence point: tmp2 As Integer = If(x < y, 1, 0) IL_0004: ldarg.0 IL_0005: ldarg.1 IL_0006: clt IL_0008: stloc.0 // sequence point: Return tmp1 - tmp2 IL_0009: ldloc.0 IL_000a: sub.ovf // sequence point: End Function IL_000b: ret } ]]>.Value) verifier = CompileAndVerify(source, expectedOutput, options:=TestOptions.ReleaseExe.WithDebugPlusMode(True)) verifier.VerifyDiagnostics() verifier.VerifyMethodBody("C.Comp", <![CDATA[ { // Code size 16 (0x10) .maxstack 2 .locals init (Integer V_0, //Comp Integer V_1, //tmp1 Integer V_2) //tmp2 // sequence point: tmp1 As Integer = If(x > y, 1, 0) IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: cgt IL_0004: stloc.1 // sequence point: tmp2 As Integer = If(x < y, 1, 0) IL_0005: ldarg.0 IL_0006: ldarg.1 IL_0007: clt IL_0009: stloc.2 // sequence point: Return tmp1 - tmp2 IL_000a: ldloc.1 IL_000b: ldloc.2 IL_000c: sub.ovf IL_000d: stloc.0 // sequence point: End Function IL_000e: ldloc.0 IL_000f: ret } ]]>.Value) End Sub <Fact, WorkItem(61483, "https://github.com/dotnet/roslyn/issues/61483")> Public Sub Branchless_Operations() Dim verifier = CompileAndVerify( <compilation> <file name="a.vb"><![CDATA[ Imports Microsoft.VisualBasic Imports System.Console Module C Sub Main() M(1, 0, Nothing, True) End Sub Sub M(x As Integer, y As Integer, a As Object, b As Boolean) Write(If(x = y, 1, 0)) Write(If(x = y, 0, 1)) Write(If(x < y, 1, 0)) Write(If(x < y, 0, 1)) Write(If(x > y, 1, 0)) Write(If(x > y, 0, 1)) Write(If(a Is a, 0, 1)) Write(If(a IsNot a, 0, 1)) Write(If(TypeOf a Is Decimal, 0, 1)) Write(If(TypeOf a IsNot Decimal, 0, 1)) Write(If(b, 0, 1)) Write(If(Not b, 0, 1)) Write(If(x <= y, True, False)) Write(If(x <= y, False, True)) Write(If(x <> y, CByte(1), CByte(0))) Write(If(x <> y, CSByte(1), CSByte(0))) Write(If(x <> y, 1S, 0S)) Write(If(x <> y, 1US, 0US)) Write(If(x <> y, 1UI, 0UI)) Write(If(x <> y, 1L, 0L)) Write(If(x <> y, 1UL, 0UL)) Write(If(x < y, ChrW(0), ChrW(1))) Write(If(x < y, ChrW(1), vbNullChar)) Write(If(True, 1, 0)) Write(If(False, 0, 1)) Const B2 As Boolean = True Write(If(B2, 1, 0)) End Sub End Module ]]></file> </compilation>, options:=TestOptions.ReleaseExe, expectedOutput:="010110011001FalseTrue1111111" & ChrW(1) & ChrW(0) & "111") verifier.VerifyDiagnostics() verifier.VerifyMethodBody("C.M", <![CDATA[ { // Code size 294 (0x126) .maxstack 2 // sequence point: Write(If(x = y, 1, 0)) IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: ceq IL_0004: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x = y, 0, 1)) IL_0009: ldarg.0 IL_000a: ldarg.1 IL_000b: ceq IL_000d: ldc.i4.0 IL_000e: ceq IL_0010: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x < y, 1, 0)) IL_0015: ldarg.0 IL_0016: ldarg.1 IL_0017: clt IL_0019: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x < y, 0, 1)) IL_001e: ldarg.0 IL_001f: ldarg.1 IL_0020: clt IL_0022: ldc.i4.0 IL_0023: ceq IL_0025: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x > y, 1, 0)) IL_002a: ldarg.0 IL_002b: ldarg.1 IL_002c: cgt IL_002e: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x > y, 0, 1)) IL_0033: ldarg.0 IL_0034: ldarg.1 IL_0035: cgt IL_0037: ldc.i4.0 IL_0038: ceq IL_003a: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(a Is a, 0, 1)) IL_003f: ldarg.2 IL_0040: ldarg.2 IL_0041: ceq IL_0043: ldc.i4.0 IL_0044: ceq IL_0046: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(a IsNot a, 0, 1)) IL_004b: ldarg.2 IL_004c: ldarg.2 IL_004d: ceq IL_004f: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(TypeOf a Is Decimal, 0, 1)) IL_0054: ldarg.2 IL_0055: isinst "Decimal" IL_005a: ldnull IL_005b: ceq IL_005d: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(TypeOf a IsNot Decimal, 0, 1)) IL_0062: ldarg.2 IL_0063: isinst "Decimal" IL_0068: ldnull IL_0069: cgt.un IL_006b: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(b, 0, 1)) IL_0070: ldarg.3 IL_0071: ldc.i4.0 IL_0072: ceq IL_0074: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not b, 0, 1)) IL_0079: ldarg.3 IL_007a: ldc.i4.0 IL_007b: cgt.un IL_007d: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x <= y, True, False)) IL_0082: ldarg.0 IL_0083: ldarg.1 IL_0084: cgt IL_0086: ldc.i4.0 IL_0087: ceq IL_0089: call "Sub System.Console.Write(Boolean)" // sequence point: Write(If(x <= y, False, True)) IL_008e: ldarg.0 IL_008f: ldarg.1 IL_0090: cgt IL_0092: call "Sub System.Console.Write(Boolean)" // sequence point: Write(If(x <> y, CByte(1), CByte(0))) IL_0097: ldarg.0 IL_0098: ldarg.1 IL_0099: ceq IL_009b: ldc.i4.0 IL_009c: ceq IL_009e: conv.u1 IL_009f: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x <> y, CSByte(1), CSByte(0))) IL_00a4: ldarg.0 IL_00a5: ldarg.1 IL_00a6: ceq IL_00a8: ldc.i4.0 IL_00a9: ceq IL_00ab: conv.i1 IL_00ac: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x <> y, 1S, 0S)) IL_00b1: ldarg.0 IL_00b2: ldarg.1 IL_00b3: ceq IL_00b5: ldc.i4.0 IL_00b6: ceq IL_00b8: conv.i2 IL_00b9: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x <> y, 1US, 0US)) IL_00be: ldarg.0 IL_00bf: ldarg.1 IL_00c0: ceq IL_00c2: ldc.i4.0 IL_00c3: ceq IL_00c5: conv.u2 IL_00c6: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x <> y, 1UI, 0UI)) IL_00cb: ldarg.0 IL_00cc: ldarg.1 IL_00cd: ceq IL_00cf: ldc.i4.0 IL_00d0: ceq IL_00d2: call "Sub System.Console.Write(UInteger)" // sequence point: Write(If(x <> y, 1L, 0L)) IL_00d7: ldarg.0 IL_00d8: ldarg.1 IL_00d9: ceq IL_00db: ldc.i4.0 IL_00dc: ceq IL_00de: conv.i8 IL_00df: call "Sub System.Console.Write(Long)" // sequence point: Write(If(x <> y, 1UL, 0UL)) IL_00e4: ldarg.0 IL_00e5: ldarg.1 IL_00e6: ceq IL_00e8: ldc.i4.0 IL_00e9: ceq IL_00eb: conv.i8 IL_00ec: call "Sub System.Console.Write(ULong)" // sequence point: Write(If(x < y, ChrW(0), ChrW(1))) IL_00f1: ldarg.0 IL_00f2: ldarg.1 IL_00f3: clt IL_00f5: ldc.i4.0 IL_00f6: ceq IL_00f8: conv.u2 IL_00f9: call "Sub System.Console.Write(Char)" // sequence point: Write(If(x < y, ChrW(1), vbNullChar)) IL_00fe: ldarg.0 IL_00ff: ldarg.1 IL_0100: blt.s IL_0109 IL_0102: ldstr "]]>.Value & ChrW(0) & <![CDATA[" IL_0107: br.s IL_010e IL_0109: ldstr "]]>.Value & ChrW(1) & <![CDATA[" IL_010e: call "Sub System.Console.Write(String)" // sequence point: Write(If(True, 1, 0)) IL_0113: ldc.i4.1 IL_0114: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(False, 0, 1)) IL_0119: ldc.i4.1 IL_011a: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(B2, 1, 0)) IL_011f: ldc.i4.1 IL_0120: call "Sub System.Console.Write(Integer)" // sequence point: End Sub IL_0125: ret } ]]>.Value) End Sub <Fact, WorkItem(61483, "https://github.com/dotnet/roslyn/issues/61483")> Public Sub Branchless_Negations() Dim verifier = CompileAndVerify( <compilation> <file name="a.vb"><![CDATA[ Imports System.Console Module C Sub Main() M(1, 0, True) End Sub Sub M(x As Integer, y As Integer, b As Boolean) Write(If(Not (x < y), 0, 1)) Write(If(Not Not (x < y), 0, 1)) Write(If(Not Not Not (x < y), 0, 1)) Write(If(Not (x = y), 0, 1)) Write(If(Not b, 0, 1)) Write(If(Not Not b, 0, 1)) Write(If(Not Not Not b, 0, 1)) Write(If(Not False, 0, 1)) Write(If(Not Not False, 0, 1)) Write(If(Not Not Not False, 0, 1)) End Sub End Module ]]></file> </compilation>, options:=TestOptions.ReleaseExe, expectedOutput:="0100101010") verifier.VerifyDiagnostics() verifier.VerifyMethodBody("C.M", <![CDATA[ { // Code size 85 (0x55) .maxstack 2 // sequence point: Write(If(Not (x < y), 0, 1)) IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: clt IL_0004: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not Not (x < y), 0, 1)) IL_0009: ldarg.0 IL_000a: ldarg.1 IL_000b: clt IL_000d: ldc.i4.0 IL_000e: ceq IL_0010: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not Not Not (x < y), 0, 1)) IL_0015: ldarg.0 IL_0016: ldarg.1 IL_0017: clt IL_0019: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not (x = y), 0, 1)) IL_001e: ldarg.0 IL_001f: ldarg.1 IL_0020: ceq IL_0022: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not b, 0, 1)) IL_0027: ldarg.2 IL_0028: ldc.i4.0 IL_0029: cgt.un IL_002b: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not Not b, 0, 1)) IL_0030: ldarg.2 IL_0031: ldc.i4.0 IL_0032: ceq IL_0034: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not Not Not b, 0, 1)) IL_0039: ldarg.2 IL_003a: ldc.i4.0 IL_003b: cgt.un IL_003d: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not False, 0, 1)) IL_0042: ldc.i4.0 IL_0043: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not Not False, 0, 1)) IL_0048: ldc.i4.1 IL_0049: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(Not Not Not False, 0, 1)) IL_004e: ldc.i4.0 IL_004f: call "Sub System.Console.Write(Integer)" // sequence point: End Sub IL_0054: ret } ]]>.Value) End Sub <Fact, WorkItem(61483, "https://github.com/dotnet/roslyn/issues/61483")> Public Sub Branchless_NonBinaryArms() Dim verifier = CompileAndVerify( <compilation> <file name="a.vb"><![CDATA[ Imports Microsoft.VisualBasic Imports System.Console Module C Sub Main() M(1, 0) End Sub Sub M(x As Integer, y As Integer) Write(If(x = y, 1, 1)) Write(If(x <> y, 0, 0)) Write(If(x <= y, 0, 2)) Write(If(x >= y, 2, 1)) Write(If(x < y, 0, -1)) Write(If(x < y, 0R, 1R)) Write(If(x < y, 0F, 1F)) Write(If(x < y, 0D, 1D)) Write(If(x < y, vbNullChar, "a"c)) End Sub End Module ]]></file> </compilation>, options:=TestOptions.ReleaseExe, expectedOutput:="1022-1111a") verifier.VerifyDiagnostics() verifier.VerifyMethodBody("C.M", <![CDATA[ { // Code size 158 (0x9e) .maxstack 2 // sequence point: Write(If(x = y, 1, 1)) IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: beq.s IL_0007 IL_0004: ldc.i4.1 IL_0005: br.s IL_0008 IL_0007: ldc.i4.1 IL_0008: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x <> y, 0, 0)) IL_000d: ldarg.0 IL_000e: ldarg.1 IL_000f: bne.un.s IL_0014 IL_0011: ldc.i4.0 IL_0012: br.s IL_0015 IL_0014: ldc.i4.0 IL_0015: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x <= y, 0, 2)) IL_001a: ldarg.0 IL_001b: ldarg.1 IL_001c: ble.s IL_0021 IL_001e: ldc.i4.2 IL_001f: br.s IL_0022 IL_0021: ldc.i4.0 IL_0022: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x >= y, 2, 1)) IL_0027: ldarg.0 IL_0028: ldarg.1 IL_0029: bge.s IL_002e IL_002b: ldc.i4.1 IL_002c: br.s IL_002f IL_002e: ldc.i4.2 IL_002f: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x < y, 0, -1)) IL_0034: ldarg.0 IL_0035: ldarg.1 IL_0036: blt.s IL_003b IL_0038: ldc.i4.m1 IL_0039: br.s IL_003c IL_003b: ldc.i4.0 IL_003c: call "Sub System.Console.Write(Integer)" // sequence point: Write(If(x < y, 0R, 1R)) IL_0041: ldarg.0 IL_0042: ldarg.1 IL_0043: blt.s IL_0050 IL_0045: ldc.r8 1 IL_004e: br.s IL_0059 IL_0050: ldc.r8 0 IL_0059: call "Sub System.Console.Write(Double)" // sequence point: Write(If(x < y, 0F, 1F)) IL_005e: ldarg.0 IL_005f: ldarg.1 IL_0060: blt.s IL_0069 IL_0062: ldc.r4 1 IL_0067: br.s IL_006e IL_0069: ldc.r4 0 IL_006e: call "Sub System.Console.Write(Single)" // sequence point: Write(If(x < y, 0D, 1D)) IL_0073: ldarg.0 IL_0074: ldarg.1 IL_0075: blt.s IL_007e IL_0077: ldsfld "Decimal.One As Decimal" IL_007c: br.s IL_0083 IL_007e: ldsfld "Decimal.Zero As Decimal" IL_0083: call "Sub System.Console.Write(Decimal)" // sequence point: Write(If(x < y, vbNullChar, "a"c)) IL_0088: ldarg.0 IL_0089: ldarg.1 IL_008a: blt.s IL_0093 IL_008c: ldstr "a" IL_0091: br.s IL_0098 IL_0093: ldstr "]]>.Value & ChrW(0) & <![CDATA[" IL_0098: call "Sub System.Console.Write(String)" // sequence point: End Sub IL_009d: ret } ]]>.Value) End Sub <Fact, WorkItem(61483, "https://github.com/dotnet/roslyn/issues/61483")> Public Sub Branchless_NonBinaryCondition() Dim comp = CreateCompilationWithCustomILSource( <compilation> <file name="a.vb"><![CDATA[ Imports System.Console Public Class D Public Shared Sub Main() Write(M1()) Write(M2()) End Sub Shared Function M1() As Integer Return If(C.M(), 1, 0) End Function Shared Function M2() As Integer Return If(C.M(), 0, 1) End Function End Class ]]></file> </compilation>, <![CDATA[ // public static class C { public static bool M() => -1; } .class public auto ansi abstract sealed beforefieldinit C extends System.Object { .method public hidebysig static bool M () cil managed { .maxstack 8 ldc.i4.m1 ret } } ]]>.Value, TestOptions.ReleaseExe) Dim verifier = CompileAndVerify(comp, expectedOutput:="10") verifier.VerifyDiagnostics() verifier.VerifyMethodBody("D.M1", <![CDATA[ { // Code size 9 (0x9) .maxstack 2 // sequence point: Return If(C.M(), 1, 0) IL_0000: call "Function C.M() As Boolean" IL_0005: ldc.i4.0 IL_0006: cgt.un // sequence point: End Function IL_0008: ret } ]]>.Value) verifier.VerifyMethodBody("D.M2", <![CDATA[ { // Code size 9 (0x9) .maxstack 2 // sequence point: Return If(C.M(), 0, 1) IL_0000: call "Function C.M() As Boolean" IL_0005: ldc.i4.0 IL_0006: ceq // sequence point: End Function IL_0008: ret } ]]>.Value) End Sub <Fact, WorkItem(61483, "https://github.com/dotnet/roslyn/issues/61483")> Public Sub Branchless_IntPtr() Dim verifier = CompileAndVerify( <compilation> <file name="a.vb"><![CDATA[ Imports System Imports System.Console Module C Sub Main() M(1, 0) End Sub Sub M(x As Integer, y As Integer) Write(If(x = y, CType(0, IntPtr), CType(1, IntPtr))) Write(If(x <> y, IntPtr.Zero, CType(1, IntPtr))) End Sub End Module ]]></file> </compilation>, options:=TestOptions.ReleaseExe, expectedOutput:="10") verifier.VerifyDiagnostics() verifier.VerifyMethodBody("C.M", <![CDATA[ { // Code size 56 (0x38) .maxstack 2 // sequence point: Write(If(x = y, CType(0, IntPtr), CType(1, IntPtr))) IL_0000: ldarg.0 IL_0001: ldarg.1 IL_0002: beq.s IL_000c IL_0004: ldc.i4.1 IL_0005: call "Function System.IntPtr.op_Explicit(Integer) As System.IntPtr" IL_000a: br.s IL_0012 IL_000c: ldc.i4.0 IL_000d: call "Function System.IntPtr.op_Explicit(Integer) As System.IntPtr" IL_0012: box "System.IntPtr" IL_0017: call "Sub System.Console.Write(Object)" // sequence point: Write(If(x <> y, IntPtr.Zero, CType(1, IntPtr))) IL_001c: ldarg.0 IL_001d: ldarg.1 IL_001e: bne.un.s IL_0028 IL_0020: ldc.i4.1 IL_0021: call "Function System.IntPtr.op_Explicit(Integer) As System.IntPtr" IL_0026: br.s IL_002d IL_0028: ldsfld "System.IntPtr.Zero As System.IntPtr" IL_002d: box "System.IntPtr" IL_0032: call "Sub System.Console.Write(Object)" // sequence point: End Sub IL_0037: ret } ]]>.Value) End Sub ' Conditional operator as parameter <Fact> Public Sub ConditionalOperatorAsParameter() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Imports System Module C Sub Main(args As String()) Dim a0 As Boolean = False Dim a1 As Integer = 0 Dim a2 As Long = 1 Dim b0 = a0 Dim b1 = a1 Dim b2 = a2 Console.WriteLine((If(b0, b1, b2)) <> (If(a0, a1, a2))) End Sub End Module </file> </compilation>, expectedOutput:=<![CDATA[ False ]]>).VerifyIL("C.Main", <![CDATA[ { // Code size 70 (0x46) .maxstack 3 .locals init (Boolean V_0, //a0 Integer V_1, //a1 Long V_2, //a2 Object V_3, //b1 Object V_4) //b2 IL_0000: ldc.i4.0 IL_0001: stloc.0 IL_0002: ldc.i4.0 IL_0003: stloc.1 IL_0004: ldc.i4.1 IL_0005: conv.i8 IL_0006: stloc.2 IL_0007: ldloc.0 IL_0008: box "Boolean" IL_000d: ldloc.1 IL_000e: box "Integer" IL_0013: stloc.3 IL_0014: ldloc.2 IL_0015: box "Long" IL_001a: stloc.s V_4 IL_001c: call "Function Microsoft.VisualBasic.CompilerServices.Conversions.ToBoolean(Object) As Boolean" IL_0021: brtrue.s IL_0027 IL_0023: ldloc.s V_4 IL_0025: br.s IL_0028 IL_0027: ldloc.3 IL_0028: ldloc.0 IL_0029: brtrue.s IL_002e IL_002b: ldloc.2 IL_002c: br.s IL_0030 IL_002e: ldloc.1 IL_002f: conv.i8 IL_0030: box "Long" IL_0035: ldc.i4.0 IL_0036: call "Function Microsoft.VisualBasic.CompilerServices.Operators.CompareObjectNotEqual(Object, Object, Boolean) As Object" IL_003b: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_0040: call "Sub System.Console.WriteLine(Object)" IL_0045: ret } ]]>).Compilation End Sub ' Function call in return expression <WorkItem(541647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541647")> <Fact()> Public Sub FunctionCallAsArgument() CompileAndVerify( <compilation> <file name="a.vb"> Imports System Module C Sub Main(args As String()) Dim z = If(True, fun_Exception(1), fun_int(1)) Dim r = If(True, fun_long(0), fun_int(1)) Dim s = If(False, fun_long(0), fun_int(1)) End Sub Private Function fun_int(x As Integer) As Integer Return x End Function Private Function fun_long(x As Integer) As Long Return CLng(x) End Function Private Function fun_Exception(x As Integer) As Exception Return New Exception() End Function End Module </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("C.Main", <![CDATA[ { // Code size 28 (0x1c) .maxstack 1 IL_0000: ldc.i4.1 IL_0001: call "Function C.fun_Exception(Integer) As System.Exception" IL_0006: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_000b: pop IL_000c: ldc.i4.0 IL_000d: call "Function C.fun_long(Integer) As Long" IL_0012: pop IL_0013: ldc.i4.1 IL_0014: call "Function C.fun_int(Integer) As Integer" IL_0019: conv.i8 IL_001a: pop IL_001b: ret }]]>) End Sub ' Lambda works in return argument <Fact()> Public Sub LambdaAsArgument_1() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Imports System Module C Sub Main(args As String()) Dim Y = 2 Dim S = If(True, _ Function(z As Integer) As Integer System.Console.WriteLine("SUB") Return z * z End Function, Y + 1) S = If(False, _ Sub(Z As Integer) System.Console.WriteLine("SUB") End Sub, Y + 1) System.Console.WriteLine(S) End Sub End Module </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("C.Main", <![CDATA[ { // Code size 77 (0x4d) .maxstack 2 .locals init (Object V_0) //Y IL_0000: ldc.i4.2 IL_0001: box "Integer" IL_0006: stloc.0 IL_0007: ldsfld "C._Closure$__.$I0-0 As <generated method>" IL_000c: brfalse.s IL_0015 IL_000e: ldsfld "C._Closure$__.$I0-0 As <generated method>" IL_0013: br.s IL_002b IL_0015: ldsfld "C._Closure$__.$I As C._Closure$__" IL_001a: ldftn "Function C._Closure$__._Lambda$__0-0(Integer) As Integer" IL_0020: newobj "Sub VB$AnonymousDelegate_0(Of Integer, Integer)..ctor(Object, System.IntPtr)" IL_0025: dup IL_0026: stsfld "C._Closure$__.$I0-0 As <generated method>" IL_002b: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_0030: pop IL_0031: ldloc.0 IL_0032: ldc.i4.1 IL_0033: box "Integer" IL_0038: call "Function Microsoft.VisualBasic.CompilerServices.Operators.AddObject(Object, Object) As Object" IL_003d: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_0042: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_0047: call "Sub System.Console.WriteLine(Object)" IL_004c: ret } ]]>).Compilation End Sub ' Conditional on expression tree <Fact()> Public Sub ExpressionTree() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer On Imports System Imports System.Linq.Expressions Module Program Sub Main(args As String()) Dim testExpr As Expression(Of Func(Of Boolean, Long, Integer, Long)) = Function(x, y, z) If(x, y, z) Dim testFunc = testExpr.Compile() Dim testResult = testFunc(False, CLng(3), 100) Console.WriteLine(testResult) End Sub End Module </file> </compilation>, expectedOutput:=<![CDATA[ 100 ]]>).Compilation End Sub ' Conditional on expression tree <Fact()> Public Sub ExpressionTree_2() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer on Imports System Imports System.Linq.Expressions Module Program Sub Main(args As String()) Dim testExpr As Expression(Of Func(Of TestStruct, Long?, Integer, Integer?)) = Function(x, y, z) If(x, y, z) Dim testFunc = testExpr.Compile() Dim testResult1 = testFunc(New TestStruct(), Nothing, 10) Dim testResult2 = testFunc(New TestStruct(), 10, Nothing) Console.WriteLine (testResult1) Console.WriteLine (testResult2) End Sub End Module Public Structure TestStruct Public Shared Operator IsTrue(ts As TestStruct) As Boolean Return False End Operator Public Shared Operator IsFalse(ts As TestStruct) As Boolean Return True End Operator End Structure </file> </compilation>, expectedOutput:=<![CDATA[ 10 0 ]]>).Compilation End Sub ' Multiple conditional operator in expression <Fact> Public Sub MultipleConditional() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Imports System Module C Sub Main(args As String()) Dim S = If(False, 1, If(True, 2, 3)) Console.Write(S) End Sub End Module </file> </compilation>, expectedOutput:=<![CDATA[ 2 ]]>).VerifyIL("C.Main", <![CDATA[ { // Code size 17 (0x11) .maxstack 1 IL_0000: ldc.i4.2 IL_0001: box "Integer" IL_0006: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_000b: call "Sub System.Console.Write(Object)" IL_0010: ret }]]>).Compilation End Sub ' Arguments are of types: bool, constant, enum <Fact> Public Sub EnumAsArguments() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Imports System Module C Sub Main(args As String()) Dim testResult = If(False, 0, color.Blue) Console.WriteLine(testResult) testResult = If(False, 5, color.Blue) Console.WriteLine(testResult) End Sub End Module Enum color Red Green Blue End Enum </file> </compilation>, expectedOutput:=<![CDATA[ 2 2 ]]>).VerifyIL("C.Main", <![CDATA[ { // Code size 33 (0x21) .maxstack 1 IL_0000: ldc.i4.2 IL_0001: box "Integer" IL_0006: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_000b: call "Sub System.Console.WriteLine(Object)" IL_0010: ldc.i4.2 IL_0011: box "Integer" IL_0016: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_001b: call "Sub System.Console.WriteLine(Object)" IL_0020: ret }]]>).Compilation End Sub ' Implicit type conversion on conditional <Fact> Public Sub ImplicitConversionForConditional() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Imports System Module C Sub Main(args As String()) Dim valueFromDatabase As Object Dim result As Decimal valueFromDatabase = DBNull.Value result = CDec(If(valueFromDatabase IsNot DBNull.Value, valueFromDatabase, 0)) Console.WriteLine(result) result = (If(valueFromDatabase IsNot DBNull.Value, CDec(valueFromDatabase), CDec(0))) Console.WriteLine(result) End Sub End Module </file> </compilation>, expectedOutput:=<![CDATA[ 0 0 ]]>).VerifyIL("C.Main", <![CDATA[ { // Code size 60 (0x3c) .maxstack 2 .locals init (Object V_0) //valueFromDatabase IL_0000: ldsfld "System.DBNull.Value As System.DBNull" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldsfld "System.DBNull.Value As System.DBNull" IL_000c: bne.un.s IL_0016 IL_000e: ldc.i4.0 IL_000f: box "Integer" IL_0014: br.s IL_0017 IL_0016: ldloc.0 IL_0017: call "Function Microsoft.VisualBasic.CompilerServices.Conversions.ToDecimal(Object) As Decimal" IL_001c: call "Sub System.Console.WriteLine(Decimal)" IL_0021: ldloc.0 IL_0022: ldsfld "System.DBNull.Value As System.DBNull" IL_0027: bne.un.s IL_0030 IL_0029: ldsfld "Decimal.Zero As Decimal" IL_002e: br.s IL_0036 IL_0030: ldloc.0 IL_0031: call "Function Microsoft.VisualBasic.CompilerServices.Conversions.ToDecimal(Object) As Decimal" IL_0036: call "Sub System.Console.WriteLine(Decimal)" IL_003b: ret }]]>).Compilation End Sub ' Not boolean type as conditional-argument <WorkItem(541647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541647")> <Fact()> Public Sub NotBooleanAsConditionalArgument() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Imports System Module C Sub Main(args As String()) Dim x = 1 Dim s = If("", x, 2) 'invalid s = If("True", x, 2) 'valid s = If("1", x, 2) 'valid End Sub End Module </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("C.Main", <![CDATA[ { // Code size 36 (0x24) .maxstack 1 .locals init (Integer V_0) //x IL_0000: ldc.i4.1 IL_0001: stloc.0 IL_0002: ldstr "" IL_0007: call "Function Microsoft.VisualBasic.CompilerServices.Conversions.ToBoolean(String) As Boolean" IL_000c: pop IL_000d: ldstr "True" IL_0012: call "Function Microsoft.VisualBasic.CompilerServices.Conversions.ToBoolean(String) As Boolean" IL_0017: pop IL_0018: ldstr "1" IL_001d: call "Function Microsoft.VisualBasic.CompilerServices.Conversions.ToBoolean(String) As Boolean" IL_0022: pop IL_0023: ret }]]>).Compilation End Sub ' Not boolean type as conditional-argument <WorkItem(541647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541647")> <Fact()> Public Sub NotBooleanAsConditionalArgument_2() CompileAndVerify( <compilation> <file name="a.vb"> Imports System Module C Sub Main(args As String()) Dim x = 1 Dim s = If(color.Green, x, 2) Console.WriteLine(S) s = If(color.Red, x, 2) Console.WriteLine(s) End Sub End Module Public Enum color Red Blue Green End Enum </file> </compilation>, expectedOutput:=<![CDATA[ 1 2 ]]>) End Sub <WorkItem(541647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541647")> <Fact> Public Sub FunctionWithNoReturnType() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Imports System Module C Sub Main(args As String()) Dim x = 1 Dim s = If(fun1(), x, 2) End Sub Private Function fun1() End Function End Module </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("C.Main", <![CDATA[ { // Code size 35 (0x23) .maxstack 1 .locals init (Object V_0) //x IL_0000: ldc.i4.1 IL_0001: box "Integer" IL_0006: stloc.0 IL_0007: call "Function C.fun1() As Object" IL_000c: call "Function Microsoft.VisualBasic.CompilerServices.Conversions.ToBoolean(Object) As Boolean" IL_0011: brtrue.s IL_001b IL_0013: ldc.i4.2 IL_0014: box "Integer" IL_0019: br.s IL_001c IL_001b: ldloc.0 IL_001c: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_0021: pop IL_0022: ret }]]>).Compilation End Sub ' Const as conditional- argument <WorkItem(541452, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541452")> <Fact()> Public Sub ConstAsArgument() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Imports System Module C Sub Main(args As String()) Const con As Boolean = True Dim s1 = If(con, 1, 2) Console.Write(s1) End Sub End Module </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("C.Main", <![CDATA[ { // Code size 7 (0x7) .maxstack 1 IL_0000: ldc.i4.1 IL_0001: call "Sub System.Console.Write(Integer)" IL_0006: ret } ]]>).Compilation End Sub ' Const i As Integer = IF <Fact> Public Sub AssignIfToConst() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Imports System Module Program Sub Main(args As String()) Const s As Integer = If(1>2, 9, 92) End Sub End Module </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("Program.Main", <![CDATA[ { // Code size 1 (0x1) .maxstack 0 IL_0000: ret }]]>).Compilation End Sub ' IF used in Redim <WorkItem(528563, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528563")> <Fact> Public Sub IfUsedInRedim() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Imports System Module Program Sub Main(args As String()) Dim s1 As Integer() ReDim Preserve s1(If(True, 10, 101)) End Sub End Module </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("Program.Main", <![CDATA[ { // Code size 20 (0x14) .maxstack 2 .locals init (Integer() V_0) //s1 IL_0000: ldloc.0 IL_0001: ldc.i4.s 11 IL_0003: newarr "Integer" IL_0008: call "Function Microsoft.VisualBasic.CompilerServices.Utils.CopyArray(System.Array, System.Array) As System.Array" IL_000d: castclass "Integer()" IL_0012: stloc.0 IL_0013: ret }]]>).Compilation End Sub ' IF on attribute <Fact> Public Sub IFOnAttribute() CompileAndVerify( <compilation> <file name="a.vb"> Imports System <Assembly: CLSCompliant(If(True, False, True))> Public Class base Public Shared sub Main() End Sub End Class </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyDiagnostics() End Sub ' #const val =if <Fact> Public Sub PredefinedConst() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Public Class Program Public Shared Sub Main() #Const ifconst = If(True, 1, 2) #If ifconst = 1 Then #End If End Sub End Class </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("Program.Main", <![CDATA[ { // Code size 1 (0x1) .maxstack 0 IL_0000: ret }]]>).Compilation End Sub ' IF as function name <Fact> Public Sub IFAsFunctionName() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Module M1 Sub Main() End Sub Public Function [if](ByVal arg As String) As String Return arg End Function End Module </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("M1.if", <![CDATA[ { // Code size 2 (0x2) .maxstack 1 IL_0000: ldarg.0 IL_0001: ret }]]>).Compilation End Sub ' IF as Optional parameter <Fact()> Public Sub IFAsOptionalParameter() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Module M1 Sub Main() goo() End Sub Public Sub goo(Optional ByVal arg As String = If(False, "6", "61")) System.Console.WriteLine(arg) End Sub End Module </file> </compilation>, expectedOutput:="61").Compilation End Sub ' IF used in For step <Fact()> Public Sub IFUsedInForStep() CompileAndVerify( <compilation> <file name="a.vb"> Module M1 Sub Main() Dim s10 As Boolean = False For c As Integer = 1 To 10 Step If(s10, 1, 2) Next End Sub End Module </file> </compilation>, options:=TestOptions.ReleaseExe) End Sub ' Passing IF as byref arg <WorkItem(541647, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541647")> <Fact()> Public Sub IFAsByrefArg() CompileAndVerify( <compilation> <file name="a.vb"> Module M1 Sub Main() Dim X = "123" Dim Y = "456" Dim Z = If(1 > 2, goo(X), goo(Y)) End Sub Private Function goo(ByRef p1 As String) p1 = "HELLO" End Function End Module </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("M1.Main", <![CDATA[ { // Code size 26 (0x1a) .maxstack 1 .locals init (String V_0, //X String V_1) //Y IL_0000: ldstr "123" IL_0005: stloc.0 IL_0006: ldstr "456" IL_000b: stloc.1 IL_000c: ldloca.s V_1 IL_000e: call "Function M1.goo(ByRef String) As Object" IL_0013: call "Function System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Object) As Object" IL_0018: pop IL_0019: ret }]]>) End Sub <WorkItem(541674, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541674")> <Fact> Public Sub TypeConversionInRuntime() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Imports System.Collections.Generic Public Class Test Private Shared Sub Main() Dim a As Integer() = New Integer() {} Dim b As New List(Of Integer)() Dim c As IEnumerable(Of Integer) = If(a.Length > 0, a, DirectCast(b, IEnumerable(Of Integer))) End Sub End Class </file> </compilation>, options:=TestOptions.ReleaseDll).VerifyIL("Test.Main", <![CDATA[ { // Code size 25 (0x19) .maxstack 2 .locals init (Integer() V_0, //a System.Collections.Generic.List(Of Integer) V_1) //b IL_0000: ldc.i4.0 IL_0001: newarr "Integer" IL_0006: stloc.0 IL_0007: newobj "Sub System.Collections.Generic.List(Of Integer)..ctor()" IL_000c: stloc.1 IL_000d: ldloc.0 IL_000e: ldlen IL_000f: conv.i4 IL_0010: ldc.i4.0 IL_0011: bgt.s IL_0016 IL_0013: ldloc.1 IL_0014: pop IL_0015: ret IL_0016: ldloc.0 IL_0017: pop IL_0018: ret } ]]>).Compilation End Sub <WorkItem(541673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541673")> <Fact> Public Sub TypeConversionInRuntime_1() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Public Interface IB Function f() As Integer End Interface Public Class AB1 Implements IB Public Function f() As Integer Implements IB.f Return 42 End Function End Class Public Class AB2 Implements IB Public Function f() As Integer Implements IB.f Return 1 End Function End Class Class MainClass Public Shared Sub g(p As Boolean) Dim x = (If(p, DirectCast(New AB1(), IB), DirectCast(New AB2(), IB))).f() End Sub Public Shared Sub Main() End Sub End Class </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("MainClass.g", <![CDATA[ { // Code size 29 (0x1d) .maxstack 1 .locals init (IB V_0) IL_0000: ldarg.0 IL_0001: brtrue.s IL_000a IL_0003: newobj "Sub AB2..ctor()" IL_0008: br.s IL_0011 IL_000a: newobj "Sub AB1..ctor()" IL_000f: stloc.0 IL_0010: ldloc.0 IL_0011: callvirt "Function IB.f() As Integer" IL_0016: box "Integer" IL_001b: pop IL_001c: ret }]]>).Compilation End Sub <Fact> Public Sub TypeConversionInRuntime_2() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Public Interface IB Function f() As Integer End Interface Public Class AB1 Implements IB Public Function f() As Integer Implements IB.f Return 42 End Function End Class Class MainClass Public Shared Sub g(p As Boolean) Dim x = (If(p, DirectCast(New AB1(), IB), DirectCast(New AB1(), IB))).f() End Sub Public Shared Sub Main() End Sub End Class </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("MainClass.g", <![CDATA[ { // Code size 29 (0x1d) .maxstack 1 .locals init (IB V_0) IL_0000: ldarg.0 IL_0001: brtrue.s IL_000a IL_0003: newobj "Sub AB1..ctor()" IL_0008: br.s IL_0011 IL_000a: newobj "Sub AB1..ctor()" IL_000f: stloc.0 IL_0010: ldloc.0 IL_0011: callvirt "Function IB.f() As Integer" IL_0016: box "Integer" IL_001b: pop IL_001c: ret }]]>).Compilation End Sub <Fact> Public Sub TypeConversionInRuntime_3() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Public Interface IB Function f() As Integer End Interface Public Class AB1 Implements IB Public Function f() As Integer Implements IB.f Return 42 End Function End Class Class MainClass Public Shared Sub g(p As Boolean) Dim x = (If(DirectCast(New AB1(), IB), DirectCast(New AB1(), IB))).f() End Sub Public Shared Sub Main() End Sub End Class </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("MainClass.g", <![CDATA[ { // Code size 28 (0x1c) .maxstack 2 .locals init (IB V_0) IL_0000: newobj "Sub AB1..ctor()" IL_0005: dup IL_0006: brtrue.s IL_0010 IL_0008: pop IL_0009: newobj "Sub AB1..ctor()" IL_000e: stloc.0 IL_000f: ldloc.0 IL_0010: callvirt "Function IB.f() As Integer" IL_0015: box "Integer" IL_001a: pop IL_001b: ret }]]>).Compilation End Sub <Fact> Public Sub TypeConversionInterface() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Interface IBase Function m1() As IBase End Interface Class Derived Public Shared mask As Integer = 1 End Class Class Test1 Implements IBase Private y As IBase Private x As IBase Private cnt As Integer = 0 Public Sub New(link As IBase) x = Me y = link If y Is Nothing Then y = Me End If End Sub Public Shared Sub Main() End Sub Public Function m1() As IBase Implements IBase.m1 Return If(Derived.mask = 0, x, y) End Function 'version1 (explicit impl in original repro) Public Function m2() As IBase Return If(Derived.mask = 0, Me, y) End Function 'version2 End Class </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("Test1.m1", <![CDATA[ { // Code size 21 (0x15) .maxstack 1 IL_0000: ldsfld "Derived.mask As Integer" IL_0005: brfalse.s IL_000e IL_0007: ldarg.0 IL_0008: ldfld "Test1.y As IBase" IL_000d: ret IL_000e: ldarg.0 IL_000f: ldfld "Test1.x As IBase" IL_0014: ret }]]>).VerifyIL("Test1.m2", <![CDATA[ { // Code size 16 (0x10) .maxstack 1 IL_0000: ldsfld "Derived.mask As Integer" IL_0005: brfalse.s IL_000e IL_0007: ldarg.0 IL_0008: ldfld "Test1.y As IBase" IL_000d: ret IL_000e: ldarg.0 IL_000f: ret }]]>).Compilation End Sub <Fact> Public Sub TypeConversionInterface_1() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Interface IBase Function m1() As IBase End Interface Class Derived Public Shared mask As Integer = 1 End Class Class Test1 Implements IBase Private y As IBase Private x As IBase Private cnt As Integer = 0 Public Sub New(link As IBase) x = Me y = link If y Is Nothing Then y = Me End If End Sub Public Shared Sub Main() End Sub Public Function m1() As IBase Implements IBase.m1 Return If(x, y) End Function 'version1 (explicit impl in original repro) Public Function m2() As IBase Return If(Me, y) End Function 'version2 End Class </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("Test1.m1", <![CDATA[ { // Code size 17 (0x11) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldfld "Test1.x As IBase" IL_0006: dup IL_0007: brtrue.s IL_0010 IL_0009: pop IL_000a: ldarg.0 IL_000b: ldfld "Test1.y As IBase" IL_0010: ret }]]>).VerifyIL("Test1.m2", <![CDATA[ { // Code size 12 (0xc) .maxstack 2 IL_0000: ldarg.0 IL_0001: dup IL_0002: brtrue.s IL_000b IL_0004: pop IL_0005: ldarg.0 IL_0006: ldfld "Test1.y As IBase" IL_000b: ret }]]>).Compilation End Sub <Fact> Public Sub TypeConversionInterface_2() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Interface IBase Function m1() As IBase End Interface Class Derived Public Shared mask As Integer = 1 End Class Class Test1 Implements IBase Private y As IBase Private x As IBase Private cnt As Integer = 0 Public Sub New(link As IBase) x = Me y = link If y Is Nothing Then y = Me End If End Sub Public Shared Sub Main() End Sub Public Function m1() As IBase Implements IBase.m1 Return If (x, DirectCast(y, IBase)) End Function 'version1 (explicit impl in original repro) Public Function m2() As IBase Return If (DirectCast(Me, IBase), y) End Function 'version2 End Class </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("Test1.m1", <![CDATA[ { // Code size 17 (0x11) .maxstack 2 IL_0000: ldarg.0 IL_0001: ldfld "Test1.x As IBase" IL_0006: dup IL_0007: brtrue.s IL_0010 IL_0009: pop IL_000a: ldarg.0 IL_000b: ldfld "Test1.y As IBase" IL_0010: ret }]]>).VerifyIL("Test1.m2", <![CDATA[ { // Code size 12 (0xc) .maxstack 2 IL_0000: ldarg.0 IL_0001: dup IL_0002: brtrue.s IL_000b IL_0004: pop IL_0005: ldarg.0 IL_0006: ldfld "Test1.y As IBase" IL_000b: ret }]]>).Compilation End Sub <Fact> Public Sub TypeConversionInterface_3() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Imports System.Collections Imports System.Collections.Generic Class Test1 Implements IEnumerable Dim x As IEnumerator Dim y As IEnumerator Public Shared Sub Main() End Sub Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Return If(Me IsNot Nothing, DirectCast(x, IEnumerator), DirectCast(y, IEnumerator)) End Function End Class </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("Test1.GetEnumerator", <![CDATA[ { // Code size 17 (0x11) .maxstack 1 IL_0000: ldarg.0 IL_0001: brtrue.s IL_000a IL_0003: ldarg.0 IL_0004: ldfld "Test1.y As System.Collections.IEnumerator" IL_0009: ret IL_000a: ldarg.0 IL_000b: ldfld "Test1.x As System.Collections.IEnumerator" IL_0010: ret }]]>).Compilation End Sub <Fact> Public Sub TypeConversionInterface_4() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Interface IBase Function GetEnumerator() As IBase End Interface Interface IDerived Inherits IBase End Interface Structure struct Implements IBase Public Shared Sub Main() End Sub Function GetEnumerator() As IBase Implements IBase.GetEnumerator Dim x As IDerived Dim y As IDerived Return If(x IsNot Nothing, DirectCast(x, IBase), DirectCast(y, IBase)) End Function End Structure </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("struct.GetEnumerator", <![CDATA[ { // Code size 9 (0x9) .maxstack 1 .locals init (IDerived V_0, //x IDerived V_1, //y IBase V_2) IL_0000: ldloc.0 IL_0001: brtrue.s IL_0005 IL_0003: ldloc.1 IL_0004: ret IL_0005: ldloc.0 IL_0006: stloc.2 IL_0007: ldloc.2 IL_0008: ret } ]]>).Compilation End Sub <Fact> Public Sub TypeConversionInterface_5() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Interface IBase Function GetEnumerator() As IBase End Interface Interface IDerived Inherits IBase End Interface Structure struct Implements IDerived Public Shared Sub Main() End Sub Function GetEnumerator() As IBase Implements IBase.GetEnumerator Dim x As IDerived Dim y As IDerived Return If(x IsNot Nothing, DirectCast(x, IDerived), DirectCast(y, IDerived)) End Function End Structure </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("struct.GetEnumerator", <![CDATA[ { // Code size 7 (0x7) .maxstack 1 .locals init (IDerived V_0, //x IDerived V_1) //y IL_0000: ldloc.0 IL_0001: brtrue.s IL_0005 IL_0003: ldloc.1 IL_0004: ret IL_0005: ldloc.0 IL_0006: ret }]]>).Compilation End Sub <Fact> Public Sub TypeConversionInterface_6() Dim compilation1 = CompileAndVerify( <compilation> <file name="a.vb"> Option Infer Off Interface IBase Function GetEnumerator() As IBase End Interface Interface IDerived Inherits IBase End Interface Structure struct Implements IDerived Public Shared Sub Main() End Sub Function GetEnumerator() As IBase Implements IBase.GetEnumerator Dim x = GetInterface() Dim y = GetInterface() Dim z = If(x IsNot Nothing, DirectCast(x, IBase), DirectCast(y, IBase)) End Function Function GetInterface() As IBase Return Nothing End Function End Structure </file> </compilation>, options:=TestOptions.ReleaseExe).VerifyIL("struct.GetEnumerator", <![CDATA[ { // Code size 34 (0x22) .maxstack 1 .locals init (IBase V_0, //GetEnumerator Object V_1, //x Object V_2) //y IL_0000: ldarg.0 IL_0001: call "Function struct.GetInterface() As IBase" IL_0006: stloc.1 IL_0007: ldarg.0 IL_0008: call "Function struct.GetInterface() As IBase" IL_000d: stloc.2 IL_000e: ldloc.1 IL_000f: brtrue.s IL_0019 IL_0011: ldloc.2 IL_0012: castclass "IBase" IL_0017: br.s IL_001f IL_0019: ldloc.1 IL_001a: castclass "IBase" IL_001f: pop IL_0020: ldloc.0 IL_0021: ret }]]>).Compilation End Sub <Fact, WorkItem(545065, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545065")> Public Sub IfOnConstrainedMethodTypeParameter() CompileAndVerify( <compilation> <file name="a.vb"> Friend Module BIFOpResult0011mod Public Sub scen7(Of T As Class)(ByVal arg As T) Dim s7_a As T = arg Dim s7_b As T = Nothing Dim s7_c = If(s7_a, s7_b) System.Console.Write(s7_c) End Sub Sub Main() scen7(Of String)("Q") End Sub End Module </file> </compilation>, expectedOutput:="Q").VerifyIL("BIFOpResult0011mod.scen7", <![CDATA[ { // Code size 30 (0x1e) .maxstack 2 .locals init (T V_0) //s7_b IL_0000: ldarg.0 IL_0001: ldloca.s V_0 IL_0003: initobj "T" IL_0009: dup IL_000a: box "T" IL_000f: brtrue.s IL_0013 IL_0011: pop IL_0012: ldloc.0 IL_0013: box "T" IL_0018: call "Sub System.Console.Write(Object)" IL_001d: ret }]]>) End Sub <Fact> Public Sub IfOnUnconstrainedMethodTypeParameter() CompileAndVerify( <compilation> <file name="a.vb"> Friend Module Mod1 Sub M1(Of T)(arg1 As T, arg2 As T) System.Console.WriteLine(If(arg1, arg2)) End Sub Sub M2(Of T1, T2 As T1)(arg1 as T1, arg2 As T2) System.Console.WriteLine(If(arg2, arg1)) End Sub Sub Main() M1(Nothing, 1000) M1(1, 1000) M1(Nothing, "String Parameter 1") M1("String Parameter 2", "Should not print") M1(Of Integer?)(Nothing, 4) M1(Of Integer?)(5, 1000) M2(1000, 6) M2(Of Object, Integer?)(7, Nothing) M2(Of Object, Integer?)(1000, 8) M2(Of Integer?, Integer?)(9, Nothing) M2(Of Integer?, Integer?)(1000, 10) End Sub End Module </file> </compilation>, expectedOutput:=<![CDATA[ 0 1 String Parameter 1 String Parameter 2 4 5 6 7 8 9 10 ]]>).VerifyIL("Mod1.M1", <![CDATA[ { // Code size 22 (0x16) .maxstack 2 IL_0000: ldarg.0 IL_0001: dup IL_0002: box "T" IL_0007: brtrue.s IL_000b IL_0009: pop IL_000a: ldarg.1 IL_000b: box "T" IL_0010: call "Sub System.Console.WriteLine(Object)" IL_0015: ret } ]]>).VerifyIL("Mod1.M2", <![CDATA[ { // Code size 33 (0x21) .maxstack 1 IL_0000: ldarg.1 IL_0001: box "T2" IL_0006: brtrue.s IL_000b IL_0008: ldarg.0 IL_0009: br.s IL_0016 IL_000b: ldarg.1 IL_000c: box "T2" IL_0011: unbox.any "T1" IL_0016: box "T1" IL_001b: call "Sub System.Console.WriteLine(Object)" IL_0020: ret } ]]>) End Sub <Fact> Public Sub IfOnUnconstrainedTypeParameterWithNothingLHS() CompileAndVerify( <compilation> <file name="a.vb"> Imports System Friend Module Mod1 Sub M1(Of T)(arg As T) Console.WriteLine(If(Nothing, arg)) End Sub Sub Main() ' Note that this behavior is different than C#'s behavior. This is consistent with Roslyn's handling ' of If(Nothing, 1), which will evaluate to 1 M1(1) Console.WriteLine(If(Nothing, 1)) M1("String Parameter 1") M1(Of Integer?)(3) End Sub End Module </file> </compilation>, expectedOutput:=<![CDATA[ 1 1 String Parameter 1 3 ]]>).VerifyIL("Mod1.M1", <![CDATA[ { // Code size 12 (0xc) .maxstack 1 .locals init (T V_0) IL_0000: ldarg.0 IL_0001: box "T" IL_0006: call "Sub System.Console.WriteLine(Object)" IL_000b: ret } ]]>) End Sub <Fact> Public Sub IfOnUnconstrainedTypeParametersOldLanguageVersion() CreateCompilation( <compilation> <file name="a.vb"> Friend Module Mod1 Sub M1(Of T)(arg1 As T, arg2 As T) System.Console.WriteLine(If(arg1, arg2)) End Sub End Module </file> </compilation>, parseOptions:=TestOptions.Regular15_5).AssertTheseDiagnostics(<![CDATA[ BC36716: Visual Basic 15.5 does not support unconstrained type parameters in binary conditional expressions. System.Console.WriteLine(If(arg1, arg2)) ~~~~~~~~~~~~~~ ]]>) End Sub End Class End Namespace